/////////////////////////////////////////////////////////////////////////////
// Name:        CellPropDlg.cpp
// Purpose:     DVD cell properties dialog
// Author:      Alex Thuering
// Created:     23.04.2011
// RCS-ID:      $Id: CellPropDlg.cpp,v 1.2 2011/05/15 13:41:21 ntalex Exp $
// Copyright:   (c) Alex Thuering
// Licence:     GPL
/////////////////////////////////////////////////////////////////////////////

#include "CellPropDlg.h"
#include "TitlePropDlg.h"
#include "Utils.h"
#include <wxSVG/mediadec_ffmpeg.h>
#include <wx/regex.h>

// begin wxGlade: ::extracode

// end wxGlade

wxRegEx s_timeRegEx(wxT("^(([[:digit:]]+:)?[[:digit:]][[:digit:]]?:)?[[:digit:]][[:digit:]]?(\\.[[:digit:]]+)?$"));

enum {
	START_CTRL_ID = 2000,
	START_SPIN_BT_ID,
	END_CTRL_ID,
	END_SPIN_BT_ID
};

BEGIN_EVENT_TABLE(CellPropDlg, wxDialog)
    // begin wxGlade: CellPropDlg::event_table
    EVT_TEXT(START_CTRL_ID, CellPropDlg::OnChangeStart)
    EVT_SPIN(START_SPIN_BT_ID, CellPropDlg::OnStartSpin)
    EVT_TEXT(END_CTRL_ID, CellPropDlg::OnChangeEnd)
    EVT_SPIN(END_SPIN_BT_ID, CellPropDlg::OnEndSpin)
    EVT_BUTTON(wxID_OK, CellPropDlg::OnOkBt)
    // end wxGlade
END_EVENT_TABLE();

/**
 * Constructor
 */
