#include "WorldScene.h"
#include "mof/GraphicsDevice.h"
#include "mof/AmbientLight.h"
#include "mof/InputDevice.h"
#include "mof/ConsoleIO.h"
#include <math.h>
#include "mof/System.h"
#include "Area.h"
#include "DungeonBuilderA.h"
#include "mof/AmbientLight.h"
#include "mof/DirectionalLight.h"
#include "mof/ConsoleIO.h"
#include "mof/SoftVertexBufferImpl.h"
#include "mof/KeyFrameAnimation.h"
#include <sstream>

mof::Vector2D toAreaCoord(mof::Vector3D position){
	return mof::Vector2D(position.x / 0.03f , -position.z  / 0.03f);
}

mof::Vector3D toWorldCoord(mof::Vector2D position){
	return mof::Vector3D((float)position.x * 0.03f + 0.015f , 0.015f , (float)position.y * -0.03f - 0.015f);
}

et::WorldScene::WorldScene()
: et::GameScene() 
{

	m_pWindow = NULL;
	m_pBuilder = NULL;
	m_pWorldMap = NULL;
	m_pCamera = NULL;
	m_pGrid = NULL;
	m_pPoint = NULL;
	//m_state = et::WorldScene::OPENING;
	m_pCurrentFrame = NULL;
	m_pAreaMenu = NULL;
	m_pWorldMenu = NULL;
	m_pWorld = NULL;
	m_pFeedEffect = NULL;
}

et::WorldScene::~WorldScene(void)
{
	//delete m_pAreaMenu;
	delete m_pWorld;
	delete m_pAreaMenu;
	delete m_pWorldMenu;
	delete m_pWindow;
	delete m_pBuilder;
	delete m_pWorldMap;
	delete m_pCamera;
	delete m_pCursor;
	delete m_pGrid;
	delete m_pPoint;
	delete m_pFeedEffect;
}


