/////////////////////////////////////////////////////////////////////////////
// Name:        MenuPropDlg.cpp
// Purpose:     DVD menu properties dialog
// Author:      Alex Thuering
// Created:     25.04.2004
// RCS-ID:      $Id: MenuPropDlg.cpp,v 1.27 2010/05/10 20:43:10 ntalex Exp $
// Copyright:   (c) Alex Thuering
// Licence:     GPL
/////////////////////////////////////////////////////////////////////////////

#include "MenuPropDlg.h"
#include "TitlesetManager.h"
#include "AVPropDlg.h"
#include "Config.h"

enum {
	AV_BT_ID = 7850,
	LOOP_CB_ID = 7851
};

BEGIN_EVENT_TABLE(MenuPropDlg, wxPropDlg)
	EVT_BUTTON(AV_BT_ID, MenuPropDlg::OnAV)
	EVT_CHECKBOX(LOOP_CB_ID, MenuPropDlg::OnLoopCheck)
END_EVENT_TABLE()

MenuPropDlg::MenuPropDlg(wxWindow *parent, DVD* dvd, int tsi, int pgci):
		wxPropDlg(parent), m_dvd(dvd), m_tsi(tsi), m_pgci(pgci) {
	PgcArray& pgcs = m_dvd->GetPgcArray(tsi, true);
	m_video = &pgcs.GetVideo();
	m_langCodes = &pgcs.GetAudioLangCodes();
	m_pgc = pgcs[pgci];
	m_vob = m_dvd->GetMenuVob(tsi, pgci);
	m_menu = m_vob->GetMenu();
	// set title
	wxString title = _("Properties") + wxString(wxT(" - "));
	if (tsi >= 0) {
		if (dvd->GetTitlesets().Count() > 1)
			title += _("Titleset") + wxString::Format(wxT(" %d "), tsi+1);
		title += _("Menu") + wxString::Format(wxT(" %d"), pgci+1);
	} else
		title += _("vmMenu") + wxString::Format(wxT(" %d"), pgci+1);
	SetTitle(title);
	// create
	Create();
	SetSize(400,-1);
}

