/////////////////////////////////////////////////////////////////////////////
// Name:        SettingsDlg.cpp
// Purpose:     Settings dialog
// Author:      Alex Thuering
// Created:     27.03.2004
// RCS-ID:      $Id: SettingsDlg.cpp,v 1.64 2012/08/29 18:49:06 ntalex Exp $
// Copyright:   (c) Alex Thuering
// Licence:     GPL
/////////////////////////////////////////////////////////////////////////////

#include "SettingsDlg.h"
#include "Config.h"
#include "Languages.h"
#include "DVD.h"
#include <wxVillaLib/utils.h>
#include <wx/notebook.h>
#include <wx/filename.h>

#define BUTTONS_DIR wxFindDataDirectory(_T("buttons"))

enum {
	FILE_BROWSER_CHOICE_ID = 7900,
	RESET_DONT_SHOW_FLAGS_BT_ID
};

BEGIN_EVENT_TABLE(SettingsDlg, wxPropDlg)
	EVT_CHOICE(FILE_BROWSER_CHOICE_ID, SettingsDlg::OnChangeFileBrowserDir)
	EVT_BUTTON(RESET_DONT_SHOW_FLAGS_BT_ID, SettingsDlg::OnResetDontShowFlags)
END_EVENT_TABLE()

SettingsDlg::SettingsDlg(wxWindow* parent): wxPropDlg(parent), m_directoryEdit(NULL), m_directorySelectButton(NULL) {
	Create(true);
	SetTitle(_("Settings"));
	SetSize(600, -1);
	Center();
}