bool et::WorldScene::initialize(){

	m_pWorld = m_pGameData->createWorld();

	//再生度表示フレームの作成
	m_pWindow = new et::MyFrame(mof::Line2D( 370 , 400 , 600 , 450) , false , m_pTextureManager->getResource(_T("image/frame0.png")));
	std::stringstream os;
	os << _T("再生度") << m_pWorld->getRegenerationLevel() << _T("/Term") << m_pWorld->getTerm();
	m_pWindow->add(mof::Sprite::createSpriteFromText((TCHAR*)os.str().c_str() , 24));
	m_pWindow->setLayout();
	mof::KeyFrameAnimation* pAnimation = new mof::KeyFrameAnimation();
	//アニメの設定
	pAnimation->setPosition( 1 , mof::Vector2D( 220 ,  200 ));
	pAnimation->setPosition(180 , mof::Vector2D(400 , 380));
	m_pWindow->setAnimation(0 , mof::AnimationResource(pAnimation));

	//ワールドメニュの作成
	m_pWorldMenu = new et::WorldMenu(m_pTextureManager , m_pWorld , m_pGameData);
	m_pCurrentFrame = m_pWorldMenu;

	//フェードエフェクト
	mof::RectangleModel rect = mof::System::getInstance()->getBounds();
	m_pFeedEffect = new mof::Sprite(mof::Line2D(rect.getPosition() , rect.getWidth() , rect.getHeight()) ,
		mof::Line2D() , m_pTextureManager->getResource(_T("null")));
	pAnimation = new mof::KeyFrameAnimation();
	pAnimation->setColor(0 , mof::createColor(255 , 0 , 0 , 0));
	pAnimation->setColor(180 , mof::createColor(255 , 0 , 0 , 0));
	pAnimation->setColor(210 , mof::createColor(0 , 0 , 0 , 0));
	m_pFeedEffect->setAnimation(0 , mof::AnimationResource(pAnimation));

	m_translationScheduler.add(0 , m_pWindow->getAnimationSet());
	m_translationScheduler.add(180 , m_pWorldMenu->getAnimationSet());
	m_translationScheduler.add(0 , m_pFeedEffect->getAnimationSet());
	


	//ワールドマップの作成
	m_pBuilder = new et::WorldMapBuilder(m_pWorld->getAreaPowerLevelMap() , m_pTextureManager , 0.03f);
	m_pWorldMap = m_pBuilder->create();
	m_pTexture = m_pTextureManager->getResource(_T("image/worldtip.png"));

	
	//カーソルの設定
	m_pCursor = new et::WorldMapCursor(new mof::Mesh(mof::tstring(_T("model/cursor.x"))));
	m_pCursor->move(et::Symbol::UP , toWorldCoord(mof::Vector2D(0 , 0 )) , 1);
	
	

	//ライトの設定
	mof::AmbientLight light(mof::createColor(255 , 255 , 255));
	light.reflect();
	mof::GraphicsDevice::getInstance()->setLight(true);

	//グリッドの作成
	m_pGrid = new mof::SoftVertexBuffer<mof::VertexXYZC>(mof::VertexBuffer<mof::VertexXYZC>::PRIMITIVE_TYPE_LINELIST);
	mof::VertexXYZC vertex;
	vertex.color = mof::createColor(155 , 155 , 155);
	vertex.y = 0.001f;
	//縦線
	for(int x = 0 ; x < 10+1 ; x++){
		vertex.x = (float)x * 0.03f;
		vertex.z = 0.0f;
		m_pGrid->add(vertex);
		vertex.x = (float)x * 0.03f;
		vertex.z = -0.03f * 10;
		m_pGrid->add(vertex);
	}
	//横線
	for(int y = 0 ; y < 10+1 ; y++){
		vertex.x = 0.0f;
		vertex.z = -(float)y * 0.03f;
		m_pGrid->add(vertex);
		vertex.x = 0.03f * 10;
		vertex.z = -(float)y * 0.03f;
		m_pGrid->add(vertex);
	}
	
	//カーソルポイントを作成
	m_pPoint = new mof::SoftVertexBuffer<mof::VertexXYZC>(mof::VertexBuffer<mof::VertexXYZC>::PRIMITIVE_TYPE_LINELIST);
	mof::Color color = mof::createColor(255 , 255 , 0);
	m_pPoint->add(mof::VertexXYZC(mof::Vector3D(0.0f , 0.002f , 0.0f) , color));
	m_pPoint->add(mof::VertexXYZC(mof::Vector3D(0.0f ,0.002f , -0.03f) , color));
	m_pPoint->add(mof::VertexXYZC(mof::Vector3D(0.0f , 0.002f , -0.03f) , color));
	m_pPoint->add(mof::VertexXYZC(mof::Vector3D(0.03f , 0.002f , -0.03f) , color));
	m_pPoint->add(mof::VertexXYZC(mof::Vector3D(0.03f , 0.002f , -0.03f) , color));
	m_pPoint->add(mof::VertexXYZC(mof::Vector3D(0.03f , 0.002f, 0.0f) , color));
	m_pPoint->add(mof::VertexXYZC(mof::Vector3D(0.03f , 0.002f , 0.0f) , color));
	m_pPoint->add(mof::VertexXYZC(mof::Vector3D(0.0f , 0.002f , 0.0f) , color));
	

	//3D環境の準備1
	m_pCamera = new mof::Camera(mof::Vector3D(/*0.25f*/  0.03f * 5 , 0.5f , -0.35f) , mof::Vector3D( 0.03f * 5 , 0.0f , -0.17f) , mof::Vector3D(0.0f , 0.0f , 0.90f));
	m_pCamera->reflect();
	mof::GraphicsDevice::getInstance()->setProjectionTransform(0.01f , 50.0f);

	
	
	return true;
}
	
