//@STATE=嶌惉拞
//@DESCRIPTION ---------------------------------------------------------------
// BGEditorImpl.cpp: BGEditorImpl 僋儔僗偺僀儞僾儕儊儞僥乕僔儑儞
// << 拲堄 >>
//   僀儞僗僞儞僗嶌惉屻偼昁偢丄BGEditor偺僷儔儊乕僞傪弶婜壔偟偰偔偩偝偄丅
//	棜楌丗
// $Log: BGEditorImpl.cpp,v $
// Revision 1.1.1.1  2001/11/06 21:29:04  fujiwara
// no message
//
// Revision 1.1  2001/10/28 21:40:35  fujiwara
// DLL偵暘妱
//
// Revision 1.5  2001/07/09 20:30:07  fujiwara
// 椺奜張棟偺慻傒崬傒
//
// Revision 1.4  2001/07/01 21:30:33  fujiwara
// 儊儌儕儕乕僋僠僃僢僋尒捈偟
//
// Revision 1.3  2001/07/01 01:03:43  fujiwara
// const 偺尒捈偟
// 攝抲僄僨傿僞偼搑拞宱夁
//
// Revision 1.2  2001/05/12 00:48:13  fujiwara
// 俠倁俽傪摫擖偟丄儘僌昞帵傪捛壛
//
//@DESCRIPTION_END -----------------------------------------------------------
//@AUTHOR=S.F.
// Copyright (C) 2000 Satoshi Fujiwara. All Rights Reserved.
///////////////////////////////////////////////////////////////////////////////

#pragma warning( disable : 4786 )	//STL偺寈崘奜偟
// 儊儌儕乕儕乕僋専弌梡
#include "sfdebug.h"


// SYSTEM INCLUDES

#include <stack>
#include <list>
#include <vector>
#include <map>
#include <fstream>

// PROJECT INCLUDES

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#include "exception.h"
#include "singleton.h"
#include "system.h"
#include "console.h"
#include "input.h"
#include "Scene.h"
#include "main.h"
#include "Obj.h"
#include "Obj2D.h"
#include "Obj3D.h"
#include "Obj3DL.h"
#include "ObjQuadrangle.h"
#include "ObjRectangle.h"
#include "Background.h"
#include "AbstractScene.h"
#include "character.h"
#include "Game.h"
#include "hit.h"
#include "MySHip.h"
#include "Enemys.h"
#include "Armys.h"
#include "DispositionControl.h"
#include "BGEditor.h"
#include "BGEditorImpl.h"

//////////////////////////////////////////////////////////////////////
// 峔抸/徚柵
//////////////////////////////////////////////////////////////////////

using namespace sf::application::scene;
using namespace sf;
using namespace sf::system::console;

const float BGEditorImpl::CellSelector::WIDTH = Background::Map::CELL_SIZE * Background::Map::CELL_TEX_COUNT_W;
const float BGEditorImpl::CellSelector::HEIGHT = Background::Map::CELL_SIZE * Background::Map::CELL_TEX_COUNT_H;

const float BGEditorImpl::CellSelector::X_MIN = viewport::X + BGEditorImpl::CellSelector::WIDTH / 2.0f;
const float BGEditorImpl::CellSelector::X_MAX = viewport::X + viewport::WIDTH - BGEditorImpl::CellSelector::WIDTH / 2.0f;
const float BGEditorImpl::CellSelector::Y_MIN = viewport::Y + BGEditorImpl::CellSelector::HEIGHT / 2.0f;
const float BGEditorImpl::CellSelector::Y_MAX = viewport::Y + viewport::HEIGHT - BGEditorImpl::CellSelector::HEIGHT / 2.0f;			


BGEditorImpl::BGEditorImpl() : AbstractScene()
{
	mbCallBack = false;
	mbListening = false;
	mpCellSelector = NULL;
	mSelectedMapData = 0x0;
	mpGame = NULL;
	mState = INITIALIZE;
}

BGEditorImpl::~BGEditorImpl()
{
	mbCallBack = false;

	if(mpInput){
		mpInput->removeMouseListener(this);
		mpInput->removeKeyboardListener(this);
		mpInput->hideMouseCursor();
	}

	if(mpCellSelector)
		delete mpCellSelector;
}


void BGEditorImpl::move(void)
{
	switch(mState)
	{
	case INITIALIZE:
		initialize();
		return;
	case MAIN:
		// 俤倃俬俿僉乕偑墴偝傟偨偐丠
		if(mpInput->exit(true)) {
			exitKeyPressed(this);
		}
		return;
	}

}

