#include "ats_application.h"
#include "ats_vp.h"
#include "ats_dxf.h"
#include "ats_exception.h"
#include "ats_glboid.h"
#include "ats_ltailboid.h"
#include <iostream.h>
#include <string>
#include <ctime>
using namespace ats;
using namespace std;

Application::Application(int argc, char** argv)
: m_argc(argc), m_argv(argv), m_glut(0), m_arg(argc, argv, "h?", "f1")
{
	m_glut = Glutxx<GLdouble>::instance(&m_argc, m_argv, 300, 300);
}

Application::~Application()
{
	delete m_glut;
}

void Application::LoadFile(const char* filename)
{
	string str_fname(filename);

	// 拡張子が.vpなら
	if(string::npos != str_fname.find(".vp")){
		// 読み込んで
		Obj3D<GLdouble>* f = new Vp<GLdouble>(filename);
		// Glutxxの描画リストに加える。
		m_glut->m_draw_list.push_back(f);
		cout << "load : " << filename << endl;
	}
	// 拡張子が.dxfなら
	if(string::npos != str_fname.find(".dxf")){
		// 読み込んで
		Obj3D<GLdouble>* f = new Dxf<GLdouble>(filename);
		// Glutxxの描画リストに加える。
		m_glut->m_draw_list.push_back(f);
		cout << "load : " << filename << endl;
	}
}

void Application::PrintHelp()
{
	// 一度だけ実行される。
	static bool flug = false;
	if(flug == false){
		cout << "view3d" << endl
			 << '\t' << "3D object viewer for Windows95/98/NT4/2k" << endl
			 << "Coder" << endl
			 << '\t' << "Atsushi Yamashita" << endl
			 << "use" << endl
			 << '\t' << "command -option filename" << endl
			 << '\t' << "ex: view3d -fh vp.vp" << endl
			 << "option" << endl
			 << '\t' << "f : load file." << endl
			 << '\t' << "h : help." << endl
			 << "support" << endl
			 << '\t' << "DXF(CAD&CG), VP(JEC)"
			 << endl;
	}
	flug = true;
}

bool Application::Command()
{
	// 引数が無ければヘルプ表示
	if(m_arg.OptionSize() <= 0){
		PrintHelp();
	}
	// オプションに h が含まれればヘルプ表示
	if(m_arg.FindOption('h')){
		PrintHelp();
	}
	// オプションに ? が含まれればヘルプ表示
	if(m_arg.FindOption('?')){
		PrintHelp();
	}

	// オプションに'f'が含まれ、
	if(m_arg.FindOption('f') == true){
		// そのパラメーターが正しければ
		if(m_arg.IsParameter('f') == true){
			// ファイル読み込み
			LoadFile(m_arg.Parameter('f', 0).c_str());
		}
		// パラメーターが正しくないなら
		else {
			throw bad_operation("f オプションのパラメーターが正しくありません。");
		}
	}
	return true;
}


void Application::Run()
{
	srand(clock());
	try {
		//Command();
		BoidGroup<GLBoid> group;
		for(int i=0; i < 500; i++){
			group.Add(new GLBoid(100, 100));
		}
		BoidGroup<LTailBoid> long_tail_group;
		for(i=0; i < 50; i++){
			long_tail_group.Add(new LTailBoid(100, 100, 50));
		}
		m_glut->m_draw_list.push_back(&group);
		m_glut->m_draw_list.push_back(&long_tail_group);
		m_glut->loop();
	}
	catch (cant_open_file ex) {
		cerr << ex.what() << endl;
	}
	catch (bad_operation ex) {
		cerr << ex.what() << endl;
	}
}

