#include "AudioPropDlg.h"

//(*InternalHeaders(AudioPropDlg)
#include <wx/button.h>
#include <wx/string.h>
#include <wx/intl.h>
//*)

//(*IdInit(AudioPropDlg)
const long AudioPropDlg::ID_STATICTEXT1 = wxNewId();
const long AudioPropDlg::ID_STATICTEXT2 = wxNewId();
const long AudioPropDlg::ID_STATICTEXT3 = wxNewId();
const long AudioPropDlg::ID_STATICTEXT4 = wxNewId();
const long AudioPropDlg::ID_STATICTEXT5 = wxNewId();
const long AudioPropDlg::ID_STATICTEXT6 = wxNewId();
const long AudioPropDlg::ID_STATICTEXT7 = wxNewId();
const long AudioPropDlg::ID_DST_CHOICE = wxNewId();
const long AudioPropDlg::ID_A51_CHECK = wxNewId();
const long AudioPropDlg::ID_STATICTEXT8 = wxNewId();
const long AudioPropDlg::ID_LANG_CHOICE = wxNewId();
const long AudioPropDlg::ID_STATICTEXT9 = wxNewId();
const long AudioPropDlg::ID_VOLUME_CTRL = wxNewId();
const long AudioPropDlg::ID_SPINBUTTON1 = wxNewId();
const long AudioPropDlg::ID_STATICTEXT10 = wxNewId();
const long AudioPropDlg::ID_TEXTCTRL1 = wxNewId();
const long AudioPropDlg::ID_SPINBUTTON2 = wxNewId();
const long AudioPropDlg::ID_STATICTEXT11 = wxNewId();
//*)

BEGIN_EVENT_TABLE(AudioPropDlg,wxDialog)
	//(*EventTable(AudioPropDlg)
	//*)
END_EVENT_TABLE()

