#include "CGamePlayState.h"
#include "CSGD_FModManager.h"
#include "CSGD_DirectInput.h"
#include "CSGD_MessageSystem.h"
#include "CSGD_ObjectManager.h"
#include "CSGD_TextureManager.h"
#include "CSGD_EventSystem.h"
#include "CNote.h"
#include "CBeatAnalyzer.h"
#include "Debug.h"
#include "CPlayer.h"
#include "CNoteManager.h"
#include "CSongParser.h"
#include "CGame.h"
#include "CWinGameState.h"

void CGamePlayState::Enter(void)
{
	m_nHudID = CSGD_TextureManager::GetInstance()->LoadTexture("Resources/HUD_Blue.png");
	m_nStaffID = CSGD_TextureManager::GetInstance()->LoadTexture("Resources/Staff_Blue.png");
	m_nVertStaffID = CSGD_TextureManager::GetInstance()->LoadTexture("Resources/VerticalLine.png");
	m_nStatusContainerID = CSGD_TextureManager::GetInstance()->LoadTexture("Resources/Song_Meter.png");
	m_nStatusBarID = CSGD_TextureManager::GetInstance()->LoadTexture("Resources/Meter_Filller.png");

	m_fBarStart = 282.0f;
	m_fBarEnd = 420.0f;
	m_fBarPosition = 0.0f;

	m_rProgressRect.left = 0;
	m_rProgressRect.top = 0;
	m_rProgressRect.right = 1020;
	m_rProgressRect.bottom = 100;

//	beatAnalyzer = new CBeatAnalyzer(m_nSoundID, 30.8142857);

	m_pMS	= CSGD_MessageSystem::GetInstance();
	m_pMS->InitMessageSystem(MessageProc);



	//--Init OM & OF & Register Object Types------
	m_pOF	= CSGD_ObjectFactory<string, CBase>::GetInstance();
	m_pOM	= CSGD_ObjectManager::GetInstance();

	m_pOF->RegisterClassType<CNote>("CNote");
	m_pOF->RegisterClassType<CBase>("CBase");
	//--End Register Object Types------

	m_pPlayer = CPlayer::GetInstance();

	m_pPlayer->AddRef();
	m_pPlayer->SetVel(tVector2D(0.0f, 0.0f));
	m_pPlayer->SetHeight(800);
	m_pPlayer->SetWidth(600);
	m_pPlayer->SetMyColor(1.0f, 0.0f, 0.0f, 0.0f);
	m_pPlayer->SetPos(tVector2D(25.0f, 200.0f));
	m_pPlayer->SetPosZ(1.0f);
	m_pPlayer->SetRotation(0.0f);
	m_pPlayer->SetScale(0.5f);
	m_pPlayer->SetType(CBase::OBJECT_PLAYER);
	m_nEqIndex = CSGD_TextureManager::GetInstance()->LoadTexture("Resources/Background_Equalizer.png");
	m_pPlayer->SetImageID(CSGD_TextureManager::GetInstance()->LoadTexture("Resources/AMP_Normal2.bmp"));
	m_pNM = CNoteManager::GetInstance();

 	//CSongParser parser;
 	//parser.SaveFile("../Resources/TechnoSong.mp3");

 	//m_pNM = CNoteManager::GetInstance();
 	//m_pNM->LoadFile("TechnoParsed.bin", CNoteManager::HARD);



	//// Structure to fill in
	//OPENFILENAME ofn;

	//// Clear structure.
	//ZeroMemory(&ofn, sizeof(ofn));

	//// Struct size and owner window.
	//ofn.lStructSize = sizeof(ofn);
	////ofn.hwndOwner = hWnd;

	//// Where to return the choosen file name.
	//char szFileName[260] = {};
	//ofn.lpstrFile = szFileName;
	//ofn.lpstrFile[0] = 0;
	//ofn.nMaxFile = MAX_PATH;

	//// Set the filter extensions.
	//ofn.lpstrFilter = "All Files (*.*)\0*.*\0Media Files (*.mp3)\0*.mp3\0(*.wma)\0*.wma\0";
	//ofn.nFilterIndex = 1;

	//ofn.Flags = OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;

	//if(GetOpenFileName(&ofn))
	//{
	//	std::string file = szFileName;
	//	file += ".bin";

		/*CSongParser parser;
		parser.SaveFile("../Resources/StillAliveSong.mp3");*/

	//	m_pNM->LoadFile(szFileName, CNoteManager::HARD);
	//	
	//}
	//else
	//{
	//	MessageBox(0,0,0,0);
	//}
	//m_pNM = CNoteManager::GetInstance();
	m_pNM->LoadFile1("../Resources/default.mp3", CNoteManager::HARD);

	m_pBM = CBitmapFontManager::GetInstance();
	m_pFont = m_pBM->CreateTemplateInstance(m_pBM->LoadTemplate("Resources/menuFont.xml"));
	m_pFont.LoadKerning("Resources/YesterdayFONT.dat");
	m_pFont.SetScaleX(0.9f);
	m_pFont.SetScaleY(0.9f);

	CSGD_EventSystem::GetInstance()->RegisterClient("UpdateProgressBar", this);	

	m_fProgress = 0.0f;
}

