#include "stdinc.h"
#include "cTearsApp.h"
#include "TOOLMemory.h"
#include "cActiveObjectList.cpp"
#include "cTearsPlayer.h"
#include "cTearsActionWindow.h"
#include "resource.h"
#include <vfw.h>
#include "cPopupMenu.h"

cTearsPictureBook PictureBook;

const int STAGE_COUNT = 10;

static char *StageBackPictureFileNames[STAGE_COUNT] = {
	"s1back.bmp",
	"s2back.bmp",
	"s3back.bmp",
	"s4back.bmp",
	"s5back.bmp",
	"s6back.bmp",
	"s7back.bmp",
	"s8back.bmp",
	"s9back.bmp"
	"s10back.bmp",
};

static char *StageBackMusicFileNames[STAGE_COUNT] = {
	"s0back.mid",
	"s0back.mid",
	"s0back.mid",
	"s0back.mid",
	"s0back.mid",
	"s0back.mid",
	"s0back.mid",
	"s0back.mid",
	"s0back.mid",
	"s0back.mid"

};

static sStageDesc StageDescs[STAGE_COUNT] = {
	{ 6, 10, 1, 0, NULL, NULL, NULL, NULL },
	{ 6, 20, 40, 64, NULL, NULL, NULL, NULL },
	{ 7, 25, 80, 32, NULL, NULL, NULL, NULL },
	{ 7, 30, 120, 16, NULL, NULL, NULL, NULL },
	{ 8, 35, 160, 8, NULL, NULL, NULL, NULL },
	{ 9, 40, 200, 4, NULL, NULL, NULL, NULL },
	{ 9, 45, 240, 2, NULL, NULL, NULL, NULL },
	{ 9, 50, 280, 2, NULL, NULL, NULL, NULL },
	{ 10, 55, 320, 1, NULL, NULL, NULL, NULL },
	{ 10, 60, 360, 1, NULL, NULL, NULL, NULL }
};

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

cTearsApp::cTearsApp(){
}

cTearsApp::~cTearsApp(){

}

//////////////////////////////////////////////////////////////////////
// 응용 프로그램 준비/제거 작업
//////////////////////////////////////////////////////////////////////

BOOL cTearsApp::Open(){
	if(!AppWindow.Create()) return false;
	if(!Display.Create(AppWindow)){
		MessageBox(NULL, "디스플레이를 초기화 할 수 없었습니다.", NULL, MB_OK);
		return false;
	}
	if(!Display.SetCooperativeLevel(DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE)){
		MessageBox(NULL, "다이렉트 드로우 협력 등급을 설정할 수 없었습니다.", NULL, MB_OK);
		return false;
	}
	if(!Display.SetDisplayMode(640, 480, 16)){
		return false;
	}
	if(!Display.CreateDoubleBuffer()){
		MessageBox(NULL, "더블 버퍼를 생성할 수 없었습니다.", NULL, MB_OK);
		return false;
	}
	SetCursor(LoadCursor(*this, MAKEINTRESOURCE(IDC_TEARS)));

	return true;
}

void cTearsApp::Close(){
	Display.DestroyDoubleBuffer();
	Display.RestoreDisplayMode();
	Display.SetCooperativeLevel(DDSCL_NORMAL);
	Display.Destroy();
	AppWindow.Destroy();
	ShowCursor(TRUE);
}

//////////////////////////////////////////////////////////////////////
// 애플리케이션의 중심 수행부
// 전형적인 구조화 프로그래밍 방식을 따른다.
//////////////////////////////////////////////////////////////////////

int cTearsApp::Run(){
	int rv;

	if(!Open()) return 0;

	rv = AppLoop();

	Close();

	return rv;
}

int cTearsApp::AppLoop(){
	eStartupMenuItemID Selection;

//	if(!Prologue()) return 0;
	if(!Title()) return 0;

	do{ // 종료가 선택되지 않는한 프로그램은 계속 반복된다.
		Selection = StartupMenu();
		switch(Selection){
		case SMID_START: // 게임 시작
			ShowCursor(FALSE);
			GameMain();
			ShowCursor(TRUE);
			break;
		}
	} while(Selection != SMID_EXIT);

	return 0;
}

//////////////////////////////////////////////////////////////////////
// 시작 메뉴
//////////////////////////////////////////////////////////////////////

eStartupMenuItemID cTearsApp::StartupMenu(){
	const int Items = 2;
	cPopupMenu Menu;
	cPicture BackPic, BtnPic[2];
	int rv;
	sPopupMenuItem MenuItems[Items] = {
		NULL, &BtnPic[0], 80, 380, 160, 64, SMID_START,
		NULL, &BtnPic[1], 400, 380, 160, 64, SMID_EXIT
	};

	BackPic.Create(new cMedium("title.bmp"));
	BtnPic[0].Create(new cMedium("smbtn0.bmp"));
	BtnPic[1].Create(new cMedium("smbtn1.bmp"));

//	Menu.SetPopupMenu(this, Display.GetFrontPic(), &BackPic, MenuItems, Items);
	if(Menu.Create(WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN, 
		0, 0, 640, 480, &AppWindow, 0, Display.GetFrontPic(), &BackPic, MenuItems, Items)){
		rv = MessageLoop();
		Menu.Destroy();
	}else rv = SMID_EXIT;

	BackPic.DeleteMedium();
	BtnPic[0].DeleteMedium();
	BtnPic[1].DeleteMedium();

	return eStartupMenuItemID(rv);

}

