// GUI.cpp: implementation of the GUI class.
//
//////////////////////////////////////////////////////////////////////

#include "GUI.h"

GUI::GUI(App * app) {

	_app = app;
	initGUI();
}

GUI::~GUI() {
	delete _controlWindow;
}

void GUI::initGUI() {

	_controlWindow = new Fl_Window(CONTROL_WINDOW_W, CONTROL_WINDOW_H, CONTROL_WINDOW_T);

	_transformationSelectGroup = new Fl_Group(10, 10, 300, 300);

	// create the widgets

	_selectNoneButton =               new Fl_Round_Button(10,  10,  80, 20, "None");
	_selectScaleButton =              new Fl_Round_Button(10,  40,  80, 20, "Scale");
	_selectRotateButton =             new Fl_Round_Button(10,  70,  80 ,20, "Rotate");
	_selectPerspectiveButton =        new Fl_Round_Button(10,  100, 80, 20, "Perspective");

	_scaleXInput =                    new Fl_Float_Input (200, 40,  80, 20, "X:");
	_scaleYInput =                    new Fl_Float_Input (350, 40,  80, 20, "Y:");
	_rotateAlphaInput =               new Fl_Float_Input (200, 70,  80, 20, "Alpha:");
	_rotateXInput =                   new Fl_Float_Input (200, 100, 80, 20, "Xalpha:");
	_rotateYInput =                   new Fl_Float_Input (350, 100, 80, 20, "Yalpha:");
	_distanceInput =                  new Fl_Float_Input (500, 100, 80, 20, "Distance:");

	_applyButton =                    new Fl_Button      (10,  130, 100, 20, "&Apply");
	_saveButton =                     new Fl_Button      (110, 130, 100, 20, "&Save");
	_quitButton =                     new Fl_Button      (210, 130, 100, 20, "&Bye");

	// matrixs view
	for (int i = 0, x = 10; i < NUMBER_OF_TRANS_MATRIXS; i++, x+= 150) {
		_matrixsView[i] = new Fl_Multiline_Output(x, 170, 120, 55);
		_controlWindow->add(_matrixsView[i]);
	}

	_mulTitle = new Fl_Box(140, 190, 20, 20, "*");
	_eqTitle = new Fl_Box(290, 190, 20, 20, "=");


	// arrange groups

	_selectNoneButton->type(FL_RADIO_BUTTON);
	_selectScaleButton->type(FL_RADIO_BUTTON);
	_selectRotateButton->type(FL_RADIO_BUTTON);
	_selectPerspectiveButton->type(FL_RADIO_BUTTON);

	_transformationSelectGroup->add(_selectNoneButton);
	_transformationSelectGroup->add(_selectScaleButton);
	_transformationSelectGroup->add(_selectRotateButton);
	_transformationSelectGroup->add(_selectPerspectiveButton);

	_controlWindow->add(_scaleXInput);
	_controlWindow->add(_scaleYInput);
	_controlWindow->add(_rotateAlphaInput);
	_controlWindow->add(_rotateXInput);
	_controlWindow->add(_rotateYInput);
	_controlWindow->add(_distanceInput);

	_controlWindow->add(_mulTitle);
	_controlWindow->add(_eqTitle);

	// callback

	_controlWindow->callback(redraw, this);
	_controlWindow->when(FL_WHEN_RELEASE_ALWAYS);

	_applyButton->callback(applyTransformation, this);
	_saveButton->callback(saveTargetImage, this);
	_quitButton->callback(quit, this);

	// defalut 
	_selectNoneButton->set();

	_controlWindow->show();

}

void GUI::applyTransformation(Fl_Widget * w, void * g) {
	GUI * gui = (GUI *)g;
	App * app = gui->_app;

	if (gui->_selectNoneButton->value() == 1) {
		app->setID();
	}

	if (gui->_selectScaleButton->value() == 1) {
		app->setScale(atof(gui->_scaleXInput->value()), atof(gui->_scaleYInput->value()));
	}

	if (gui->_selectRotateButton->value() == 1) {
		app->setRotate(atof(gui->_rotateAlphaInput->value()));
	}

	if (gui->_selectPerspectiveButton->value() == 1) {
		double d = atof(gui->_distanceInput->value());

		if (d < MIN_D) {
			char buffer[MAX_BUFFER];

			fl_alert("Distance must be at least %d.", MIN_D);
			sprintf(buffer, "%d", MIN_D);
			gui->_distanceInput->value(buffer);
			d = MIN_D;
		}

		app->setPerspective(
			atof(gui->_rotateXInput->value()), 
			atof(gui->_rotateYInput->value()),
			d);
	}

}

void GUI::saveTargetImage(Fl_Widget * w, void * g) {
	GUI * gui = (GUI *)g;
	App * app = gui->_app;

	char * fileName = fl_file_chooser("Save target as...", "*.bmp", NULL);

	if (fileName == NULL) {
		return;
	}

	// check if the file exists !!!
	FILE * temp = fopen(fileName, "r");

	if (temp != NULL) { // exists
		if (fl_ask ("File exists, Overwrite?")) {
			fclose(temp);
		}
		else {
			return;
		}
	}

	app->saveTarget(fileName);

}

void GUI::quit(Fl_Widget * w, void * g) {
	if (fl_ask ("Are you sure?")) {
		exit(0);
	}
}


void GUI::updateMatrixs(Matrix3D  matrixs[]) {
	
	char buffer[MAX_BUFFER];

	for (int i = 0; i < NUMBER_OF_TRANS_MATRIXS; i++) {
		matrixs[i].toString(buffer);
		_matrixsView[i]->value(buffer);
	}
	

}

void GUI::redraw(Fl_Widget * w, void * g) {
	GUI * gui = (GUI *)g;

	gui->_controlWindow->damage(1);
	gui->_controlWindow->redraw();
}
