SpringLobbyApp::SpringLobbyApp()
    : quit_called(false)
    , m_translationhelper(NULL)
    , m_log_verbosity(6)
    , m_log_console(true)
    , m_log_window_show(false)
    , m_crash_handle_disable(false)
    , m_appname(GetSpringlobbyName())
{
#if wxUSE_UNIX
	/*
workarrounds this crash:
The program 'springlobby' received an X Window System error.
This probably reflects a bug in the program.
The error was 'RenderBadPicture (invalid Picture parameter)'.
  (Details: serial 71245 error_code 143 request_code 139 minor_code 8)
  (Note to programmers: normally, X errors are reported asynchronously;
   that is, you will receive the error a while after causing it.
   To debug your program, run it with the --sync command line
   option to change this behavior. You can then get a meaningful
   backtrace from your debugger if you break on the gdk_x_error() function.)
*/
	XInitThreads();
#endif
}
OptionsDialog::OptionsDialog(wxWindow* parent)
    : wxDialog(parent, -1, wxString::Format(_("%s Preferences"), GetSpringlobbyName()),
	    wxDefaultPosition, wxSize(1055, 620),
	    wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX)
    , WindowAttributesPickle(_T("preferences"), this, wxSize(1055, 620))
{
	SetMinSize(wxSize(1055, 620));
	m_options = new MainOptionsTab(this);
	m_main_sizer = new wxBoxSizer(wxVERTICAL);
	m_main_sizer->Add(m_options, 1, wxEXPAND | wxALL, 0);
	SetSizer(m_main_sizer);
	Layout();
}
LobbyOptionsTab::LobbyOptionsTab(wxWindow* parent)
    : wxScrolledWindow(parent, -1)
    , m_show_tooltips_label(0)
{
	GetAui().manager->AddPane(this, wxLEFT, _T("lobbyoptionstab"));

	wxBoxSizer* m_main_sizer = new wxBoxSizer(wxVERTICAL);

	/* ================================
   * Web browser
   */

	wxStaticBox* m_web_box = new wxStaticBox(this, -1, _("Web Browser"));
	m_web_loc_text = new wxStaticText(this, -1, _("Web Browser"));

	m_web_def_radio = new wxRadioButton(this, SPRING_DEFWEB, _("Default Browser."),
					    wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
	m_web_def_radio->SetToolTip(_("Use your system-wide browser preference"));

	m_web_spec_radio = new wxRadioButton(this, SPRING_DEFWEB, _("Specify:"));
	m_web_spec_radio->SetToolTip(_("Specify the web browser you want to use"));

	m_web_edit = new wxTextCtrl(this, -1, sett().GetWebBrowserPath());

	m_web_browse_btn = new wxButton(this, SPRING_WEBBROWSE, _("Browse"));
	m_web_browse_btn->SetToolTip(_("Use a file dialog to find the web browser"));

	if (sett().GetWebBrowserUseDefault())
		m_web_def_radio->SetValue(true);
	else
		m_web_spec_radio->SetValue(true);

	m_web_loc_sizer = new wxBoxSizer(wxHORIZONTAL);
	m_web_loc_sizer->Add(m_web_loc_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
	m_web_loc_sizer->Add(m_web_edit, 1, wxEXPAND);
	m_web_loc_sizer->Add(m_web_browse_btn);

	m_web_box_sizer = new wxStaticBoxSizer(m_web_box, wxVERTICAL);

	m_web_box_sizer->Add(m_web_def_radio, 0, wxALL, 2);
	m_web_box_sizer->Add(m_web_spec_radio, 0, wxALL, 2);
	m_web_box_sizer->Add(m_web_loc_sizer, 0, wxEXPAND | wxALL, 2);
	/////
	wxStaticBox* m_editor_box = new wxStaticBox(this, -1, _("External text editor"));
	m_editor_loc_text = new wxStaticText(this, -1, _("Path"));

	m_editor_edit = new wxTextCtrl(this, -1, TowxString(SlPaths::GetEditorPath()));

	m_editor_browse_btn = new wxButton(this, ID_BUT_EDITOR, _("Browse"));
	m_editor_browse_btn->SetToolTip(_("Use a file dialog to find the editor binary"));

	m_editor_loc_sizer = new wxBoxSizer(wxHORIZONTAL);
	m_editor_loc_sizer->Add(m_editor_loc_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
	m_editor_loc_sizer->Add(m_editor_edit, 1, wxEXPAND);
	m_editor_loc_sizer->Add(m_editor_browse_btn);

	m_editor_box_sizer = new wxStaticBoxSizer(m_editor_box, wxVERTICAL);

	m_editor_box_sizer->Add(m_editor_loc_sizer, 0, wxEXPAND | wxALL, 2);
	////////
	wxStaticBoxSizer* m_autojoin_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Autoconnect"));
	m_autoconnect_label = new wxStaticText(this, -1, wxString::Format(_("If checked, %s will automatically log on to the last used server"), GetSpringlobbyName()));
	m_autojoin = new wxCheckBox(this, -1, _("Autoconnect on lobby start"), wxDefaultPosition, wxDefaultSize, 0);
	m_autojoin->SetValue(cfg().ReadBool(_T( "/Server/Autoconnect")));
	m_autojoin_sizer->Add(m_autoconnect_label, 1, wxEXPAND | wxALL, 5);
	m_autojoin_sizer->Add(m_autojoin, 0, wxEXPAND | wxALL, 5);

	m_main_sizer->Add(m_web_box_sizer, 0, wxEXPAND | wxALL, 5);
	m_main_sizer->Add(m_editor_box_sizer, 0, wxEXPAND | wxALL, 5);
	wxStaticBoxSizer* m_updater_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Automatic updates"));
	m_updater_label = new wxStaticText(this, -1, wxString::Format(_("%s can check at startup if a newer version is available and automatically download it for you."), GetSpringlobbyName()));
	m_updater = new wxCheckBox(this, -1, _("automatically check for updates"), wxDefaultPosition, wxDefaultSize, 0);
	m_updater->SetValue(cfg().ReadBool(_T("/General/AutoUpdate")));
	m_updater_sizer->Add(m_updater_label, 1, wxEXPAND | wxALL, 5);
	m_updater_sizer->Add(m_updater, 0, wxEXPAND | wxALL, 5);

	m_main_sizer->Add(m_autojoin_sizer, 0, wxEXPAND | wxALL, 5);
	m_main_sizer->Add(m_updater_sizer, 0, wxEXPAND | wxALL, 5);

	wxStaticBoxSizer* m_show_tooltips_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Tooltips"));
	m_show_tooltips = new wxCheckBox(this, -1, _("Show Tooltips?"), wxDefaultPosition, wxDefaultSize, 0);
	m_show_tooltips->SetValue(sett().GetShowTooltips());
#ifndef __WXMSW__ // on windows this change is immediate
	m_show_tooltips_label = new wxStaticText(this, -1, wxString::Format(_("Requires %s restart to take effect."), GetSpringlobbyName()));
	m_show_tooltips_sizer->Add(m_show_tooltips_label, 1, wxEXPAND | wxALL, 5);
#endif
	m_show_tooltips_sizer->Add(m_show_tooltips, 0, wxEXPAND | wxALL, 5);

	wxStaticBoxSizer* m_show_promotions_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Battle Promotion"));
	m_show_promotions = new wxCheckBox(this, -1, _("Show notifications when someone promotes battle?"), wxDefaultPosition, wxDefaultSize, 0);
	m_show_promotions->SetValue(cfg().ReadBool("/GUI/ShowPromotions"));
	m_show_promotions_sizer->Add(m_show_promotions, 0, wxEXPAND | wxALL, 5);

	wxStaticBoxSizer* m_complete_method_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Tab completion method"));
	m_complete_method_label = new wxStaticText(this, -1, _("\"Match exact\" will complete a word if there is one and only one match.\n"
							       "\"Match nearest\" will select the (first) match that has closest Levenshtein distance"));
	m_complete_method_old = new wxRadioButton(this, -1, _("Match exact"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
	m_complete_method_new = new wxRadioButton(this, -1, _("Match nearest"), wxDefaultPosition, wxDefaultSize);
	m_complete_method_old->SetValue(sett().GetCompletionMethod() == Settings::MatchExact);
	m_complete_method_new->SetValue(sett().GetCompletionMethod() == Settings::MatchNearest);
	m_complete_method_sizer->Add(m_complete_method_label, 1, wxEXPAND | wxALL, 5);
	m_complete_method_sizer->Add(m_complete_method_old, 0, wxEXPAND | wxALL, 5);
	m_complete_method_sizer->Add(m_complete_method_new, 0, wxEXPAND | wxALL, 5);

	m_main_sizer->Add(m_show_tooltips_sizer, 0, wxEXPAND | wxALL, 5);
	m_main_sizer->Add(m_show_promotions_sizer, 0, wxEXPAND | wxALL, 5);
	m_main_sizer->Add(m_complete_method_sizer, 0, wxEXPAND | wxALL, 5);

	wxStaticBoxSizer* m_misc_gui_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Misc GUI"));
	m_use_tabicons = new wxCheckBox(this, -1, _("Show big icons in mainwindow tabs?"), wxDefaultPosition, wxDefaultSize, 0);
	m_use_tabicons->SetValue(cfg().ReadBool(_T( "/GUI/UseTabIcons" )));
	m_misc_gui_sizer->Add(m_use_tabicons, 0, wxEXPAND | wxALL, 5);
	m_use_notif_popups = new wxCheckBox(this, -1, _("Use notification popups?"), wxDefaultPosition, wxDefaultSize, 0);
	m_misc_gui_sizer->Add(m_use_notif_popups, 0, wxEXPAND | wxALL, 5);
	m_notif_popup_pos_sizer = new wxBoxSizer(wxHORIZONTAL);
	m_notif_popup_pos_label = new wxStaticText(this, -1, _("Screen position for notification popups"));
	m_notif_popup_pos = new wxChoice(this, -1, wxDefaultPosition, wxDefaultSize, ScreenPosition());
	m_notif_popup_pos_sizer->Add(m_notif_popup_pos_label, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
	m_notif_popup_pos_sizer->Add(m_notif_popup_pos, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
	m_misc_gui_sizer->Add(m_notif_popup_pos_sizer, 0, wxEXPAND | wxALL, 0);
	m_notif_popup_time_sizer = new wxBoxSizer(wxHORIZONTAL);
	m_notif_popup_time = new wxSpinCtrl(this, wxID_ANY);
	m_notif_popup_time_label = new wxStaticText(this, -1, _("Display time for popup notifications in seconds"));
	m_notif_popup_time_sizer->Add(m_notif_popup_time_label, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
	m_notif_popup_time_sizer->Add(m_notif_popup_time, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
	m_misc_gui_sizer->Add(m_notif_popup_time_sizer, 0, wxEXPAND | wxALL, 0);


	m_x_on_all_tabs = new wxCheckBox(this, -1, _("Show close button on all tabs? (needs restart to take effect)"), wxDefaultPosition, wxDefaultSize, 0);
	m_x_on_all_tabs->SetValue(sett().GetShowXallTabs());

	m_test_notification = new wxButton(this, TEST_NOTIFICATION, _("Test Notification"));
	m_misc_gui_sizer->Add(m_x_on_all_tabs, 1, wxEXPAND | wxALL, 5);
	m_misc_gui_sizer->Add(m_test_notification, 1, wxEXPAND | wxALL, 5);

	wxStaticBoxSizer* m_start_tab_sizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Start tab"));
	m_start_tab = new wxChoice(this, -1, wxDefaultPosition, wxDefaultSize, ui().mw().GetTabNames());
	m_start_tab->SetSelection(cfg().ReadLong(_T( "/GUI/StartTab" )));
	wxStaticText* m_start_tab_label = new wxStaticText(this, -1, _("Select which tab to show at startup"));
	m_start_tab_sizer->Add(m_start_tab_label, 0, wxEXPAND | wxALL, 5);
	m_start_tab_sizer->Add(m_start_tab, 0, wxEXPAND | wxALIGN_TOP, 5);

	m_main_sizer->Add(m_misc_gui_sizer, 0, wxEXPAND | wxALL, 5);
	m_main_sizer->Add(m_start_tab_sizer, 0, wxEXPAND | wxALL, 5);

	//dummy event that updates controls to correct state
	wxCommandEvent evt;
	OnRestore(evt);

	SetScrollRate(SCROLL_RATE, SCROLL_RATE);
	SetSizer(m_main_sizer);
	Layout();
}