#include "shortcutpicker.h"
#include "shortcuts.h"


using namespace VRUT;

ShortCutDialog::ShortCutDialog( wxWindow* parent, wxWindowID id, ShortCut sc, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
	this->SetSizeHints( wxDefaultSize, wxDefaultSize );
	
	wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL );
	
	wxFlexGridSizer* fgSizer = new wxFlexGridSizer( 0, 2, 0, 0 );
	fgSizer->SetFlexibleDirection( wxBOTH );
	fgSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
	
	shortcutLabel = new wxStaticText( this, wxID_ANY, wxT("shortcut"), wxDefaultPosition, wxDefaultSize, 0 );
	shortcutLabel->Wrap( -1 );
	fgSizer->Add( shortcutLabel, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
	
	shortcutText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
	fgSizer->Add( shortcutText, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
	
	infoLabel = new wxStaticText( this, wxID_ANY, wxT("info"), wxDefaultPosition, wxDefaultSize, 0 );
	infoLabel->Wrap( -1 );
	fgSizer->Add( infoLabel, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
	
	infoText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
	fgSizer->Add( infoText, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
		
	mainSizer->Add( fgSizer, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
	
	wxBoxSizer* buttonSizer = new wxBoxSizer( wxHORIZONTAL );
	
	buttonSizer->Add( 0, 0, 1, wxEXPAND, 5 );
	
	okButton = new wxButton( this, wxID_OK, wxT("Ok"), wxDefaultPosition, wxDefaultSize, 0 );
	buttonSizer->Add( okButton, 0, wxALL, 5 );
		
	buttonSizer->Add( 0, 0, 1, wxEXPAND, 5 );
	
	cancelButton = new wxButton( this, wxID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
	buttonSizer->Add( cancelButton, 0, wxALL, 5 );
		
	buttonSizer->Add( 0, 0, 1, wxEXPAND, 5 );
	
	mainSizer->Add( buttonSizer, 1, wxEXPAND, 5 );
	
	this->SetSizerAndFit( mainSizer );
	this->Layout();
	
	this->Centre( wxBOTH );

	okButton->Connect(wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ShortCutDialog::OnClick), NULL, this);
	cancelButton->Connect(wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ShortCutDialog::OnClick), NULL, this);

	shortCut = sc;
	ShowKeyInfo(shortCut);

	infoText->SetValue(wxT("press shortcut"));

	// bind on the char hook event. This event is sent before any
	// other, so we can catch it to intercept our shortcuts
	this->Bind(wxEVT_CHAR_HOOK, &ShortCutDialog::OnCharHook, this);
}

ShortCutDialog::~ShortCutDialog()
{
	this->Unbind(wxEVT_CHAR_HOOK, &ShortCutDialog::OnCharHook, this);
}

void ShortCutDialog::ShowKeyInfo(ShortCut sc)
{
	wxString keyStr = ShortCutManager::GetKeyName(sc);

	shortcutText->SetValue(keyStr);

	wxString keyStatus;

	if (KERNEL->GetMainWindow()->GetShortCutManager()->IsShortCutRegistered(shortCut))
		keyStatus = wxT("already registered");		
	else
		keyStatus = wxT("still not registered");

	infoText->SetValue(keyStatus);
}

void ShortCutDialog::OnCharHook(wxKeyEvent& event)
{
	int keyCode = event.GetKeyCode();

	if ((keyCode == WXK_SHIFT) || (keyCode == WXK_CONTROL) || (keyCode == WXK_ALT) || (keyCode == WXK_CAPITAL) || (keyCode == WXK_NONE))
		return;

	shortCut.keyCode = keyCode;
	shortCut.modifiers = event.GetModifiers();

	ShowKeyInfo(shortCut);
}

void ShortCutDialog::OnClick(wxCommandEvent &evt)
{
	if (evt.GetEventObject() == okButton)
		this->EndModal(wxID_OK);
	else
		this->EndModal(wxID_CANCEL);
}

IMPLEMENT_DYNAMIC_CLASS(ShortCutPicker, wxButton)

void ShortCutPicker::OnClick(wxMouseEvent &evt)
{
	dialog = new ShortCutDialog(this, wxID_ANY, shortCut);


	wxString strValueTmp = strValue;

	if (dialog->ShowModal() == wxID_OK)
	{
		ShortCut sc = dialog->GetShortCut();

		if (sc.keyCode != WXK_NONE)
			strValueTmp = wxString::Format("%i,%i", sc.modifiers, sc.keyCode);
	}

	if (strValueTmp != strValue)
	{
		SetValue(strValueTmp);
		SendEvent();
	}

	SAFE_DELETE(dialog);
}

void ShortCutPicker::SendEvent()
{
	wxCommandEvent textEvent(wxEVT_COMMAND_TEXT_ENTER, this->GetId());

	textEvent.SetEventObject(this);
	textEvent.SetClientData(&strValue);
	textEvent.SetString(strValue);

	this->ProcessEvent(textEvent);
}

void ShortCutPicker::SetValue(const wxString &value)
{
	if (value.IsEmpty() || value == strValue)
		return;

	TextParser textParser(value.utf8_str());

	int modifiers;
	int keyCode;

	if (!textParser.ParseInt(&modifiers, ","))
		return;

	if (!textParser.ParseInt(&keyCode, ","))
		return;

	strValue = value;

	shortCut.modifiers = modifiers;
	shortCut.keyCode = keyCode;

	ShowKeyInfo();
}

void ShortCutPicker::ShowKeyInfo(void)
{
	wxString keyStr = ShortCutManager::GetKeyName(shortCut);

	this->SetLabel(keyStr);
}

// Register with wxWidgets' dynamic class subsystem.
IMPLEMENT_DYNAMIC_CLASS(ShortCutPickerXmlHandler, wxXmlResourceHandler)