void SettingsDlg::CreatePropPanel(wxSizer* sizer) {
	bool def = sizer == NULL;
	wxNotebook* notebook = NULL;
	if (sizer) {
		notebook = new wxNotebook(this, -1);
		sizer->Add(notebook, 0, wxEXPAND);
	}

	// ----------- Interface Tab Sizers ------------- //
	wxBoxSizer* interfaceSizer = NULL;
	wxFlexGridSizer* interfaceGrid = NULL;
	if (sizer) {
		wxPanel* interfacePanel = new wxPanel(notebook, -1);
		notebook->AddPage(interfacePanel, _("Interface"));
		propWindow = interfacePanel;

		interfaceSizer = new wxBoxSizer(wxVERTICAL);
		interfacePanel->SetAutoLayout(true);
		interfacePanel->SetSizer(interfaceSizer);

		interfaceGrid = new wxFlexGridSizer(2, 4, 16);
		interfaceGrid->AddGrowableCol(1);
		interfaceSizer->Add(interfaceGrid, 1, wxEXPAND | wxALL, 10);
	}

	// -------------- Interface Tab ----------------- //
	wxString lang = GetLangName(s_config.GetLanguageCode());
	AddBitmapComboProp(interfaceGrid, _("Language:"), lang, GetLangNames(), GetLangBitmaps(), wxCB_READONLY);
	AddTextProp(interfaceGrid, _("Default disc label:"), s_config.GetDefDiscLabel(def));
	wxArrayString labels = DVD::GetCapacityLabels();
	AddChoiceProp(interfaceGrid, _("Default disc capacity:"), labels[s_config.GetDefDiscCapacity()], labels, 0);
	wxControl* discCapacityChoice = GetLastControl();
	
	// video format
	AddText(interfaceGrid, _("Default video format:"));
	wxSizer* vfSizer = NULL;
	if (interfaceGrid) {
		vfSizer = new wxBoxSizer(wxHORIZONTAL);
		interfaceGrid->Add(vfSizer);
	}
	int vf = s_config.GetDefVideoFormat() >= 2 ? s_config.GetDefVideoFormat() - 2 : 0;
	labels = DVD::GetVideoFormatLabels();
	AddChoiceProp(vfSizer, wxT(""), labels[vf], labels);
	// fix size
	wxControl* videoChoice = GetLastControl();
	discCapacityChoice->SetMinSize(videoChoice->GetBestSize());
	// aspect ratio
	labels = DVD::GetAspectRatioLabels();
	AddChoiceProp(vfSizer, wxT(""), labels[s_config.GetDefAspectRatio() - 1], labels, 0);
	wxControl* aspectRatioChoice = GetLastControl();
	
	// audio format
	AddText(interfaceGrid, _("Default audio format:"));
	wxSizer* afSizer = NULL;
	if (interfaceGrid) {
		afSizer = new wxBoxSizer(wxHORIZONTAL);
		interfaceGrid->Add(afSizer);
	}
	int af = s_config.GetDefAudioFormat() >= 2 ? s_config.GetDefAudioFormat() - 2 : 0;
	labels = DVD::GetAudioFormatLabels();
	AddChoiceProp(afSizer, wxT(""), labels[af], labels);
	// fix size
	GetLastControl()->SetMinSize(videoChoice->GetBestSize());
	// default audio language
	labels = DVD::GetAudioLanguageCodes();
	AddChoiceProp(afSizer, wxT(""), s_config.GetDefAudioLanguage(), labels, 0);
	GetLastControl()->SetMinSize(aspectRatioChoice->GetBestSize());
	
	// default chapter length
	AddSpinProp(interfaceGrid, _("Default chapter length:"), s_config.GetDefChapterLength(def), 1, 999, 60, _("min"));
	
	// default title post command
	labels = DVD::GetDefPostCommandLabels();
	AddChoiceProp(interfaceGrid, _("Default title post command:"), labels[s_config.GetDefPostCommand(def)], labels, 0);
	
	// default button
	int sel = 0;
	wxArrayString tmpArray;
	labels.Clear();
	m_buttons.Clear();
	wxString fname = wxFindFirstFile(BUTTONS_DIR + _T("*.xml"));
	while (!fname.IsEmpty()) {
		MenuObject obj(NULL, false, fname);
		tmpArray.Add(wxGetTranslation((const wxChar*)obj.GetTitle().GetData()) + wxString(wxT("|"))
				+ wxFileName(fname).GetFullName());
		fname = wxFindNextFile();
	}
	tmpArray.Sort();
	for (int i = 0; i<(int)tmpArray.GetCount(); i++) {
		labels.Add(tmpArray[i].BeforeLast('|'));
		wxString button = tmpArray[i].AfterLast('|');
		m_buttons.Add(button);
		if (button == s_config.GetDefButton(def))
			sel = m_buttons.GetCount() - 1;
	}
	wxSizer* dbtSizer = AddChoiceProp(interfaceGrid, _("Default button:"), labels[sel], labels, 0, false);
	wxControl* defButtonChoice = GetLastControl();
	if (dbtSizer)
		dbtSizer->AddSpacer(4);
	AddCheckProp(dbtSizer, _("Accept invalid actions"), s_config.GetAcceptInvalidActions(def));

	// File Browser start directory
	wxString fbDir = s_config.GetFileBrowserDir();
	const wxString fbChoices[] = { _("Last directory"),_("Custom") };
	wxSizer* fbSizer = AddChoiceProp(interfaceGrid, _("File Browser start directory:"),
		fbChoices[fbDir.IsEmpty() ? 0 : 1], wxArrayString(2, fbChoices), 0, false, FILE_BROWSER_CHOICE_ID);
	if (GetLastControl()->GetBestSize().GetWidth() < defButtonChoice->GetBestSize().GetWidth())
		GetLastControl()->SetMinSize(defButtonChoice->GetBestSize());
	else
		defButtonChoice->SetMinSize(GetLastControl()->GetBestSize());
	if (fbSizer)
		fbSizer->AddSpacer(4);
	AddDirectoryProp(fbSizer, wxT(""), fbDir);
	if (fbSizer) {
		m_directoryEdit = (wxTextCtrl*) GetLastControl();
		m_directorySelectButton = (wxButton*) this->FindWindowByName(
				wxString::Format(wxT("SelectDirButton_%d"), GetLastControlIndex()));
	}
	m_directoryEdit->Enable(!fbDir.IsEmpty());
	m_directorySelectButton->Enable(!fbDir.IsEmpty());
#ifndef GNOME2
	AddText(interfaceGrid, wxEmptyString);
	AddCheckProp(interfaceGrid, _("Clear thumbnail cache after exit"), s_config.GetClearThumbnailCache(def));
#endif
	
	// undo history size
	AddSpinProp(interfaceGrid, _("Undo history size:"), s_config.GetUndoHistorySize(def), 0, 9999, 60);
	
	// don't show fags
	AddText(interfaceGrid, _("\"Don't show again\" flags:"));
	if (interfaceGrid)
		interfaceGrid->Add(new wxButton(propWindow, RESET_DONT_SHOW_FLAGS_BT_ID, _("Reset All")));
	

	// -------------- Core Tab Sizers ----------------- //
	wxBoxSizer* coreSizer = NULL;
	wxFlexGridSizer* coreGrid = NULL;
	wxBoxSizer* debugSizer = NULL;
	if (sizer) {
		wxPanel* interfacePanel = new wxPanel(notebook, -1);
		notebook->AddPage(interfacePanel, _("Core"));
		propWindow = interfacePanel;

		coreSizer = new wxBoxSizer(wxVERTICAL);
		interfacePanel->SetAutoLayout(true);
		interfacePanel->SetSizer(coreSizer);

		coreGrid = new wxFlexGridSizer(2, 4, 16);
		coreGrid->AddGrowableCol(1);
		coreSizer->Add(coreGrid, 1, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 10);

		debugSizer = new wxBoxSizer(wxVERTICAL);
		coreSizer->Add(debugSizer, 0, wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 10);
	}

	// ----------------- Core Tab -------------------- //
	wxSizer* menuSizer = AddSpinProp(coreGrid, _("Frame count of menu:"), s_config.GetMenuFrameCount(def), 1, 9999, 80,
			wxT(""), false);
	if (menuSizer)
		menuSizer->AddSpacer(6);
	AddCheckProp(menuSizer, _("Draw buttons on background"), s_config.GetDrawButtonsOnBackground(def));
	AddSpinProp(coreGrid, _("Menu video bitrate:"), s_config.GetMenuVideoBitrate(def), 1, 9999999, 80);
	AddSpinProp(coreGrid, _("Slideshow video bitrate:"), s_config.GetSlideshowVideoBitrate(def), 1, 9999999, 80);
	AddSpinProp(coreGrid, _("Audio bitrate:"), s_config.GetAudioBitrate(def), 1, 9999999, 80);
	AddSpinProp(coreGrid, _("Thread count:"), s_config.GetThreadCount(def), 1, 99, 80);
	AddSpinProp(coreGrid, _("DVD reserved space:"), s_config.GetDvdReservedSpace(def), 0, 9999999, 80);
#if defined(__WXMSW__)
	AddFileProp(coreGrid, _("Preview command:"), s_config.GetPreviewCmd(def), wxFD_OPEN, wxT("..."),
			wxString(_("Executable Files ")) + wxT(" (*.exe)|*.exe") + wxT("|") +
			wxString(_("All Files")) + wxT(" (*.*)|*.*"));
#else
	AddTextProp(coreGrid, _("Preview command:"), s_config.GetPreviewCmd(def));
#endif
	AddTextProp(coreGrid, _("Create ISO command:"), s_config.GetIsoCmd(def));
	AddTextProp(coreGrid, _("Burn command:"), s_config.GetBurnCmd(def));
	AddTextProp(coreGrid, _("Burn ISO command:"), s_config.GetBurnISOCmd(def));
	AddTextProp(coreGrid, _("Add ECC command:"), s_config.GetAddECCCmd(def));
	AddTextProp(coreGrid, _("Format command:"), s_config.GetFormatCmd(def));

	wxSizer* grpSizer = BeginGroup(debugSizer, _("Debug"));
	AddCheckProp(grpSizer, _("Don't remove temp files"), !s_config.GetRemoveTempFiles(def));
	AddCheckProp(grpSizer, _("Use mplex"), s_config.GetUseMplex(def));
	AddCheckProp(grpSizer, _("Use mplex for menus"), s_config.GetUseMplexForMenus(def));
}