bool CGamePlayState::Input(float fElapsedTime)
{
	CSGD_DirectInput* pDI = CSGD_DirectInput::GetInstance();

	m_pPlayer->Input();

	if(pDI->GetKey(DIK_ESCAPE))
		return false;
	
	return true;
}

void CGamePlayState::Update(float fElapsedTime)
{
	/*if(!CSGD_FModManager::GetInstance()->IsSoundPlaying(m_nSoundID))
		CSGD_FModManager::GetInstance()->PlaySoundA(m_nSoundID);*/




	m_pNM->UpdateObjects(fElapsedTime);

	m_pOM->UpdateObjects(fElapsedTime);
	m_pOM->CheckCollisions();

	CSGD_EventSystem::GetInstance()->ProcessEvents();
	m_pMS->ProcessMessages();
	m_pPlayer->Update(fElapsedTime);
}

void CGamePlayState::Render(void)
{
	char szBuffer[256];
	float* fSpecArr = new float[2048];
	RECT rTemp;
	if(FMOD_OK == CSGD_FModManager::GetInstance()->GetSystemObject()->getSpectrum(fSpecArr, 2048, 0, FMOD_DSP_FFT_WINDOW_RECT))
	{
		for(short i = 0; i < 64; ++i)
		{
			rTemp.bottom = int(480 - fSpecArr[i]*2400);
			rTemp.left = 14*i;
			rTemp.top = int(fSpecArr[i]*2400);
			rTemp.right = 14*(i+1);

			CSGD_TextureManager::GetInstance()->DrawTexture(m_nEqIndex, 14.0f*i, 0.0f, 0.5f, 2.0f, 0.46f);

			//	////////////////////////////////////////////////////////////
			// Draw Equalizer
			CSGD_Direct3D::GetInstance()->SpriteEnd();
			CSGD_Direct3D::GetInstance()->DeviceEnd();
			CSGD_Direct3D::GetInstance()->DrawRect(rTemp, 0, 0, 0);
			CSGD_Direct3D::GetInstance()->DeviceBegin();	
			CSGD_Direct3D::GetInstance()->SpriteBegin();
			//////////////////////////////////////////////////////////////

		}
	}
	delete[] fSpecArr;
	CSGD_TextureManager* pTM = CSGD_TextureManager::GetInstance();
	pTM->DrawTexture(m_nStaffID, 0.0f, 35.0f, 0.5f, 1.0f, 1.0f, NULL, 0.0f, 0.0f, 0.0f);
	pTM->DrawTexture(m_nStaffID, 0.0f, 145.0f, 0.5f, 1.0f, 1.0f, NULL, 0.0f, 0.0f, 0.0f);
	pTM->DrawTexture(m_nStaffID, 0.0f, 255.0f, 0.5f, 1.0f, 1.0f, NULL, 0.0f, 0.0f, 0.0f);
	pTM->DrawTexture(m_nStaffID, 0.0f, 365.0f, 0.5f, 1.0f, 1.0f, NULL, 0.0f, 0.0f, 0.0f);
	pTM->DrawTexture(m_nVertStaffID, 100.0f, 0.0f, 0.5f, 1.0f, 1.0f, NULL);
	m_pOM->RenderObjects();
	m_pPlayer->Render();
	pTM->DrawTexture(m_nHudID, 0.0f, 481.0f, 0.0f, 1.0f, 1.0f, NULL, 0.0f, 0.0f, 0.0f);

	float percent;
	CNoteManager::GetInstance()->GetPercentSongDone(percent);

	RECT temp = m_rProgressRect;
	temp.right = (LONG)(temp.right * percent);
	if(!percent)
		temp = m_rProgressRect;

	pTM->DrawTexture(m_nStatusBarID, 282.0f, 545.0f, 0.0f, 0.226f, 0.4f, &temp);
	pTM->DrawTexture(m_nStatusContainerID, 195.0f, 520.0f, 0.0f, 0.4f, 0.3f, NULL);
	if(!m_fProgress)
		sprintf_s(szBuffer, 256, "Accuracy: 100%%");
	else
		sprintf_s(szBuffer, 256, "Accuracy: %i%%", (int)(m_fProgress*100));
	m_pFont.DrawString(szBuffer, 6, 490);

	switch(CNoteManager::GetInstance()->GetDifficulty())
	{
	case CNoteManager::EASY:
		sprintf_s(szBuffer, 256, "Target:   60%%");
		break;
	case CNoteManager::MEDIUM:
		sprintf_s(szBuffer, 256, "Target:   70%%");
		break;
	case CNoteManager::HARD:
		sprintf_s(szBuffer, 256, "Target:   80%%");
		break;
	}
	m_pFont.DrawString(szBuffer, 6, 520);

	switch(CNoteManager::GetInstance()->GetCurrentState())
	{
	case CNoteManager::INTRO:
		sprintf_s(szBuffer, 256, "  Dont shoot the friendly white notes!");
		m_pFont.DrawString(szBuffer, 125, 5);
		break;
	case CNoteManager::RISE:
		sprintf_s(szBuffer, 256, "Destroy the evil notes! They are killing the song!");
		m_pFont.DrawString(szBuffer, 40, 5);
		break;
	case CNoteManager::MIDDLE:
		sprintf_s(szBuffer, 256, "    Keep it up! Theyre taking over!");
		m_pFont.DrawString(szBuffer, 125, 5);
		break;
	case CNoteManager::FALL:
		sprintf_s(szBuffer, 256, "      A little bit farther...");
		m_pFont.DrawString(szBuffer, 125, 5);
		break;
	case CNoteManager::END:
		switch(CNoteManager::GetInstance()->GetDifficulty())
		{
		case CNoteManager::EASY:
			if(m_fProgress < 0.6f)
			{
				sprintf_s(szBuffer, 256, "You failed to equalize the music....");
				m_pFont.DrawString(szBuffer, 125, 5);
			}
			else
			{
				sprintf_s(szBuffer, 256, "Congratulations!  Youve equalized the music!!!");
				m_pFont.DrawString(szBuffer, 100, 5);
			}
			break;
		case CNoteManager::MEDIUM:
			if(m_fProgress < 0.7f)
			{
				sprintf_s(szBuffer, 256, "You failed to equalize the music....");
				m_pFont.DrawString(szBuffer, 125, 5);
			}
			else
			{
				sprintf_s(szBuffer, 256, "Congratulations!  Youve equalized the music!!!");
				m_pFont.DrawString(szBuffer, 125, 5);
			}
			break;
		case CNoteManager::HARD:
			if(m_fProgress < 0.8f)
			{
				sprintf_s(szBuffer, 256, "You failed to equalize the music....");
				m_pFont.DrawString(szBuffer, 125, 5);
			}
			else
			{
				sprintf_s(szBuffer, 256, "Congratulations!  Youve equalized the music!!!");
				m_pFont.DrawString(szBuffer, 125, 5);
				
			}
			break;
		}
		break;
	}
}

