#include "GStaticData.h"
//#include "scene/GTitleScene.h"
#include "GGameScene.h"
#include "GTitleScene.h"
#include "GPlayerSelectScene.h"
#include "GStageSelectScene.h"
//#include "scene/GSelectMapScene.h"


#ifdef _DEV_CPP_
#undef main
#endif
GStaticData* staticData = NULL;

#undef _RS_CONSTS_
#include "rss/RSConsts.h"

#include <windows.h>

#include <SDL/SDL_syswm.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_net.h>

#include "rss/PacketData.h"

#include <stdio.h>

#include <tchar.h>

using namespace std;

#ifdef _NETWORK
// パケット受信
int func( void* data ) {
	/////////////////////////
	// サーバからの情報受信用
		
	UDPsocket sdServerSocket;
	UDPpacket* lpServerPacket;

	if( !( sdServerSocket = SDLNet_UDP_Open( RSConsts::CLIENT_RECV_PORT ) ) ){
		return RSConsts::ErrorType::NET_OPEN_SOCKET_ERROR;
	}

	if( !( lpServerPacket = SDLNet_AllocPacket( PACKET_DATA_LENGTH ) ) ) {
		return RSConsts::ErrorType::NET_ALLOC_PACKET_ERROR;
	}


	while( staticData->isRunning() ) {
		if( SDLNet_UDP_Recv( sdServerSocket, lpServerPacket ) ) {
			// データを変換
			PacketData pacPacketData = (*((PacketData*)( lpServerPacket->data )));

			// 適用
			if( pacPacketData.m_nUUID >= 0 ) {
				// 自分の情報
				staticData->m_ObjectManager.m_nPlayingIndex = pacPacketData.m_nUUID;
			} else {
				// 他人の情報
				// 値反映
				fprintf( stdout, "[id:%d][state:%d][x:%d,y:%d]\n", pacPacketData.m_nID,
					pacPacketData.m_nState, pacPacketData.m_nX, pacPacketData.m_nY );
				GPlayer* player = &staticData->m_ObjectManager.m_aryPlayerList[ pacPacketData.m_nID ];
				player->setCenter( pacPacketData.m_nX, pacPacketData.m_nY );
				player->changeState( pacPacketData.m_nState );
			}
		}
	}

	SDLNet_FreePacket( lpServerPacket );

	return 0;
}
#endif

int main(int argc, char** argv)
{
	HPL_LOGGER.init( "HogePiyo.txt" );
	// 生成
	staticData = new GStaticData();
	HPL_LOGGER.write( "ap start" );

	// フルスクリーンチェック
	if(staticData->getSetting()->isFullScreen){
		// フルスクリーンにする
		staticData->getScreenFormat()->videoFlags |= SDL_FULLSCREEN;
	}

	// ウィンドウセットアップ
	staticData->setupWindow();

	// テクスチャ読み込み
	staticData->loadTexture();


	// シーン追加
	HPLSceneManager* sceneManager = staticData->getSceneManager();

	sceneManager->putScene( GEnum::SceneType::TITLE, new GTitleScene() );
	sceneManager->putScene( GEnum::SceneType::PLAYER_SELECT, new GPlayerSelectScene() );
	sceneManager->putScene( GEnum::SceneType::STAGE_SELECT, new GStageSelectScene() );
	sceneManager->putScene( GEnum::SceneType::GAME, new GGameScene() );

	sceneManager->setScene( GEnum::SceneType::TITLE );

	HPL_LOGGER.write( "initialize done" );

	bool bIsFirst = true;

#ifdef _NETWORK
	bool bNetAvailable = true;

	// SDLNet接続
	if( SDLNet_Init() < 0 ) {
		MessageBox( NULL, _T("SDLNet_Init Failed"), _T("hoge"), MB_OK );
		bNetAvailable = false;
	}
	UDPsocket sdClientSocket;
	UDPpacket *lpPacket;
	IPaddress adServerAddress;

	if( ! ( sdClientSocket = SDLNet_UDP_Open( 0 ) ) ) {
		MessageBox( NULL, _T("SDLNet_UDP_Open Failed"), _T("hoge"), MB_OK );
		bNetAvailable = false;
	}

	using namespace std;
	vector<string> vecLines = HPLFile::loadStringLinesFromFile( "ClientData.txt" );

	string szHostName = "localhost";
	int nPort = RSConsts::SERVER_RECV_PORT;
	for( int i = 0; i < static_cast<int>( vecLines.size() ) ; i ++ ) {
		if( HPLFile::isCommentLine( &vecLines[i] ) ) {
			continue;
		}

		vector<string> equals = HPLString::split( vecLines[i], "=" );
		if( equals.size() < 2 ) {
			continue;
		}
		if( equals[0].compare( "ServerHostName" ) == 0 ) {
			szHostName = equals[1];
		} else if( equals[0].compare( "ServerPort" ) == 0 ) {
			nPort = atoi( equals[1].c_str() );
		}
	}
	if( SDLNet_ResolveHost( &adServerAddress, szHostName.c_str(), nPort ) == -1 ) {
		MessageBox( NULL, _T("SDLNet_ResolveHost Failed"), _T("hoge"), MB_OK );
		bNetAvailable = false;
	}

	// alloc packet
	PacketData pacPacketData;

	if( ! ( lpPacket = SDLNet_AllocPacket( sizeof( pacPacketData ) ) ) ) {
		MessageBox( NULL, _T("SDLNet_AllocPacket Failed"), _T("hoge"), MB_OK );
		bNetAvailable = false;
	}

	SDL_Thread* lpThread = NULL;
	if( bNetAvailable ) {
		lpThread = SDL_CreateThread(func, NULL );
	}

#endif

	while(staticData->isRunning()){
		// パケット送信

		sceneManager->processScene();
		if( bIsFirst ) {
			HPL_LOGGER.write( "process scene done" );
		}
		
		staticData->processFadeOut();
		if( bIsFirst ) {
			HPL_LOGGER.write( "process fade out done" );
		}
		
		// event
		staticData->doEvent();
		if( bIsFirst ) {
			HPL_LOGGER.write( "process do event done" );
		}

		// common
		staticData->doCommonLoopProcess();
		if( bIsFirst ) {
			HPL_LOGGER.write( "process common loop done" );
			bIsFirst = false;
		}

#ifdef _NETWORK

		if( bNetAvailable ) {
			// 情報をサーバへ送信
			lpPacket->address = adServerAddress;
			PacketData pacPacketData;
			GPlayer* player = &staticData->m_ObjectManager.m_aryPlayerList[ staticData->m_ObjectManager.m_nPlayingIndex ];
			pacPacketData.m_nType = player->getType();
			pacPacketData.m_nX = player->getCenter().getX();
			pacPacketData.m_nY = player->getCenter().getY();
			pacPacketData.m_nState = player->getState()->getState();

			lpPacket->data = (Uint8*)(&pacPacketData);
			lpPacket->len = PACKET_DATA_LENGTH;

			// 送信
			SDLNet_UDP_Send( sdClientSocket, -1, lpPacket );
		}
#endif

	}

#ifdef _NETWORK
	
	if( bNetAvailable ) {
		if( lpThread != NULL ) {
			int status = 0;
			SDL_WaitThread( lpThread , &status );
		}

		//SDLNet_FreePacket( lpPacket );
	}
#endif

	delete staticData;

	return 0;
}
