/*
 *	realKeyFrameDialog.h - Real value keyframe selection dialog
 *	Copyright (C) 2018, D Haley 

 *	This program is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, either version 3 of the License, or
 *	(at your option) any later version.

 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.

 *	You should have received a copy of the GNU General Public License
 *	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
// -*- C++ -*- generated by wxGlade 0.6.5 on Tue Aug 28 22:07:07 2012
#ifndef REALKEYFRAMEDIALOG_H
#define REALKEYFRAMEDIALOG_H

// begin wxGlade: ::dependencies
// end wxGlade

#include "wx/wxcommon.h"

enum
{
	TRANSITION_STEP,
	TRANSITION_INTERP,
	TRANSITION_END
};


// begin wxGlade: ::extracode
enum
{
	ID_COMBO_TRANSITION,
	ID_TEXT_FRAME_START,
	ID_TEXT_FRAME_END,
	ID_TEXT_FINAL_VALUE,
	ID_TEXT_INITIAL_VALUE,
};
// end wxGlade

template<class T>
class RealKeyFrameDialog: public wxDialog
{
public:
	// begin wxGlade: RealKeyFrameDialog::ids
	// end wxGlade

	RealKeyFrameDialog(wxWindow* parent, int id, const wxString& title, const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize, long style=wxDEFAULT_DIALOG_STYLE);

	//!Return the keyframe transition style selected by user
	size_t getTransitionMode() const { return transitionMode;}

	//!Return the initial frame from user
	size_t getEndFrame() const { return endFrame;}
	//!Return the start frame, as was given by user
	size_t getStartFrame() const { return startFrame;}

	//!Return the initial value, as given by user 
	T getEndValue() const { return endValue;}
	//!Return the start value, as was given by user 
	T getStartValue() const { return startValue;}
private:
	size_t transitionMode;
	size_t startFrame, endFrame;
	T startValue, endValue;

	bool startFrameOK,endFrameOK;
	bool startValueOK,endValueOK;

	void updateOKButton();

	// begin wxGlade: RealKeyFrameDialog::methods
	void set_properties();
	void do_layout();
	// end wxGlade

protected:
	// begin wxGlade: RealKeyFrameDialog::attributes
	wxStaticBox* sizerMainArea_staticbox;
	wxStaticText* labelTransition;
	wxComboBox* comboTransition;
	wxStaticText* labelFrameStart;
	wxTextCtrl* textFrameStart;
	wxStaticText* labelFrameEnd;
	wxTextCtrl* textFrameEnd;
	wxStaticLine* verticalLine;
	wxStaticText* labelStartVal;
	wxTextCtrl* textStartVal;
	wxStaticText* labelEndVal;
	wxTextCtrl* textEndVal;
	wxButton* buttonCancel;
	wxButton* buttonOK;
	// end wxGlade

	DECLARE_EVENT_TABLE();

public:
	virtual void OnComboTransition(wxCommandEvent &event); // wxGlade: <event_handler>
	virtual void OnTextStartFrame(wxCommandEvent &event); // wxGlade: <event_handler>
	virtual void OnTextEndFrame(wxCommandEvent &event); // wxGlade: <event_handler>
	virtual void OnTextStartValue(wxCommandEvent &event); // wxGlade: <event_handler>
	virtual void OnTextEndValue(wxCommandEvent &event); // wxGlade: <event_handler>
}; // wxGlade: end class

using std::string;

bool validatePoint3D(wxTextCtrl *t, Point3D &i)
{
	bool isOK;
	std::string s; 
	s= stlStr(t->GetValue());

	//string cannot be empty
	bool condition;
	condition = s.empty() || !i.parse(s);

	if(condition)
	{
		//OK, so bad things happened. Prevent the user from doing this
		isOK=false;

		//if it is bad and non-empty, highlight it as such
		// if it is empty, then just set it to normal colour
		if(s.empty())
			t->SetBackgroundColour(wxNullColour);
		else
			t->SetBackgroundColour(*wxCYAN);
	}
	else
	{
		t->SetBackgroundColour(wxNullColour);
		isOK=true;
	}


	return isOK;
}

template<class T>
RealKeyFrameDialog<T>::RealKeyFrameDialog(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
	wxDialog(parent, id, title, pos, size, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxMAXIMIZE_BOX|wxMINIMIZE_BOX)
{
	// begin wxGlade: RealKeyFrameDialog<T>::RealKeyFrameDialog
	sizerMainArea_staticbox = new wxStaticBox(this, -1, wxT("Keyframe Data"));
	labelTransition = new wxStaticText(this, wxID_ANY, wxT("Transition"));
	//FIXME: This is declared in animator.h, use it!
	const wxString comboTransition_choices[] = {
        wxT("Step"),
        wxT("Ramp")
    };
	comboTransition = new wxComboBox(this, ID_COMBO_TRANSITION, wxT(""), wxDefaultPosition, wxDefaultSize, 2, comboTransition_choices, wxCB_DROPDOWN|wxCB_READONLY);
	labelFrameStart = new wxStaticText(this, wxID_ANY, wxT("Start Frame"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
	textFrameStart = new wxTextCtrl(this, ID_TEXT_FRAME_START, wxEmptyString);
	labelFrameEnd = new wxStaticText(this, wxID_ANY, wxT("End Frame"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
	textFrameEnd = new wxTextCtrl(this, ID_TEXT_FRAME_END, wxEmptyString);
	verticalLine = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL);
	labelStartVal = new wxStaticText(this, wxID_ANY, wxT("Start Value"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
	textStartVal = new wxTextCtrl(this, ID_TEXT_INITIAL_VALUE, wxEmptyString);
	labelEndVal = new wxStaticText(this, wxID_ANY, wxT("End Value"), wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
	textEndVal = new wxTextCtrl(this, ID_TEXT_FINAL_VALUE, wxEmptyString);
	buttonCancel = new wxButton(this, wxID_CANCEL, wxEmptyString);
	buttonOK = new wxButton(this, wxID_OK, wxEmptyString);

	startFrameOK=endFrameOK=startValueOK=endValueOK=false;
	buttonOK->Enable(false);

	const int DEFAULT_TRANSITION=TRANSITION_INTERP;
	comboTransition->SetSelection(DEFAULT_TRANSITION);
	transitionMode=DEFAULT_TRANSITION;
	
	set_properties();
	do_layout();
	// end wxGlade
}



BEGIN_EVENT_TABLE_TEMPLATE1(RealKeyFrameDialog, wxDialog,T)
	// begin wxGlade: RealKeyFrameDialog<T>::event_table
	EVT_COMBOBOX(ID_COMBO_TRANSITION, RealKeyFrameDialog::OnComboTransition)
	EVT_TEXT(ID_TEXT_FRAME_START, RealKeyFrameDialog::OnTextStartFrame)
	EVT_TEXT(ID_TEXT_FRAME_END, RealKeyFrameDialog::OnTextEndFrame)
	EVT_TEXT(ID_TEXT_INITIAL_VALUE, RealKeyFrameDialog::OnTextStartValue)
	EVT_TEXT(ID_TEXT_FINAL_VALUE, RealKeyFrameDialog::OnTextEndValue)
	// end wxGlade
END_EVENT_TABLE();

template<class T>
void RealKeyFrameDialog<T>::updateOKButton()
{
	bool isOK=true;
	isOK&=startFrameOK;
	//step transitions need to be handled without end frame
	isOK&=endFrameOK || transitionMode==TRANSITION_STEP;

	//Ensure start frame is > end frame
	if(isOK && transitionMode != TRANSITION_STEP)
	{
		isOK&=(startFrame<endFrame);
		if(!isOK)
		{
			textFrameStart->SetBackgroundColour(*wxCYAN);
			textFrameEnd->SetBackgroundColour(*wxCYAN);
		}
		else
		{
			textFrameStart->SetBackgroundColour(wxNullColour);
			textFrameEnd->SetBackgroundColour(wxNullColour);
		}
	}
	
	isOK&=startValueOK;
	isOK&=endValueOK || transitionMode==TRANSITION_STEP;
	
	buttonOK->Enable(isOK);
}

template<class T>
void RealKeyFrameDialog<T>::OnComboTransition(wxCommandEvent &event)
{
	ASSERT(event.GetInt() < TRANSITION_END);

	transitionMode=event.GetInt();

	textEndVal->Enable(transitionMode != TRANSITION_STEP);
	textFrameEnd->Enable(transitionMode!=TRANSITION_STEP);
}


template<class T>
void RealKeyFrameDialog<T>::OnTextStartFrame(wxCommandEvent &event)
{
	startFrameOK=validateTextAsStream(textFrameStart,startFrame);
	updateOKButton();
}

template<class T>
void RealKeyFrameDialog<T>::OnTextEndFrame(wxCommandEvent &event)
{
	endFrameOK=validateTextAsStream(textFrameEnd,endFrame);
	updateOKButton();
}

template<class T>
void RealKeyFrameDialog<T>::OnTextStartValue(wxCommandEvent &event)
{
	startValueOK=validateTextAsStream(textStartVal,startValue);
	updateOKButton();
}

template<>
void RealKeyFrameDialog<Point3D>::OnTextStartValue(wxCommandEvent &evt)
{
	startValueOK=validatePoint3D(textStartVal,startValue);
	updateOKButton();
}


template<class T>
void RealKeyFrameDialog<T>::OnTextEndValue(wxCommandEvent &event)
{
	endValueOK=validateTextAsStream(textEndVal,endValue);
	updateOKButton();
}

template<>
void RealKeyFrameDialog<Point3D>::OnTextEndValue(wxCommandEvent &evt)
{
	endValueOK=validatePoint3D(textEndVal,endValue);
	updateOKButton();
}

// wxGlade: add RealKeyFrameDialog event handlers


template<class T>
void RealKeyFrameDialog<T>::set_properties()
{
	// begin wxGlade: RealKeyFrameDialog<T>::set_properties
	comboTransition->SetSelection(-1);
	// end wxGlade
}


template<class T>
void RealKeyFrameDialog<T>::do_layout()
{
	// begin wxGlade: RealKeyFrameDialog<T>::do_layout
	wxBoxSizer* sizerTop = new wxBoxSizer(wxVERTICAL);
	wxBoxSizer* sizerBUttons = new wxBoxSizer(wxHORIZONTAL);
	wxStaticBoxSizer* sizerMainArea = new wxStaticBoxSizer(sizerMainArea_staticbox, wxHORIZONTAL);
	wxBoxSizer* sizerRight = new wxBoxSizer(wxVERTICAL);
	wxBoxSizer* sizerRightEnd = new wxBoxSizer(wxHORIZONTAL);
	wxBoxSizer* sizerRightStart = new wxBoxSizer(wxHORIZONTAL);
	wxBoxSizer* sizerLeft = new wxBoxSizer(wxVERTICAL);
	wxBoxSizer* sizerEndFrame = new wxBoxSizer(wxHORIZONTAL);
	wxBoxSizer* sizerStartFrame = new wxBoxSizer(wxHORIZONTAL);
	wxBoxSizer* sizerTransition = new wxBoxSizer(wxHORIZONTAL);
	sizerTop->Add(20, 5, 0, 0, 0);
	sizerMainArea->Add(10, 20, 0, 0, 0);
	sizerLeft->Add(20, 10, 0, 0, 0);
	sizerTransition->Add(labelTransition, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 14);
	sizerTransition->Add(comboTransition, 1, wxLEFT|wxALIGN_CENTER_VERTICAL, 5);
	sizerLeft->Add(sizerTransition, 1, wxEXPAND, 0);
	sizerStartFrame->Add(labelFrameStart, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5);
	sizerStartFrame->Add(textFrameStart, 1, wxLEFT|wxALIGN_CENTER_VERTICAL, 4);
	sizerLeft->Add(sizerStartFrame, 1, wxEXPAND, 0);
	sizerEndFrame->Add(labelFrameEnd, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 12);
	sizerEndFrame->Add(textFrameEnd, 1, wxLEFT|wxALIGN_CENTER_VERTICAL, 4);
	sizerLeft->Add(sizerEndFrame, 1, wxEXPAND, 0);
	sizerLeft->Add(20, 10, 0, 0, 0);
	sizerMainArea->Add(sizerLeft, 1, wxEXPAND, 0);
	sizerMainArea->Add(verticalLine, 0, wxLEFT|wxRIGHT|wxEXPAND, 5);
	sizerRight->Add(20, 20, 1, 0, 0);
	sizerRightStart->Add(labelStartVal, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5);
	sizerRightStart->Add(textStartVal, 1, wxLEFT|wxALIGN_CENTER_VERTICAL, 4);
	sizerRight->Add(sizerRightStart, 1, wxEXPAND, 0);
	sizerRightEnd->Add(labelEndVal, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 9);
	sizerRightEnd->Add(textEndVal, 1, wxLEFT|wxALIGN_CENTER_VERTICAL, 4);
	sizerRight->Add(sizerRightEnd, 1, wxEXPAND, 0);
	sizerRight->Add(20, 20, 1, 0, 0);
	sizerMainArea->Add(sizerRight, 1, wxEXPAND, 0);
	sizerMainArea->Add(10, 20, 0, 0, 0);
	sizerTop->Add(sizerMainArea, 1, wxEXPAND, 0);
	sizerBUttons->Add(20, 20, 1, 0, 0);
	sizerBUttons->Add(buttonCancel, 0, wxALL, 4);
	sizerBUttons->Add(buttonOK, 0, wxALL, 4);
	sizerTop->Add(sizerBUttons, 0, wxEXPAND, 0);
	SetSizer(sizerTop);
	sizerTop->Fit(this);
	Layout();
	// end wxGlade
}



#endif // REALKEYFRAMEDIALOG_H