void CGamePlayState::Exit(void)
{
	CSGD_TextureManager::GetInstance()->ReleaseTexture(m_pPlayer->GetImageID());
	CSGD_TextureManager::GetInstance()->ReleaseTexture(m_nHudID);
	CSGD_TextureManager::GetInstance()->ReleaseTexture(m_nStaffID);
	CSGD_TextureManager::GetInstance()->ReleaseTexture(m_nEqIndex);
	CSGD_TextureManager::GetInstance()->ReleaseTexture(m_nVertStaffID);
	CSGD_TextureManager::GetInstance()->ReleaseTexture(m_nStatusContainerID);
	CSGD_TextureManager::GetInstance()->ReleaseTexture(m_nStatusBarID);
	m_pPlayer->Release();

	m_pNM->RemoveAllObjects();
	m_pNM->DeleteInstance();

	if(m_pOF)
	{
		m_pOF->ShutdownObjectFactory();
		m_pOF = NULL;
	}

	if(m_pOM)
	{
		m_pOM->RemoveAllObjects();
		m_pOM = NULL;
	}

	if (m_pMS)
	{
		m_pMS->ShutdownMessageSystem();
		m_pMS = NULL;
	}
}

void CGamePlayState::HandleEvent(CEvent* pEvent)
{
	if(pEvent->GetEventID() == "UpdateProgressBar")
	{
		unsigned int badNotes = *((unsigned int*)(pEvent->GetParam()));
		unsigned int totalNotes = *((unsigned int*)(pEvent->GetParam2()));
		delete pEvent->GetParam();
		delete pEvent->GetParam2();
		m_fProgress = 1 - ((float)badNotes)/((float)totalNotes);
	}
}