// 弶婜壔 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
bool BGEditorImpl::initialize()
{
//	if(!mBackground.load("test.map"))
//		return false;

//	mBackground.offsetY(0.0f);
//	mBackground.visibility(true);
	mpInput->addMouseListener(this);
	mpInput->addKeyboardListener(this);

	mpInput->showMouseCursor();
	mState = MAIN;
	mbCallBack = true;
	mbListening = true;
	return true;
}

//BGEditorImpl Scene 偺廔椆 ---------------------------------------------------------
void BGEditorImpl::endOfScene(Scene *pScene)
{
	CellSelector *pcs;

	switch(pScene->type())
	{
	case CELLSELECTOR:
		mbCallBack = true;
		pcs = dynamic_cast<CellSelector*>(pScene);
		selectedData( (pcs->selectedTextureNo() << 16) | (0x7fff & pcs->selectedIndex() + 1));
		break;
	default:
		callSceneEvent(&sf::application::scene::Listener::endOfScene);
		delete this;
	}

} //endOfScene()

// exit key 偑墴偝傟偨両 ------------------------------------------------------
void BGEditorImpl::exitKeyPressed(Scene *pScene)
{
	callSceneEvent(&sf::application::scene::Listener::exitKeyPressed);
	delete this;
} //endOfScene()

// 儅僂僗儂僀乕儖偑摦偄偨 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void BGEditorImpl::mouseWheel(const int screenX,const int screenY,const DWORD mkey)
{
	using namespace sf::system::input::mouse;
	int wheel = (int)(mkey & 0xffff0000) / 65536;
	
	float speed = 8.0f;

	if(MKEY_SHIFT & mkey)
		speed = 64.0f;

	if(MKEY_CONTROL & mkey)
		speed = 64.0f * 8.0f;
	
	if(wheel > 0){
		mpGame->scrollY(mpGame->scrollY() + speed);
	} else {
		mpGame->scrollY(mpGame->scrollY() - speed);
	}

}// mouseWheel()

// 僉乕儃乕僪偑墴偝傟偨両
void BGEditorImpl::keyDown(DWORD keyCode,DWORD extKeyCode)
{
	switch((char)keyCode)
	{
	case 'G':
		endOfScene(this);
		break;
	case 'S':
		mpGame->background()->save(NULL);
		break;
	}
}// keyDown()

// 塃僋儕僢僋  亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void BGEditorImpl::rightButtonDown(const int screenX,const int screenY,const DWORD mkey)
{
	mbCallBack = false;

	CellSelector *pcsel = new CellSelector(mpGame->background()->textureList());
	Container::instance()->add(pcsel);
	pcsel->addListener(this);
	pcsel->selectedIndex(selectedData() & 0xffff);
	pcsel->selectedTextureNo((selectedData() & 0xffff0000) >> 16);
	
	pcsel->selectorX((float)screenX);
	pcsel->selectorY((float)screenY);
	pcsel->z((float)0.0001);

	mMouseX = (float)screenX;
	mMouseY = (float)screenY;
	
}// rightButtonDown

// 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
//
//  CellSelector Class
//
// 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅

BGEditorImpl::CellSelector::CellSelector(sf::system::console::Background::TextureList* pTextureList)
{
	mpTextureList = pTextureList;
	visibility(false);
	sprite(NULL);
	mState = INITIALIZE;
	mbMouseListening = false;
}// CellSelector()

// 僨僗僩儔僋僞 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
BGEditorImpl::CellSelector::~CellSelector()
{
	if(mpInput)
		mpInput->removeMouseListener(this);
//	Obj::List::deleteObj(this);

}// ~CellSelector()

// 摦嶌婰弎 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void BGEditorImpl::CellSelector::move(void)
{
	switch(mState)
	{
	case INITIALIZE:
		initialize();
		return;
	case MAIN:
//		return main();
		break;
	}

}// move()

// 弶婜壔 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
bool BGEditorImpl::CellSelector::initialize()
{
	if(mSelectorX > X_MAX)
		mSelectorX = X_MAX;
	
	if(mSelectorX< X_MIN)
		mSelectorX = X_MIN;
	
	if(mSelectorY > Y_MAX)
		mSelectorY = Y_MAX;

	if(mSelectorY < Y_MIN)
		mSelectorY = Y_MIN;
	mpInput->addMouseListener(this);
	mbMouseListening = true;
	visibility(true);
	mState = MAIN;
	return true;
}// move()