bool et::WorldScene::draw(){
	//m_pCapturer->capture();
	mof::GraphicsDevice* pDevice = mof::GraphicsDevice::getInstance();
	pDevice->clearRenderTarget(mof::createColor(27 , 37 , 67));//27
	pDevice->setAlphaBlendingMode(mof::GraphicsDevice::BLENDING_MODE_BASIC);
	
	if(m_pWindow != NULL && m_pWindow->getAnimationSet()->isFinalized()){
		pDevice->setZBuffer(true);
		pDevice->clearZBuffer();
		pDevice->setLight(false);
		mof::Material().reflect();
		m_pTexture->setTextureToDevice();
		m_pWorldMap->draw(mof::Matrix3D());
	}

	if(m_pAreaMenu != NULL || (m_pCurrentFrame == NULL || (m_menuChangeAnimation.get() != NULL && !m_menuChangeAnimation->isFinalized()))){
		//エリアグリッドの描画
		pDevice->setLight(false);
		m_pTextureManager->getResource(_T("null"))->setTextureToDevice(); 
		m_pGrid->draw(m_menuChangeAnimation->getWorldTransform(mof::Matrix3D()));
	}

	if(m_pAreaMenu != NULL || (m_pCurrentFrame == NULL  && m_translationScheduler.isFinalized())){
		
		//カーソルポイントの描画
		mof::Vector3D pointPosition = m_pCursor->getPosition();
		pointPosition.x = (float)(int)(pointPosition.x / 0.03f) * 0.03f;
		pointPosition.z = (float)(int)(pointPosition.z / 0.03f) * 0.03f;
		//DEBUG_PRINT(pointPosition.y);
		m_pPoint->draw(mof::Matrix3D::createTranslation(pointPosition));
		
		//エリアアイコンの描画
		mof::Billboard icon(mof::Billboard::XYZ_FIXED , m_pTexture);
		mof::Matrix3D scaling = mof::Matrix3D::createScaling(0.03f , 0.03f , 0.03f);
		for(int y = 0 ; y < m_pWorld->getAreaHeight() ; y++){
			for(int x = 0 ; x < m_pWorld->getAreaWidth() ; x++){
				if(m_pWorld->getArea(x , y).forestGen)icon.setTextureRectangle(mof::Line2D(32 * 4 , 32 * 6 , 32 * 5 , 32 * 7));
				else continue;
				icon.setWorldTransform(scaling * mof::Matrix3D::createTranslation(mof::Vector3D(0.015f + 0.03*x , pointPosition.y , -0.015f - 0.03*y)));
				icon.draw();
			}
		}
		pDevice->setZBuffer(false);
		pDevice->setLight(true);
		//エリアカーソルの描画
		mof::DirectionalLight(mof::createColor(255 , 255 , 0) , mof::createColor(55 , 55 , 155) , mof::Vector3D(1.0f , -1.0f , -1.0f)).reflect();
		m_pCursor->draw();
		

	}else pDevice->setZBuffer(false);
	
	if(m_pAreaMenu != NULL)m_pAreaMenu->draw();
	if(m_pWorldMenu != NULL)m_pWorldMenu->draw();
	
	mof::Color color = m_pFeedEffect->getCornerColor(mof::Sprite::C_RIGHT_BOTTOM);
	//DEBUG_PRINT("color:" << (int)mof::getRed(color));
	if(mof::getAlpha(color) != 0){//透明で見えないときは描画しない
		pDevice->setAlphaBlendingMode(mof::GraphicsDevice::BLENDING_MODE_ALPHA);
		m_pFeedEffect->draw();
		pDevice->setAlphaBlendingMode(mof::GraphicsDevice::BLENDING_MODE_BASIC);
	}
	m_pWindow->draw();
	
	return true;
}