CellPropDlg::CellPropDlg(wxWindow* parent, DVD* dvd, int tsi, int pgci, Vob* vob, Cell* cell): wxDialog(parent,
		wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
	m_dvd = dvd;
	m_tsi = tsi;
	m_pgci = pgci;
	m_vob = vob;
	m_cell = cell;
    // begin wxGlade: CellPropDlg::CellPropDlg
    m_typeLabel = new wxStaticText(this, wxID_ANY, _("Type:"));
    m_regularRadioBt = new wxRadioButton(this, wxID_ANY, _("Regular"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
    m_chapterRadioBt = new wxRadioButton(this, wxID_ANY, _("Chapter"));
    m_programRadioBt = new wxRadioButton(this, wxID_ANY, _("Program"));
    m_startLabel = new wxStaticText(this, wxID_ANY, _("Start:"));
    m_startCtrl = new wxTextCtrl(this, START_CTRL_ID, wxEmptyString);
    m_startSpinBt = new wxSpinButton(this, START_SPIN_BT_ID, wxDefaultPosition, wxDefaultSize, wxSP_VERTICAL);
    m_endLabel = new wxStaticText(this, wxID_ANY, _("End:"));
    m_endCtrl = new wxTextCtrl(this, END_CTRL_ID, wxEmptyString);
    m_endSpinBt = new wxSpinButton(this, END_SPIN_BT_ID, wxDefaultPosition, wxDefaultSize, wxSP_VERTICAL);
    m_pauseLabel = new wxStaticText(this, wxID_ANY, _("Pause:"));
    m_pauseSpin = new wxSpinCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -1, 255);
    m_secLabel = new wxStaticText(this, wxID_ANY, _("sec"));
    m_commandLabel = new wxStaticText(this, wxID_ANY, _("Commands:"));
    const wxString *m_commandsCtrl_choices = NULL;
    m_commandsCtrl = new wxComboBox(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0, m_commandsCtrl_choices, wxCB_DROPDOWN);
    m_okBt = new wxButton(this, wxID_OK, _("OK"));
    m_cancelBt = new wxButton(this, wxID_CANCEL, _("Cancel"));

    set_properties();
    do_layout();
    // end wxGlade
    
    m_startCtrl->SetFocus();
}

void CellPropDlg::set_properties() {
    // begin wxGlade: CellPropDlg::set_properties
    SetTitle(_("Cell properties"));
    m_startSpinBt->SetMinSize(wxSize(16, 16));
    m_endSpinBt->SetMinSize(wxSize(16, 16));
    m_okBt->SetDefault();
    // end wxGlade
    
    int x = 0;
    m_startCtrl->GetTextExtent(wxT("00:00:00.000"), &x, NULL);
	m_startCtrl->SetMinSize(wxSize(x + 10, -1));
	m_endCtrl->SetMinSize(wxSize(x + 10, -1));
	m_pauseSpin->GetTextExtent(wxT("999"), &x, NULL);
	m_pauseSpin->SetMinSize(wxSize(x + 32, -1));
    
    wxFfmpegMediaDecoder decoder;
    if (decoder.Load(m_vob->GetFilename())) {
		m_startSpinBt->SetMax(lround(decoder.GetDuration()));
		m_endSpinBt->SetMax(lround(decoder.GetDuration()));
    }
	m_startSpinBt->SetValue(m_cell->GetStart() / 1000);
	m_startCtrl->ChangeValue(Time2String(m_cell->GetStart(), true));
	m_endSpinBt->SetValue(m_cell->GetEnd() >= 0 ? m_cell->GetEnd() / 1000 : 0);
	m_endCtrl->ChangeValue(m_cell->GetEnd() >= 0 ? Time2String(m_cell->GetEnd(), true) : wxT(""));
	m_pauseSpin->SetValue(m_cell->GetPause());
	m_commandsCtrl->Append(TitlePropDlg::GetCommandList(m_dvd, m_tsi));
	m_commandsCtrl->SetValue(m_cell->GetCommands());
	m_chapterRadioBt->SetValue(m_cell->IsChapter());
	m_programRadioBt->SetValue(m_cell->IsProgram());
}


void CellPropDlg::do_layout() {
    // begin wxGlade: CellPropDlg::do_layout
    wxBoxSizer* mainVSizer = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer* buttonSizer = new wxBoxSizer(wxHORIZONTAL);
    wxFlexGridSizer* mainGridSizer = new wxFlexGridSizer(3, 2, 4, 4);
    wxBoxSizer* timeSizer = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* radioBtSizer = new wxBoxSizer(wxHORIZONTAL);
    mainGridSizer->Add(m_typeLabel, 0, wxTOP|wxBOTTOM|wxALIGN_CENTER_VERTICAL, 2);
    radioBtSizer->Add(m_regularRadioBt, 0, wxALIGN_CENTER_VERTICAL, 0);
    radioBtSizer->Add(m_chapterRadioBt, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 4);
    radioBtSizer->Add(m_programRadioBt, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 4);
    mainGridSizer->Add(radioBtSizer, 1, wxEXPAND, 0);
    mainGridSizer->Add(m_startLabel, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 2);
    timeSizer->Add(m_startCtrl, 0, 0, 0);
    timeSizer->Add(m_startSpinBt, 0, wxRIGHT|wxEXPAND, 4);
    timeSizer->Add(m_endLabel, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 4);
    timeSizer->Add(m_endCtrl, 0, wxLEFT, 2);
    timeSizer->Add(m_endSpinBt, 0, wxRIGHT|wxEXPAND, 4);
    timeSizer->Add(m_pauseLabel, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 4);
    timeSizer->Add(m_pauseSpin, 0, wxLEFT, 2);
    timeSizer->Add(m_secLabel, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 4);
    mainGridSizer->Add(timeSizer, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL, 0);
    mainGridSizer->Add(m_commandLabel, 0, wxALIGN_CENTER_VERTICAL, 0);
    mainGridSizer->Add(m_commandsCtrl, 1, wxEXPAND, 0);
    mainGridSizer->AddGrowableRow(2);
    mainGridSizer->AddGrowableCol(1);
    mainVSizer->Add(mainGridSizer, 1, wxALL|wxEXPAND, 6);
    buttonSizer->Add(10, 10, 1, wxEXPAND, 0);
    buttonSizer->Add(m_okBt, 0, 0, 0);
    buttonSizer->Add(8, 8, 0, 0, 0);
    buttonSizer->Add(m_cancelBt, 0, 0, 0);
    buttonSizer->Add(10, 10, 1, wxEXPAND, 0);
    mainVSizer->Add(buttonSizer, 0, wxALL|wxEXPAND, 4);
    SetSizer(mainVSizer);
    mainVSizer->Fit(this);
    Layout();
    // end wxGlade
}

void CellPropDlg::OnChangeStart(wxCommandEvent &event) {
	if (s_timeRegEx.Matches(m_startCtrl->GetValue()))
		m_startSpinBt->SetValue(String2Time(m_startCtrl->GetValue()) / 1000);
}

void CellPropDlg::OnStartSpin(wxSpinEvent &event) {
	m_startCtrl->ChangeValue(Time2String(m_startSpinBt->GetValue() * 1000, true));
}

void CellPropDlg::OnChangeEnd(wxCommandEvent &event) {
	if (s_timeRegEx.Matches(m_endCtrl->GetValue()))
		m_endSpinBt->SetValue(String2Time(m_endCtrl->GetValue()) / 1000);
}

void CellPropDlg::OnEndSpin(wxSpinEvent &event) {
	m_endCtrl->ChangeValue(Time2String(m_endSpinBt->GetValue() * 1000, true));
}

void CellPropDlg::OnOkBt(wxCommandEvent &event) {
	if (!s_timeRegEx.Matches(m_startCtrl->GetValue())) {
		wxLogError(_("'%s' is not valid time"), m_startCtrl->GetValue().c_str());
		return;
	}
	if (m_endCtrl->GetValue().length() > 0 && !s_timeRegEx.Matches(m_endCtrl->GetValue())) {
		wxLogError(_("'%s' is not valid time"), m_endCtrl->GetValue().c_str());
		return;
	}
	if (m_endCtrl->GetValue().length() > 0
			&& String2Time(m_startCtrl->GetValue()) > String2Time(m_endCtrl->GetValue())) {
		wxLogError(_("Start time cannot be after end time"));
		return;
	}
	DVDAction action;
	action.SetCustom(m_commandsCtrl->GetValue());
	if (m_commandsCtrl->GetValue().length() && !action.IsValid(m_dvd, m_tsi, m_pgci, false, wxT(""), true, false)) {
		return;
	}
	m_cell->SetStart(String2Time(m_startCtrl->GetValue()));
	m_cell->SetEnd(m_endCtrl->GetValue().length() ? String2Time(m_endCtrl->GetValue()) : -1);
	m_cell->SetPause(m_pauseSpin->GetValue());
	m_cell->SetCommands(m_commandsCtrl->GetValue());
	m_cell->SetChapter(m_chapterRadioBt->GetValue());
	m_cell->SetProgram(m_programRadioBt->GetValue());
	EndModal(wxID_OK);
}

// wxGlade: add CellPropDlg event handlers