void MenuPropDlg::CreatePropPanel(wxSizer* sizer) {
	wxFlexGridSizer* grid = new wxFlexGridSizer(3, 4, 16);
	grid->AddGrowableCol(1);
	grid->AddGrowableCol(2);
	wxArrayString formats = DVD::GetVideoFormatLabels(false, false, true);
	int vf = m_menu->GetVideoFormat() >= 2 ? m_menu->GetVideoFormat() - 2 : 0;
	AddChoiceProp(grid, _("Format:"), formats[vf], formats);
	formats = DVD::GetAspectRatioLabels();
	int ar = m_menu->GetAspectRatio() >= 1 ? m_menu->GetAspectRatio() - 1 : 0;
	AddChoiceProp(grid, wxT(""), formats[ar], formats);
	sizer->Add(grid, 0, wxEXPAND | wxALL, 6);

	wxSizer* grpSizer = BeginGroup(sizer, _("Background"));
	grid = new wxFlexGridSizer(2, 2, 4, 16);
	grid->AddGrowableCol(1);
	AddFileProp(grid, _("Image:"), m_menu->GetBackground(), wxFD_OPEN, wxT("..."),
			_("Image Files ") + wxImage::GetImageExtWildcard()
		+ wxT("|") + wxString(_("All Files")) + wxT(" (*.*)|*.*"));
	AddColourProp(grid, _("Colour:"), m_menu->GetBackgroundColour());
	grpSizer->Add(grid, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 6);

	sizer->Add(6,6);

	grpSizer = BeginGroup(sizer, _("Subtitles (buttons)"));
	grid = new wxFlexGridSizer(2, 2, 4, 16);
	grid->AddGrowableCol(1);
	AddTextProp(grid, _("Start time:"), m_menu->GetStartTime());
	AddTextProp(grid, _("End time:"), m_menu->GetEndTime());
	grpSizer->Add(grid, 0, wxEXPAND|wxALL, 6);

	// VOB properties
	grpSizer = BeginGroup(sizer, _("Video object"));
	grid = new wxFlexGridSizer(2, 4, 16);
	grid->AddGrowableCol(1);
	// audio file
	wxString audioFile = m_vob->GetAudioFilenames().size() ? m_vob->GetAudioFilenames()[0] : wxT("");
	AddFileProp(grid, _("Audio:"), audioFile, wxFD_OPEN, wxT("..."),
			_("Audio Files") + wxString(wxT(" (*.mp2;*.ac3)|*.mp2;*.ac3|"))
			+ _("All Files") + wxString(wxT(" (*.*)|*.*")));
	// audio language
	wxArrayString labels = DVD::GetAudioLanguageCodes();
	if (m_langCodes->GetCount() < 1)
		m_langCodes->Add(s_config.GetDefAudioLanguage());
	AddChoiceProp(grid, _("Language:"), (*m_langCodes)[0], labels, 0, false);
	
	// pause and loop
	bool loop = m_vob->GetPause() == 0 && m_pgc->GetPostCommands() == wxT("jump cell 1;");
	wxSizer* pSizer = AddSpinProp(grid, _("Pause:"), m_vob->GetPause(), -1, 254, 100, _("sec"),false);
	m_pauseCtrl = (wxSpinCtrl*) GetLastControl();
	m_pauseCtrl->Enable(!loop);
	pSizer->AddSpacer(4);
	AddCheckProp(pSizer, _T("Loop"), loop, false, LOOP_CB_ID);
	grpSizer->Add(grid, 0, wxEXPAND|wxALL, 6);

	sizer->Add(6,6);

	grpSizer = BeginGroup(sizer, _("Menu"));
	grid = new wxFlexGridSizer(2, 2, 4, 16);
	grid->AddGrowableCol(1);

	const StringSet& entries = m_pgc->GetEntries();
	if (m_tsi>=0) {
		AddCheckProp(grid, _("Root"), entries.find(wxT("root")) != entries.end());
		AddCheckProp(grid, _("Subtitle"), entries.find(wxT("subtitle")) != entries.end());
		AddCheckProp(grid, _("Chapter"), entries.find(wxT("ptt")) != entries.end());
		AddCheckProp(grid, _("Angle"), entries.find(wxT("angle")) != entries.end());
		AddCheckProp(grid, _("Audio"), entries.find(wxT("audio")) != entries.end());
	} else
		AddCheckProp(grid, _("Title"), entries.find(wxT("title")) != entries.end());
	AddText(grid, wxEmptyString);

	wxArrayString commands = GetCommands();
	AddComboProp(grid, _("Pre commands:"), m_pgc->GetPreCommands(), commands);
	AddComboProp(grid, _("Post commands:"), m_pgc->GetPostCommands(), commands);
	m_postCommandsCtrl = (wxComboBox*) GetLastControl();
	m_postCommandsCtrl->Enable(!loop);
	grpSizer->Add(grid, 0, wxEXPAND|wxALL, 6);
}

wxArrayString MenuPropDlg::GetCommands() {
	wxArrayString commands;
	commands.Add(wxT("jump cell 1;"));
	for (int pgci=0; pgci<(int)m_dvd->GetVmgm().Count(); pgci++)
		commands.Add(wxString::Format(_T("jump vmgm menu %d;"),pgci+1));
	for (int tsi=0; tsi<(int)m_dvd->GetTitlesets().Count(); tsi++) {
		Titleset* ts = m_dvd->GetTitlesets()[tsi];
		for (int pgci=0; pgci<(int)ts->GetMenus().Count(); pgci++)
			commands.Add(wxString::Format(_T("jump menu %d;"),pgci+1));
		for (int pgci=0; pgci<(int)ts->GetTitles().Count(); pgci++)
			commands.Add(wxString::Format(_T("jump title %d;"),pgci+1));
	}
	return commands;
}