bool SettingsDlg::SetValues() {
	// interface settings
	int i = 0;
	if (GetLangCode(GetInt(i++)) != s_config.GetLanguageCode()) {
		s_config.SetLanguageCode(GetLangCode(GetInt(i - 1)));
		wxString langCode = s_config.GetLanguageCode().Upper().substr(0, 2);
		if (DVD::GetAudioLanguageCodes().Index(langCode) != wxNOT_FOUND)
			s_config.SetDefSubtitleLanguage(langCode);
		wxMessageBox(_("Language change will not take effect until DVDStyler is restarted"),
				GetTitle(), wxOK|wxICON_INFORMATION, this);
	}
	s_config.SetDefDiscLabel(GetString(i++));
	s_config.SetDefDiscCapacity(GetInt(i++));
	s_config.SetDefVideoFormat(GetInt(i++) + 2);
	s_config.SetDefAspectRatio(GetInt(i++) + 1);
	s_config.SetDefAudioFormat(GetInt(i++) + 2);
	s_config.SetDefAudioLanguage(GetString(i++));
	s_config.SetDefChapterLength(GetInt(i++));
	s_config.SetDefPostCommand(GetInt(i++));
	s_config.SetDefButton(m_buttons[GetInt(i++)]);
	s_config.SetAcceptInvalidActions(GetBool(i++));
	i++;
	s_config.SetFileBrowserDir(GetString(i++));
#ifndef GNOME2
	s_config.SetClearThumbnailCache(GetBool(i++));
#endif
	s_config.SetUndoHistorySize(GetInt(i++));
	
	// system core settings
	s_config.SetMenuFrameCount(GetInt(i++));
	s_config.SetDrawButtonsOnBackground(GetBool(i++));
	s_config.SetMenuVideoBitrate(GetInt(i++));
	s_config.SetSlideshowVideoBitrate(GetInt(i++));
	s_config.SetAudioBitrate(GetInt(i++));
	s_config.SetThreadCount(GetInt(i++));
	s_config.SetDvdReservedSpace(GetInt(i++));
	s_config.SetPreviewCmd(GetString(i++));
	s_config.SetIsoCmd(GetString(i++));
	s_config.SetBurnCmd(GetString(i++));
	s_config.SetBurnISOCmd(GetString(i++));
	s_config.SetAddECCCmd(GetString(i++));
	s_config.SetFormatCmd(GetString(i++));
	s_config.SetRemoveTempFiles(!GetBool(i++));
	s_config.SetUseMplex(GetBool(i++));
	s_config.SetUseMplexForMenus(GetBool(i++));
	return true;
}

void SettingsDlg::OnChangeFileBrowserDir(wxCommandEvent& evt) {
	wxString dir = evt.GetSelection() == 0 ? wxT("") : wxGetHomeDir();
	m_directoryEdit->SetValue(dir);
	m_directoryEdit->Enable(evt.GetSelection() == 1);
	m_directorySelectButton->Enable(evt.GetSelection() == 1);
}

void SettingsDlg::OnResetDontShowFlags(wxCommandEvent& evt) {
	s_config.SetShowWelcomeDlg(true);
	s_config.SetShowTitleDeletePrompt(true);
	wxMessageBox(_("All \"don't show again\" flags are reseted."), _("Settings"),
			wxOK | wxCENTRE | wxICON_INFORMATION);
}