//////////////////////////////////////////////////////////////////////
// 데몬스트레이션
//////////////////////////////////////////////////////////////////////

BOOL cTearsApp::Prologue(){
// 후에 동영상을 연주할 것임
/*	int rv;
	HWND hWnd;
	hWnd = MCIWndCreate(AppWindow, *this,
		WS_CHILD | WS_VISIBLE | MCIWNDF_NOMENU | MCIWNDF_NOPLAYBAR , "logo.avi");
	if(hWnd == NULL)
		return TRUE;

	MoveWindow(hWnd, 0, 0, 640, 480, FALSE);
	MCIWndPlay(hWnd);
	while(DispatchAMessage(&rv)){
		if(MCIWndGetEnd(hWnd) <= MCIWndGetPosition(hWnd))
			break;
	}

	MCIWndDestroy(hWnd);
*/
	return TRUE;
}

BOOL cTearsApp::Title(){
	return TRUE;
}

BOOL cTearsApp::Epilogue(){
// 후에 동영상을 연주할 것임
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// 게임 관련
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
// 게임의 중심 수행부
//////////////////////////////////////////////////////////////////////
int cTearsApp::GameMain(){
	cTearsPlayer Player;
	cPictureBook TearsBook;
	cPicture StageBack;
	cPicture StageTitle;
	cPicture StageClear;
	cPicture PlayerDead;
	int Stage;
	int rv;
	char buff[256];

	TearsBook.AutoCropPicture("Tears.bmp", 11 * 10, 40, 40);
	cTear::SetPictureBook(&TearsBook);

	if(!ActionWindow.Create("동작 창", WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 
		0, 0, 640, 480, &AppWindow, 0, &Display))
		return -1;
	AppWindow.SetMainChild(&ActionWindow);
	ActionWindow.SetFocus();
	ActionWindow.Set(&Player);
	ActionWindow.SetBackPicture(&StageBack);

	StageTitle.Create(new cMedium("ready.bmp"));
	StageClear.Create(new cMedium("clear.bmp"));
	PlayerDead.Create(new cMedium("dead.bmp"));

	for(Stage = 0;; Stage ++){
		// 게임의 중심 수행부
//		mciPlay
		StageBack.Create(new cMedium(StageBackPictureFileNames[Stage % STAGE_COUNT]));
		StageDescs[Stage % STAGE_COUNT].pBackPicture = &StageBack;
		StageDescs[Stage % STAGE_COUNT].pTitlePicture = &StageTitle;
		StageDescs[Stage % STAGE_COUNT].pClearPicture = &StageClear;
		StageDescs[Stage % STAGE_COUNT].pDeadPicture = &PlayerDead;
		sprintf(buff, "open %s", StageBackMusicFileNames[Stage % STAGE_COUNT]);
		mciSendString(buff, NULL, 0, NULL);
		sprintf(buff, "play %s", StageBackMusicFileNames[Stage % STAGE_COUNT]);
		mciSendString(buff, NULL, 0, NULL);

		Player.SetStage(Stage + 1, &StageDescs[Stage % STAGE_COUNT]);
		rv = GameBody(&Player);
		StageBack.DeleteMedium();

		sprintf(buff, "stop %s", StageBackMusicFileNames[Stage % STAGE_COUNT]);
		mciSendString(buff, NULL, 0, NULL);
		sprintf(buff, "close %s", StageBackMusicFileNames[Stage % STAGE_COUNT]);
		mciSendString(buff, NULL, 0, NULL);
		if(rv == MLEC_EXITAPP) break;
		if(rv == TEC_DEAD) break;
	}
	PlayerDead.DeleteMedium();
	StageTitle.DeleteMedium();
	StageClear.DeleteMedium();

	// 게임 삭제 작업
	AppWindow.SetMainChild(NULL);
	ActionWindow.Destroy();
//	PictureBook.DestroyAll();
	return rv;
}

int cTearsApp::GameBody(cTearsPlayer *pPlayer){
	// 1초당 16번 세계를 동작 시킨다.
	// 이 동안에 ActionWindow는 1초에 16번씩
	// 프레임을 재생한다.
	DWORD ThisTime, ExecuteTime;
	int rv;

	ExecuteTime = GetTickCount() + 64;
	ThisTime = GetTickCount();
	while(DispatchAMessage(&rv)){ // 시스템 메시지를 메시지 윈도우로 전송한다.
		ThisTime = GetTickCount();
		if(ThisTime >= ExecuteTime){
			ExecuteTime = ThisTime + 64;
			pPlayer->Act(); // 게임을 동작시킨다.
			ActionWindow.Invalidate();
			ActionWindow.Update();
		}
	}
	return rv;
}
	