bool MenuPropDlg::SetValues() {
	// check commands
	DVDAction action(false, BUTTON_ACTION);
	action.SetCustom(GetString(m_tsi >= 0 ? 15 : 11));
	if (!action.IsValid(m_dvd, m_tsi, m_pgci, true, wxT(""), true, false))
		return false;
	action.SetCustom(GetString(m_tsi >= 0 ? 16 : 12));
	if (!action.IsValid(m_dvd, m_tsi, m_pgci, true, wxT(""), true, false))
		return false;
	
	int n = 0;
	m_menu->SetVideoFormat((VideoFormat) (GetInt(n++) + 2));
	m_menu->SetAspectRatio((AspectRatio) (GetInt(n++) + 1));
	m_menu->SetBackground(GetString(n++));
	if (!GetString(n - 1).length())
		m_menu->SetBackgroundColour(GetColour(n));
	n++;

	m_menu->SetStartTime(GetString(n++));
	m_menu->SetEndTime(GetString(n++));

	// VOB properties
	wxString audioFile = GetString(n++).Strip(wxString::both);
	while (m_vob->GetAudioFilenames().GetCount() > 0)
		m_vob->RemoveAudioFile(0);
	if (audioFile.length() > 0)
		m_vob->AddAudioFile(audioFile);
	m_langCodes->RemoveAt(0);
	m_langCodes->Insert(GetString(n++), 0);
	m_vob->SetPause(GetInt(n++));
	n++;

	// set entries
	StringSet entries;
	if (m_tsi >= 0) {
		if (GetBool(n++))
			entries.insert(wxT("root"));
		if (GetBool(n++))
			entries.insert(wxT("subtitle"));
		if (GetBool(n++))
			entries.insert(wxT("ptt"));
		if (GetBool(n++))
			entries.insert(wxT("angle"));
		if (GetBool(n++))
			entries.insert(wxT("audio"));
	} else if (GetBool(n++))
		entries.insert(wxT("title"));
	m_pgc->SetEntries(entries);
	// remove same entries from other menus in the same titleset
	PgcArray& pgcs = m_dvd->GetPgcArray(m_tsi, true);
	for (int pgci = 0; pgci<(int)pgcs.size(); pgci++) {
		if (pgci != m_pgci) {
			pgcs[pgci]->RemoveEntries(entries);
		}
	}

	m_pgc->SetPreCommands(GetString(n++));
	m_pgc->SetPostCommands(GetString(n++));
	// fix coordinates of buttons if they are out of range
	m_menu->FixButtonCoordinates();
	return true;
}

void MenuPropDlg::CreateButtonPane(wxSizer* sizer, bool resetButton, bool dontShowCheckbox) {
	wxBoxSizer* buttonPane = new wxBoxSizer(wxHORIZONTAL);
	wxButton* avBt = new wxButton(this, AV_BT_ID, _("Video..."));
	buttonPane->Add(avBt, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
	buttonPane->Add(10, 10, 1, wxEXPAND);
	wxButton* okBt = new wxButton(this, wxID_OK, _("OK"));
	okBt->SetDefault();
	buttonPane->Add(okBt, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
	buttonPane->Add(8, 0);
	wxButton* cancelBt = new wxButton(this, wxID_CANCEL, _("Cancel"));
	buttonPane->Add(cancelBt, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
	sizer->Add(buttonPane, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10);
}

void MenuPropDlg::OnAV(wxCommandEvent& event) {
	AVPropDlg propDlg(this, m_video, true);
	if (propDlg.ShowModal() == wxID_OK) {
		wxCommandEvent evt(EVT_COMMAND_DVD_CHANGED, this->GetId());
		GetEventHandler()->ProcessEvent(evt);
	}
}

void MenuPropDlg::OnLoopCheck(wxCommandEvent& event) {
	m_pauseCtrl->SetValue(event.IsChecked() ? 0 : -1);
	m_pauseCtrl->Enable(!event.IsChecked());
	m_postCommandsCtrl->SetValue(event.IsChecked() ? wxT("jump cell 1;"): wxT(""));
	m_postCommandsCtrl->Enable(!event.IsChecked());
}