AudioPropDlg::AudioPropDlg(wxWindow* parent,Vob* vob, const wxString& audioFile, const wxString& langCode, int streamIdx) {
	m_vob = vob;
	m_audioFile = audioFile;
	m_langCode = langCode;
	m_stream = vob->GetStreams()[streamIdx];

	//(*Initialize(AudioPropDlg)
	wxStaticText* label3;
	wxStaticText* label4;
	wxBoxSizer* BoxSizer3;
	wxStdDialogButtonSizer* stdDialogButtonSizer;
	wxFlexGridSizer* propGridSizer;
	wxStaticText* label5;
	wxBoxSizer* BoxSizer2;
	wxStaticText* label2;
	wxStaticText* label6;
	wxBoxSizer* mainVSizer;
	wxStaticText* label8;
	wxStaticText* label7;
	wxBoxSizer* BoxSizer1;
	wxStaticText* label1;
	
	Create(parent, wxID_ANY, _("Audio properties"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER, _T("wxID_ANY"));
	mainVSizer = new wxBoxSizer(wxVERTICAL);
	propGridSizer = new wxFlexGridSizer(0, 2, 4, 4);
	label1 = new wxStaticText(this, ID_STATICTEXT1, _("File Name:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT1"));
	propGridSizer->Add(label1, 1, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
	m_fileNameText = new wxStaticText(this, ID_STATICTEXT2, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT2"));
	propGridSizer->Add(m_fileNameText, 1, wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
	label2 = new wxStaticText(this, ID_STATICTEXT3, _("Duration:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT3"));
	propGridSizer->Add(label2, 1, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
	m_durText = new wxStaticText(this, ID_STATICTEXT4, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT4"));
	propGridSizer->Add(m_durText, 1, wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
	label3 = new wxStaticText(this, ID_STATICTEXT5, _("Source Format:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT5"));
	propGridSizer->Add(label3, 1, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 0);
	m_srcText = new wxStaticText(this, ID_STATICTEXT6, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT6"));
	propGridSizer->Add(m_srcText, 1, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 0);
	label4 = new wxStaticText(this, ID_STATICTEXT7, _("Destination Format:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT7"));
	propGridSizer->Add(label4, 1, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 0);
	BoxSizer3 = new wxBoxSizer(wxHORIZONTAL);
	m_dstChoice = new wxChoice(this, ID_DST_CHOICE, wxDefaultPosition, wxDefaultSize, 0, 0, 0, wxDefaultValidator, _T("ID_DST_CHOICE"));
	BoxSizer3->Add(m_dstChoice, 0, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 0);
	m_audio51 = new wxCheckBox(this, ID_A51_CHECK, _("5.1"), wxDefaultPosition, wxSize(-1,-1), 0, wxDefaultValidator, _T("ID_A51_CHECK"));
	m_audio51->SetValue(false);
	BoxSizer3->Add(m_audio51, 0, wxLEFT|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
	propGridSizer->Add(BoxSizer3, 1, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 0);
	label5 = new wxStaticText(this, ID_STATICTEXT8, _("Language:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT8"));
	propGridSizer->Add(label5, 1, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 0);
	m_langChoice = new wxChoice(this, ID_LANG_CHOICE, wxDefaultPosition, wxDefaultSize, 0, 0, 0, wxDefaultValidator, _T("ID_LANG_CHOICE"));
	propGridSizer->Add(m_langChoice, 1, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 0);
	label6 = new wxStaticText(this, ID_STATICTEXT9, _("Volume:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT9"));
	propGridSizer->Add(label6, 1, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 0);
	BoxSizer1 = new wxBoxSizer(wxHORIZONTAL);
	m_volumeCtrl = new wxTextCtrl(this, ID_VOLUME_CTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_VOLUME_CTRL"));
	BoxSizer1->Add(m_volumeCtrl, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 0);
	m_volumeSpin = new wxSpinButton(this, ID_SPINBUTTON1, wxDefaultPosition, wxDefaultSize, wxSP_VERTICAL|wxSP_ARROW_KEYS, _T("ID_SPINBUTTON1"));
	m_volumeSpin->SetRange(0, 1000);
	m_volumeSpin->SetMinSize(wxSize(16,12));
	BoxSizer1->Add(m_volumeSpin, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 0);
	propGridSizer->Add(BoxSizer1, 1, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 0);
	label7 = new wxStaticText(this, ID_STATICTEXT10, _("Time delay:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT10"));
	propGridSizer->Add(label7, 1, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 0);
	BoxSizer2 = new wxBoxSizer(wxHORIZONTAL);
	m_offsetCtrl = new wxTextCtrl(this, ID_TEXTCTRL1, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_TEXTCTRL1"));
	BoxSizer2->Add(m_offsetCtrl, 1, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 0);
	m_offsetSpin = new wxSpinButton(this, ID_SPINBUTTON2, wxDefaultPosition, wxDefaultSize, wxSP_VERTICAL|wxSP_ARROW_KEYS, _T("ID_SPINBUTTON2"));
	m_offsetSpin->SetRange(0, 999);
	m_offsetSpin->SetMinSize(wxSize(16,12));
	BoxSizer2->Add(m_offsetSpin, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 0);
	label8 = new wxStaticText(this, ID_STATICTEXT11, _("ms"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT11"));
	BoxSizer2->Add(label8, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
	propGridSizer->Add(BoxSizer2, 1, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 0);
	mainVSizer->Add(propGridSizer, 1, wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
	stdDialogButtonSizer = new wxStdDialogButtonSizer();
	stdDialogButtonSizer->AddButton(new wxButton(this, wxID_OK, wxEmptyString));
	stdDialogButtonSizer->AddButton(new wxButton(this, wxID_CANCEL, wxEmptyString));
	stdDialogButtonSizer->Realize();
	mainVSizer->Add(stdDialogButtonSizer, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
	SetSizer(mainVSizer);
	mainVSizer->Fit(this);
	mainVSizer->SetSizeHints(this);
	Center();
	
	Connect(ID_DST_CHOICE,wxEVT_COMMAND_CHOICE_SELECTED,(wxObjectEventFunction)&AudioPropDlg::OnChangeFormat);
	Connect(ID_VOLUME_CTRL,wxEVT_COMMAND_TEXT_UPDATED,(wxObjectEventFunction)&AudioPropDlg::OnChangeVolume);
	Connect(ID_SPINBUTTON1,wxEVT_SCROLL_THUMBTRACK,(wxObjectEventFunction)&AudioPropDlg::OnVolumeSpin);
	Connect(ID_TEXTCTRL1,wxEVT_COMMAND_TEXT_UPDATED,(wxObjectEventFunction)&AudioPropDlg::OnChangeOffset);
	Connect(ID_SPINBUTTON2,wxEVT_SCROLL_THUMBTRACK,(wxObjectEventFunction)&AudioPropDlg::OnOffsetSpin);
	//*)
	Connect(wxID_OK,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&AudioPropDlg::OnOk);
	stdDialogButtonSizer->GetAffirmativeButton()->SetDefault();
	
	m_fileNameText->SetLabel(m_audioFile.length() ? m_audioFile : m_vob->GetFilename());
	// duration
	double duration = m_vob->GetDuration();
	if (m_audioFile.length()) {
		wxFfmpegMediaDecoder ffmpeg;
		if (ffmpeg.Load(m_audioFile) && ffmpeg.GetDuration() > 0)
			duration = ffmpeg.GetDuration();
	}
	wxString s = wxT("N/A");
	if (duration > 0) {
		int secs = (int) duration;
		int ms = lround((duration - secs) * 1000);
		int mins = secs / 60;
		secs %= 60;
		int hours = mins / 60;
		mins %= 60;
		s = wxString::Format(wxT("%02d:%02d:%02d.%03d"), hours, mins, secs, ms);
	}
	m_durText->SetLabel(s);
	m_srcText->SetLabel(m_stream->GetSourceFormat());
	
	m_dstChoice->Append(DVD::GetAudioFormatLabels(true, true));
	m_dstChoice->SetSelection(m_stream->GetAudioFormat());
	
	m_audio51->SetValue(m_stream->GetChannelNumber() == 6);
	
	m_langChoice->Append(DVD::GetLanguageNames());
	map<wxString, wxString>& langMap = DVD::GetLanguageMap();
	for (map<wxString, wxString>::iterator langIt = langMap.begin(); langIt != langMap.end(); langIt++) {
		if (langIt->second == m_langCode) {
			m_langChoice->SetStringSelection(langIt->first);
		}
	}
	
	m_volumeCtrl->SetValue(wxString::Format(wxT("%0.2f"), ((double) m_stream->GetAudioVolume())/256));
	m_volumeCtrl->SetMinSize(wxSize(m_dstChoice->GetBestSize().x - m_volumeSpin->GetMinWidth(), -1));
	m_volumeSpin->SetValue(lround(((double) m_stream->GetAudioVolume())/2.56));
	
	m_offsetCtrl->ChangeValue(Time2String(m_stream->GetTsOffset()));
	m_offsetCtrl->Enable(m_audioFile.length() > 0);
	m_offsetCtrl->SetMinSize(wxSize(m_dstChoice->GetBestSize().x - m_offsetSpin->GetMinWidth(), -1));
	m_offsetSpin->SetValue(m_stream->GetTsOffset()/1000);
	m_offsetSpin->Enable(m_audioFile.length() > 0);
	
	wxCommandEvent evt;
	OnChangeFormat(evt);
	
	m_dstChoice->SetFocus();
	mainVSizer->Fit(this);
	mainVSizer->SetSizeHints(this);
	Center();
}

AudioPropDlg::~AudioPropDlg() {
	//(*Destroy(AudioPropDlg)
	//*)
}

void AudioPropDlg::OnChangeFormat(wxCommandEvent& event) {
	m_audio51->Enable(GetAudioFormat() == afAC3 && m_stream->GetSourceChannelNumber() != 6);
	if (!m_audio51->IsEnabled())
		m_audio51->SetValue(m_stream->GetSourceChannelNumber() == 6);
	m_volumeCtrl->Enable(GetAudioFormat() != afNONE && GetAudioFormat() != afCOPY);
}

AudioFormat AudioPropDlg::GetAudioFormat() {
	return (AudioFormat) m_dstChoice->GetSelection();
}

wxString AudioPropDlg::GetLangCode() {
	return DVD::GetLanguageMap()[m_langChoice->GetStringSelection()];
}

void AudioPropDlg::OnChangeVolume(wxCommandEvent& event) {
	wxString value = m_volumeCtrl->GetValue();
	for (unsigned int i = 0; i < value.length(); i++)
		if ((value[i] < wxT('0') || value[i] > wxT('9')) && value[i] != wxT('.'))
			value.Remove(i, 1);
	if (m_volumeCtrl->GetValue() != value)
		m_volumeCtrl->SetValue(value);
	double dval;
	if (m_volumeCtrl->GetValue().ToDouble(&dval))
		m_volumeSpin->SetValue(lround(dval * 100));
}

void AudioPropDlg::OnVolumeSpin(wxSpinEvent& event) {
	m_volumeCtrl->SetValue(wxString::Format(wxT("%0.2f"), ((double) m_volumeSpin->GetValue())/100));
}

void AudioPropDlg::OnChangeOffset(wxCommandEvent& event) {
	if (s_timeRE.Matches(m_offsetCtrl->GetValue()))
		m_offsetSpin->SetValue(lround(String2Time(m_offsetCtrl->GetValue())/1000));
}

void AudioPropDlg::OnOffsetSpin(wxSpinEvent& event) {
	m_offsetCtrl->ChangeValue(Time2String(((long)m_offsetSpin->GetValue()) * 1000));
}

void AudioPropDlg::OnOk(wxCommandEvent& event) {
	double volume;
	if (!m_volumeCtrl->GetValue().ToDouble(&volume)) {
		wxLogError(_("Invalid volume value '%s'"), m_volumeCtrl->GetValue().c_str());
		return;
	}
	if (!s_timeRE.Matches(m_offsetCtrl->GetValue())) {
		wxLogError(_("Invalid time value '%s'"), m_offsetCtrl->GetValue().c_str());
		return;
	}
	m_stream->SetChannelNumber(m_audio51->IsEnabled() && m_audio51->GetValue() ? 6 : -1);
	m_stream->SetAudioVolume(lround(volume*256));
	m_stream->SetTsOffset(String2Time(m_offsetCtrl->GetValue()));
	EndModal(wxID_OK);
}
