/**
@file main.cpp
@brief rota_graphのすべての処理
@note
<h2>CSVデータの記述の仕方</h2>
画像は 相対パス、絶対パスどっちでもOK  bmp png jpeg等
@code
ベースの画像名 ,何分割(整数) ,倍率(小数),画像の縦横のサイズ(2の累乗を推奨）,抜き色red,抜き色green,抜き色blue
@endcode

*/
#define BOOST_ENABLE_ASSERT_HANDLER//assertion_failed

#include <dxex/manager.hpp>
//#include <dxex/dxexlib.hpp>
#include <dkutil/gui/select.hpp>
#include <dkutil/parser/csv.hpp>
#include <dkutil/filesystem/std_filestream.hpp>
#include <dkutil/math/trig_func.hpp>

namespace boost{
	void assertion_failed(char const * expr, char const * function, char const * file, long line){
		dkcErrorMessage(expr, file,line,function);
	}
}

using namespace dxex;
using namespace dkutil;

bool isInt(int type){
	return (type==edkInt || type==edkUInt);
}
bool isFloat(int type){
	return (type==edkDouble);
}
void Chack3DFlag(void){
  HRESULT _hr = MessageBox(NULL,"3Dアクセラレータを使いますか？","Message",MB_YESNO);

  if(_hr==IDYES){//はいだったばあい
    SetUse3DFlag(TRUE);

  }else{//いいえだったばあい
    SetUse3DFlag(FALSE);

  }
}

inline int getOptimizeHeight(int hc,int graph_h){
	int t = 0;
	for(int i=1;t < DxLibManager::getScreenHeight();i++){
		
		t = (int)pow(2,i);

		if(t > (hc * graph_h)){
			break;
		}
	}
	return t;
}


// WinMain 関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
			 LPSTR lpCmdLine, int nCmdShow )
{
	/*dkutil::dODS("a2 = %d",GetAngle2(0,0,50,50));
	dkutil::dODS("a1 = %d",GetAngle(0,0,50,50));
	return 0;*/
	int r = edk_FAILED;

	DxLibManager mgr;
	DxLibInitializer init;
	
	Chack3DFlag();

	char filename[MAX_PATH + 1024]="";
	char savename[MAX_PATH + 1024]="";
	{
	
		bool re = FileOpenDialog(filename,sizeof(filename),"設定ファイルを選択してください。",
			"csv(*.csv)\0*.csv\0All files(*.*)\0*.*\0\0",NULL,NULL);
		if(false==re){
			return r;
		}
	}

	std_filestream stream;
	stream.reset(filename,read_mode | text_mode);
	stream.open();
	char buff[2048]="";
	stream.all_read(buff,sizeof(buff));

	CSVParser par;
	par.reset(buff);
	if(par.empty()){
		return r;
	}
	if(par.size() < 4){
		return r;
	}
	if(IDYES==MessageBox(NULL,"スペースを取り除きますか？","message",MB_YESNO))
	{
		par.space_erase();
	}

	{

		bool re = FileSaveDialog(savename,sizeof(savename),"保存するファイル名を!!!",
			"bmp(*.bmp)\0*.bmp\0\0",NULL,NULL);
		if(false==re){
			return r;
		}
	}

	

	if(false==init.reset()){
		return r;
	}

	
	int string_width;
	//画像ハンドル
	int base_handle;
	//分割数
	UINT div_num;
	//倍率
	double mul_per;
	//画像の縦横
	UINT graph_wh;
	
	//透明色
	int TransCol;
	try
	{
		CSVAnalyzer ana;
		ana.reset(par);
		CSVAnalyzer::const_iterator it = ana.begin();

		
		const GeneralPurposeVariable v = (*it);
		if(v.type() != edkString){
			throw std::runtime_error("ファイル名指定が文字列ではない");
		}
		//const std::string rstr = (*it).str;
		base_handle = LoadGraph(v.c_str());

		if(-1==base_handle){
			dMB("%s をロードできませんでした。",(*it).c_str());
			goto End;
		}
		it++;
		if(false==isInt((*it).type())){
			throw std::runtime_error("整数指定がint型整数ではない");
		}

		div_num = (*it).GetUnionData().ui;

		
		it++;
		if(false==isFloat((*it).type())){
			throw std::runtime_error("少数指定がdouble型ではない");
		}
		mul_per = (*it).GetUnionData().d;

		it++;
		if(false==isInt((*it).type())){
			throw std::runtime_error("整数指定がint型整数ではない");
		}

		graph_wh = (*it).GetUnionData().ui;
		
		it++;
		//抜き色Temp
		UINT trc[3]={0};
		int i = 0;
		for(;it != ana.end();it++,i++){
			trc[i] = (*it).GetUnionData().ui;
		}	//抜き色セット
		if(i){
			SetTransColor(trc[0],trc[1],trc[2]);
			SetGraphTransColor(base_handle,trc[0],trc[1],trc[2]);
			TransCol = GetColor(trc[0],trc[1],trc[2]);
		}else{
			TransCol = GetColor(0,0,0);
		}
			
	}catch(std::runtime_error e){
		MB(e.what());
		goto End;
	}



	{
		int white = GetColor(255,255,255);
		sine_float_table st;
		//key_wrap
		for(;;){

			mgr.Update();
			mgr.screen_clear();
			if(mgr.isEnd()){
				break;
			}
			if(mgr.keyState(KEY_INPUT_ESCAPE)){
				break;
			}
			
			int ww = 512 / graph_wh;
			int wc = 0,hc = 0;
			int half = graph_wh / 2;
			for(int i=0;i<div_num;i++)
			{
				if(wc >= ww){
					wc = 0;
					hc ++;
				}
				DrawRotaGraph(
					(wc * graph_wh) + half,
					(hc * graph_wh) + half,
					mul_per,i * st.getDoublePAI() / (div_num / 2),
					base_handle,TRUE,FALSE);

				
				wc++;
			}
			Sleep(30);

			static bool succeeded = false;
			if(succeeded==false){
				if(true==mgr.saveScreen(512,getOptimizeHeight(hc,graph_wh),savename)){
					succeeded = true;
					
				}else{
					int id = MessageBox(NULL,"なんか上手く保存できなかったけど、もう一回TRY?","HOGE",MB_YESNO);
					if(id==IDNO){
						break;
					}
				}
			}else{
				static count = 0;
				DrawRotaGraph(
					half,
					half,
					mul_per,count * st.getDoublePAI() / 180,
					base_handle,TRUE,FALSE
				);


				DrawRotaGraph(
					half + graph_wh,
					half + graph_wh,
					mul_per,count * st.getDoublePAI() / 180,
					base_handle,TRUE,TRUE
				);
				count++;
				if(360 <= count){
					count = 0;
				}

				DrawBox(0,0,512,getOptimizeHeight(hc,graph_wh),white,FALSE);



			}
						



			
			
			mgr.screen_flip();
			//WaitKey();



			
		}//end of loop
	}

End:

	init.clear();

	r = edk_SUCCEEDED;
	return r;
Error:
	mgr.screen_flip();
	WaitKey();
	goto End;
}