void MessageProc(CBaseMessage* pMsg)
{
	switch(pMsg->GetMessageID())
	{
	case MSG_CREATE_GOOD_NOTE:
		{
			CCreateGoodNoteMessage* pCBM = (CCreateGoodNoteMessage*)pMsg;
			CNote* pNote = (CNote*)pCBM->GetGoodNote();

			if(pNote)
			{
				pNote->SetImageID(CSGD_TextureManager::GetInstance()->LoadTexture("Resources/Good_Cool2.png"));			
				pNote->SetNoteType(pCBM->GetNoteType());
				pNote->SetMyColor(D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f));
				pNote->SetPos(tVector2D(pCBM->GetPosX(), pCBM->GetPosY()));
				pNote->SetPosZ(1.0f);
				pNote->SetScale(0.8f);
				pNote->SetWidth(CSGD_TextureManager::GetInstance()->GetTextureWidth(pNote->GetImageID()));
				pNote->SetHeight(CSGD_TextureManager::GetInstance()->GetTextureWidth(pNote->GetImageID()));
				
				pNote->SetType(CBase::OBJECT_GOOD_NOTE);
				pNote->SetVelX(pCBM->GetVelX());
				pNote->SetVelY(0);
				pNote->SetRotation(0.0f);
				pNote->SetIsHit(false);

				pNote->SetStartY(pCBM->GetPosY());
			

				RECT tempRect;
				tempRect.top = 0;
				tempRect.left = 0;
				tempRect.bottom = 40;
				tempRect.right = 40;

				pNote->SetCollisionRect(tempRect);
				
				CSGD_ObjectManager::GetInstance()->AddObject(pNote);
			}

		}
		break;

	case MSG_DESTROY_NOTE:
		{
			CDestroyNoteMessage* pCBM = (CDestroyNoteMessage*)pMsg;
			CNote* pNote = (CNote*)pCBM->GetNote();
			
			if(pNote)
			{

				CSGD_ObjectManager::GetInstance()->RemoveObject(pCBM->GetNote());
			}
		}
		break;

	case MSG_CREATE_BAD_NOTE:
		{
			CCreateBadNoteMessage* pCBM = (CCreateBadNoteMessage*)pMsg;
			CNote* pNote = (CNote*)pCBM->GetBadNote();

			if(pNote)
			{
				pNote->SetImageID(CSGD_TextureManager::GetInstance()->LoadTexture("Resources/Bad_Mad2.png"));
				pNote->SetNoteType(pCBM->GetNoteType());
				pNote->SetMyColor(D3DXCOLOR(1.0f, 0.0f, 0.0f, 0.0f));
				pNote->SetPos(tVector2D(pCBM->GetPosX(), pCBM->GetPosY()));
				pNote->SetPosZ(1.0f);
				pNote->SetScale(0.8f);
				pNote->SetWidth(CSGD_TextureManager::GetInstance()->GetTextureWidth(pNote->GetImageID()));
				pNote->SetHeight(CSGD_TextureManager::GetInstance()->GetTextureWidth(pNote->GetImageID()));
				
				pNote->SetType(CBase::OBJECT_BAD_NOTE);
				pNote->SetVelX(pCBM->GetVelX());
				pNote->SetVelY(0);
				pNote->SetRotation(0.0f);
				pNote->SetIsHit(false);

				pNote->SetStartY(pCBM->GetPosY());

				RECT tempRect;
				tempRect.top = 0;
				tempRect.left = 0;
				tempRect.bottom = 60;
				tempRect.right = 80;

				pNote->SetCollisionRect(tempRect);
				
				CSGD_ObjectManager::GetInstance()->AddObject(pNote);
			}
		}
		break;


	case MSG_CREATE_BULLET:
		{
			CCreateBulletMessage* pCBM = (CCreateBulletMessage*)pMsg;
			CSGD_ObjectFactory<string, CBase>* m_pOF = CSGD_ObjectFactory<string, CBase>::GetInstance();

			CBase* pBullet = (CBase*)m_pOF->CreateObject("CBase");
			pBullet->GetAnimInstance()->SetSpriteFile("Waves.png");
			pBullet->GetAnimInstance()->SetCurrentAnim("Sound Wave");
			pBullet->SetIsAnimated(true);
			//pBullet->SetImageID(CSGD_TextureManager::GetInstance()->LoadTexture("Resources/boomcloud.bmp"));
			pBullet->SetPosX(pCBM->GetPlayer()->GetPosX() + 25);
			pBullet->SetPosY(pCBM->GetPlayer()->GetPosY() +  25);
			pBullet->SetType(CBase::OBJECT_SOUND_WAVE);
			pBullet->SetVelX(300);
			pBullet->SetScale(0.75f);

			pBullet->SetWidth(pBullet->GetAnimInstance()->GetCurrentCollRect().right - pBullet->GetAnimInstance()->GetCurrentCollRect().left);
			pBullet->SetHeight(pBullet->GetAnimInstance()->GetCurrentCollRect().bottom - pBullet->GetAnimInstance()->GetCurrentCollRect().top);
			
			CSGD_ObjectManager::GetInstance()->AddObject(pBullet);

			SAFE_RELEASE(pBullet);

		}
		break;

	case MSG_DESTROY_BULLET:
		{
			CDestroyBulletMessage* pCBM = (CDestroyBulletMessage*)pMsg;

			if(pCBM->GetBullet())
			{
				CBase* pBullet = pCBM->GetBullet();
				CSGD_ObjectManager::GetInstance()->RemoveObject(pBullet);
			}
		}
		break;
	}
}