bool et::WorldScene::update(){
	//カーソルの移動
	mof::Vector2D areaPosition = toAreaCoord(m_pCursor->getPosition());
	if(m_pCurrentFrame == NULL && m_translationScheduler.isFinalized()){
		mof::Vector2D nextPosition = areaPosition;
		if(m_pInputReceiver->checkKeyState(mof::InputReceiver::UP) && areaPosition.y > 0){
			nextPosition.y--;
			m_pCursor->move(et::Symbol::UP , toWorldCoord(nextPosition) , 10);
		}
		else if(m_pInputReceiver->checkKeyState(mof::InputReceiver::DOWN) && areaPosition.y < 10-1){
			nextPosition.y++;
			m_pCursor->move(et::Symbol::DOWN , toWorldCoord(nextPosition) , 10);
		}
		else if(m_pInputReceiver->checkKeyState(mof::InputReceiver::LEFT) && areaPosition.x > 0){
			nextPosition.x--;
			m_pCursor->move(et::Symbol::LEFT , toWorldCoord(nextPosition) , 10);
		}
		else if(m_pInputReceiver->checkKeyState(mof::InputReceiver::RIGHT) && areaPosition.x < 10-1){
			nextPosition.x++;
			m_pCursor->move(et::Symbol::RIGHT , toWorldCoord(nextPosition) , 10);
		}
		else if(m_pInputReceiver->checkKeyPressed(mof::InputReceiver::Z)){
			if(!m_pCursor->isTraveling()){
				//エリアメニュー設定
				m_pAreaMenu = new et::AreaMenu( m_pWorld->getArea(areaPosition.x , areaPosition.y) , m_pTextureManager
					, m_pWorld , m_pGameData , areaPosition);
				m_pCurrentFrame = m_pAreaMenu;

				m_translationScheduler.clear();
				m_translationScheduler.add(0 , m_pAreaMenu->getAnimationSet());
			}
			
		}
		else if(m_pInputReceiver->checkKeyPressed(mof::InputReceiver::X)){
			//エリアメニュー→ワールドメニューの遷移アニメをセット
			mof::KeyFrameAnimation* pAnimation = new mof::KeyFrameAnimation();
			pAnimation->setPosition( 0 , mof::Vector3D(0.0f ,  0.015f  , 0.0f));
			pAnimation->setPosition(30 , mof::Vector3D(0 , 0.0001 , 0));
			m_menuChangeAnimation = mof::AnimationResource(pAnimation);
				
			m_pWorldMenu = new et::WorldMenu(m_pTextureManager , m_pWorld , m_pGameData);
			m_pCurrentFrame = m_pWorldMenu;

			m_translationScheduler.clear();
			m_translationScheduler.add(0 , m_pWorldMenu->getAnimationSet());
			m_translationScheduler.add(0 , m_menuChangeAnimation);
		
		}
	}
	else if(m_pCurrentFrame != NULL && m_translationScheduler.isFinalized()){
		
		//ウィンドウに対するキー
		if(m_pInputReceiver->checkKeyPressed(mof::InputReceiver::UP))m_pCurrentFrame->getSelectionModel()->previous();
		else if(m_pInputReceiver->checkKeyPressed(mof::InputReceiver::DOWN))m_pCurrentFrame->getSelectionModel()->next();
		else if(m_pInputReceiver->checkKeyPressed(mof::InputReceiver::Z) && 
			m_pCurrentFrame->getSelectionModel()->getSelectingItem()->isAvailable()){
			
			int selectedIndex = m_pCurrentFrame->getSelectionModel()->getSelectingIndex();
			MyFrame* tmpFrame = m_pCurrentFrame;
			MyFrame* pFrame = m_pCurrentFrame->performAction();
			if(pFrame != m_pCurrentFrame){
				//ウィンドウの遷移
				m_translationScheduler.clear();
				if(!m_pCurrentFrame->isVisible())m_translationScheduler.add(0 , m_pCurrentFrame->getAnimationSet());
				m_pCurrentFrame = pFrame;
				if(m_pCurrentFrame != NULL)m_translationScheduler.add(0 , m_pCurrentFrame->getAnimationSet());

			}
			if(tmpFrame == m_pWorldMenu && selectedIndex == 1){
				//ワールドメニュー→エリアメニューの遷移アニメをセット
				mof::KeyFrameAnimation* pAnimation = new mof::KeyFrameAnimation();
				pAnimation->setPosition( 0 , mof::Vector3D(0.0f ,  0.0001f  , 0.0f));
				pAnimation->setPosition(30 , mof::Vector3D(0 , 0.015 , 0));
				m_menuChangeAnimation = mof::AnimationResource(pAnimation);
				m_translationScheduler.add(0 , m_menuChangeAnimation);
				
			}
			else if(tmpFrame == m_pWorldMenu && selectedIndex == 2){
				//ワールドシーンの終了
				end(0);
			}
		}
		else if(m_pInputReceiver->checkKeyPressed(mof::InputReceiver::X)){
			if(m_pCurrentFrame == m_pAreaMenu){
				m_pAreaMenu->setVisible(false);
				m_pCurrentFrame = NULL;
			}
		}

	}


	
	//フレームの更新処理
	/*et::MyFrame** targets[] = {&m_pAreaMenu , &m_pWorldMenu};
	int length = sizeof(targets) / sizeof(targets[0]);
	for(int i = 0 ; i < length ; i++){
		if(*(targets[i]) != NULL){
			(*(targets[i]))->update();
			if(!(*(targets[i]))->isVisible() && (*(targets[i]))->getAnimation(0)->isFinalized()){
				delete *(targets[i]);
				*(targets[i]) = NULL;
			}
		}
	}*/
	if(m_pAreaMenu != NULL){
		m_pAreaMenu->update();
		if(!m_pAreaMenu->isVisible() && m_pAreaMenu->getAnimation(0)->isFinalized()){
			delete m_pAreaMenu;
			m_pAreaMenu = NULL;
		}
	}
	if(m_pWorldMenu != NULL){
		m_pWorldMenu->update();
		if(!m_pWorldMenu->isVisible() && m_pWorldMenu->getAnimation(0)->isFinalized()){
			delete m_pWorldMenu;
			m_pWorldMenu = NULL;
		}
	}
	if(m_pWindow != NULL){
		m_pWindow->update();
	}
	
	if(m_menuChangeAnimation.get() != NULL)m_menuChangeAnimation->update();
	m_pCamera->setWorldTransform(mof::Matrix3D::createTranslation(mof::Vector3D(0.0f , 0.0f,  0.0f)));
	m_pCamera->reflect();
	m_pCursor->update();
	m_pFeedEffect->update();
	
	mof::Billboard::updateBillboardDirection(m_pCamera);
	m_translationScheduler.update();

	return true;
}

