//@STATE=嶌惉拞
//@DESCRIPTION ---------------------------------------------------------------
// DispositionEditorImpl.cpp: DispositionEditorImpl 僋儔僗偺僀儞僾儕儊儞僥乕僔儑儞
//	棜楌丗
// $Log: DispositionEditorImpl.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.9  2001/07/09 20:30:08  fujiwara
// 椺奜張棟偺慻傒崬傒
//
// Revision 1.8  2001/07/01 21:30:33  fujiwara
// 儊儌儕儕乕僋僠僃僢僋尒捈偟
//
// Revision 1.7  2001/07/01 01:03:43  fujiwara
// const 偺尒捈偟
// 攝抲僄僨傿僞偼搑拞宱夁
//
// Revision 1.6  2001/05/29 01:13:06  fujiwara
// 嶨嫑僉儍儔(旘峴暔乯偺嶌惉丅攝抲僄僨傿僞偺僶僌廋惓
//
// Revision 1.5  2001/05/17 12:34:10  fujiwara
// 抧忋揋僒儞僾儖嶌惉
//
// Revision 1.4  2001/05/12 12:48:28  fujiwara
// 攝抲僄僨傿僞嶌惉偵敽偆曄峏丒捛壛
//
// Revision 1.3  2001/05/12 00:50:48  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


#include "exception.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#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 "hit.h"
#include "MySHip.h"
#include "Enemys.h"
#include "Armys.h"
#include "Game.h"
#include "DispositionControl.h"
#include "DispositionEditorImpl.h"

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

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

const DWORD DispositionEditorImpl::CURRENT_SPECULAR = 0x202080;
const DWORD DispositionEditorImpl::NORMAL_SPECULAR = 0;

// 僐儞僗僩儔僋僞 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
DispositionEditorImpl::DispositionEditorImpl() : AbstractScene()
{
	mbCallBack = false;
	mbListening = false;
	
	mEditType = application::disposition::command::SET_ENEMY;
	mpEditCommand = sf::application::disposition::Controller::create(mEditType);
	mpEditCommand->load();

	mpGame = NULL;

	mState = INITIALIZE;
	mDifficulty = sf::application::scene::Game::EASY;

	visibility(false);
}// DispositionEditorImpl()

// 僨僗僩儔僋僞 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
DispositionEditorImpl::~DispositionEditorImpl()
{
	mbCallBack = false;
	
	if(mpInput){
		mpInput->removeMouseListener(this);
		mpInput->removeKeyboardListener(this);
	
		mpInput->hideMouseCursor();
	
		mpInput->removeKeyboardListener(mpEditCommand);
		mpInput->removeMouseListener(mpEditCommand);
	}
	
	unload();
	delete mpEditCommand;

}// ~DispositionEditorImpl()


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

// 弶婜壔 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void DispositionEditorImpl::initialize(void)
{
	mpInput->addMouseListener(this);
	mpInput->addKeyboardListener(this);
	mpInput->showMouseCursor();

	mpInput->addKeyboardListener(mpEditCommand);
	mpInput->addMouseListener(mpEditCommand);
	
	mState = MAIN;
	mbCallBack = true;
	mbListening = true;
	mpGame->background()->edit(true);

	load();
	z(0.1f);
	visibility(true);
}

//DispositionEditorImpl Scene 偺廔椆 ---------------------------------------------------------
void DispositionEditorImpl::endOfScene(Scene *pScene)
{
	mpGame->background()->edit(false);
	mpGame->controllerPtr()->restart(mpGame->scrollY());
	callSceneEvent(&sf::application::scene::Listener::endOfScene);
	delete this;
} //endOfScene()

// exit key 偑墴偝傟偨両 ------------------------------------------------------
void DispositionEditorImpl::exitKeyPressed(Scene *pScene)
{
	mpGame->background()->edit(false);
	mpGame->controllerPtr()->restart(mpGame->scrollY());
	callSceneEvent(&sf::application::scene::Listener::exitKeyPressed);
	delete this;
} //endOfScene()

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

	if(MKEY_SHIFT & mkey)
		speed = 8.0f;

	if(MKEY_CONTROL & mkey)
		speed = 32.0f;
	
	if(wheel > 0)
		mpGame->scrollY(mpGame->scrollY() + speed);
	else
		mpGame->scrollY(mpGame->scrollY() - speed);
	
	if(mpEditCommand)
		mpEditCommand->mouseWheel(screenX,screenY,mkey);
	
}// mouseWheel()