// 僙儗僋僞偺昤夋 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void BGEditorImpl::CellSelector::draw()
{
	if(!visibility())
		return;
	
	float start_y = mSelectorY - (Background::Map::CELL_TEX_COUNT_H / 2.0f 
					*  Background::Map::CELL_SIZE - Background::Map::CELL_SIZE / 2.0f);
	float end_y = mSelectorY + (Background::Map::CELL_TEX_COUNT_H / 2.0f 
					*  Background::Map::CELL_SIZE - Background::Map::CELL_SIZE / 2.0f);
	
	float start_x = mSelectorX - (Background::Map::CELL_TEX_COUNT_W / 2.0f 
					*  Background::Map::CELL_SIZE - Background::Map::CELL_SIZE / 2.0f);
	
	float end_x = mSelectorX + (Background::Map::CELL_TEX_COUNT_W / 2.0f 
					*  Background::Map::CELL_SIZE - Background::Map::CELL_SIZE / 2.0f);

	int t_index = 0;

	for(float iy = start_y ; iy <= end_y;iy += Background::Map::CELL_SIZE)
	{
		for(float ix = start_x ; ix <= end_x ; ix += Background::Map::CELL_SIZE){
			index(t_index);
			x(ix);
			y(iy);

			if(	mMouseX > (ix - Background::Map::CELL_SIZE / 2.0f) && 
				mMouseX < (ix + Background::Map::CELL_SIZE / 2.0f) && 
				mMouseY > (iy - Background::Map::CELL_SIZE / 2.0f) && 
				mMouseY < (iy + Background::Map::CELL_SIZE / 2.0f))
			{	
				color(0xffff0000);
			}
			else
				color(0xffffffff);

			(*mpTextureList)[selectedTextureNo()]->draw(this);
			t_index++;
		}
	}

}

// 嵍僋儕僢僋偑墴偝傟偨 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void BGEditorImpl::CellSelector::leftButtonDown(const int screenX,const int screenY,const DWORD mkey)
{

	if(!visibility())
	return;
	
	float start_y = mSelectorY - (Background::Map::CELL_TEX_COUNT_H / 2.0f 
					*  Background::Map::CELL_SIZE - Background::Map::CELL_SIZE / 2.0f);
	float end_y = mSelectorY + (Background::Map::CELL_TEX_COUNT_H / 2.0f 
					*  Background::Map::CELL_SIZE - Background::Map::CELL_SIZE / 2.0f);
	
	float start_x = mSelectorX - (Background::Map::CELL_TEX_COUNT_W / 2.0f 
					*  Background::Map::CELL_SIZE - Background::Map::CELL_SIZE / 2.0f);
	
	float end_x = mSelectorX + (Background::Map::CELL_TEX_COUNT_W / 2.0f 
					*  Background::Map::CELL_SIZE - Background::Map::CELL_SIZE / 2.0f);

	int t_index = 0;

	for(float iy = start_y ; iy <= end_y;iy += Background::Map::CELL_SIZE)
	{
		for(float ix = start_x ; ix <= end_x ; ix += Background::Map::CELL_SIZE){
			if(	mMouseX > (ix - Background::Map::CELL_SIZE / 2.0f) && 
				mMouseX < (ix + Background::Map::CELL_SIZE / 2.0f) && 
				mMouseY > (iy - Background::Map::CELL_SIZE / 2.0f) && 
				mMouseY < (iy + Background::Map::CELL_SIZE / 2.0f))
			{	
				selectedIndex(t_index);
				callSceneEvent(&sf::application::scene::Listener::endOfScene);
				delete this;
				return;
			}
			t_index++;
		}
	}
	callSceneEvent(&sf::application::scene::Listener::endOfScene);
	delete this;
}// leftButtonDown()

// 儅僂僗儂僀乕儖偑摦偄偨 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void BGEditorImpl::CellSelector::mouseWheel(const int screenX,const int screenY,const DWORD mkey)
{
	using namespace sf::system::input::mouse;
	int wheel = (int)(mkey & 0xffff0000) / 65536;
	if(wheel > 0){
		if(selectedTextureNo() == (mpTextureList->size() - 1))
			return;
		else
			selectedTextureNo(selectedTextureNo() + 1);
	} else {
		if(selectedTextureNo() == 0)
			return;
		else
			selectedTextureNo(selectedTextureNo() - 1);
	}
		


}// mouseWheel()