// 僉乕儃乕僪偑墴偝傟偨両
void DispositionEditorImpl::keyDown(const DWORD keyCode,const DWORD extKeyCode)
{	
	using namespace sf::system::input;
	using namespace sf::application::disposition::command;

	float speed = 1.0f;
	int max = 0;
	
	if(extKeyCode & keyboard::SHIFT)
		speed = 8.0f;

	switch((char)keyCode)
	{
	case 'G':
		endOfScene(this);
		break;
	case 'S':
		mpGame->controllerPtr()->save();
		break;
	case VKEY_DOWN:
		mpGame->background()->startOffsetY(mpGame->background()->startOffsetY() + speed);
		break;
	case VKEY_UP:
		mpGame->background()->startOffsetY(mpGame->background()->startOffsetY() - speed);
		break;
	case VKEY_LEFT:
		mpGame->background()->startOffsetX(mpGame->background()->startOffsetX() - speed);
		break;
	case VKEY_RIGHT:
		mpGame->background()->startOffsetX(mpGame->background()->startOffsetX() + speed);
		break;
	case '1':
//		if((int)selectedObj() > 0)
//			selectedObj(selectedObj() - 1);
		break;
	case '2':
//		max = (mEditType == SET_ENEMY)?(sf::application::enemy::MAX_TYPE):(sf::application::enemy::MAX_ARMYS_TYPE);
//		if((int)selectedObj() < max)
//			selectedObj(selectedObj() + 1);
		break;
	case '3':
		mpInput->removeKeyboardListener(mpEditCommand);
		mpInput->removeMouseListener(mpEditCommand);
		delete mpEditCommand;
		
		if((int)mEditType == (disposition::command::MAX - 1)){
			mEditType = disposition::command::SET_SCROLLSPEED;
		} else {
			mEditType = (disposition::command::TYPE)((int)mEditType + 1);
		}
		mpEditCommand = sf::application::disposition::Controller::create(mEditType);

		mpEditCommand->load();
		mpEditCommand->game(mpGame);
	
		mpInput->addKeyboardListener(mpEditCommand);
		mpInput->addMouseListener(mpEditCommand);

		break;
	}

}// keyDown()

// 塃僋儕僢僋  亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void DispositionEditorImpl::rightButtonDown(const int screenX,const int screenY,const DWORD mkey)
{
	using namespace sf::application::disposition;
	mpGame->controllerPtr()->deleteCommand((float)screenX,(float)screenY,mpGame->scrollY(),mEditType);
}// rightButtonDown

// 嵍僋儕僢僋偑墴偝傟偨 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void DispositionEditorImpl::leftButtonDown(const int screenX,const int screenY,const DWORD mkey)
{
	using namespace sf::application::disposition;
	
	// 僐儅儞僪傪憓擖偡傞丅 //
	
	mpInput->removeKeyboardListener(mpEditCommand);
	mpInput->removeMouseListener(mpEditCommand);

	mpGame->controllerPtr()->insertCommand(mpGame->scrollY(),mpEditCommand);
	
	command::Interface *mpi = sf::application::disposition::Controller::create(mEditType);
	mpi->copy(*mpEditCommand); 
	mpEditCommand = mpi;
//	mpEditCommand->load();
//	mpEditCommand->game(mpGame);		

	mpInput->addKeyboardListener(mpEditCommand);
	mpInput->addMouseListener(mpEditCommand);

}// leftButtonDown();

// 揋偺僥僋僗僠儍傪儘乕僪偡傞 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void DispositionEditorImpl::load(void){
}// load()

// 揋偺僥僋僗僠儍偺傾儞儘乕僪 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void DispositionEditorImpl::unload(void){
}// unload()

// 儅僢僾忣曬偺昞帵 亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅亅
void DispositionEditorImpl::draw(){
	if(!visibility())
		return;

	using namespace sf::application::disposition;

	Controller::CommandList::iterator it = mpGame->controllerPtr()->commandList().begin();
	while(it != mpGame->controllerPtr()->commandList().end())
	{
		it->second->load();
		it->second->draw(this,it->first,false);
		it++;
	}

	// 僇乕僜儖埵抲

	mpEditCommand->draw(this,0.0f,true);

}// draw()

