/////////////////////////////////////////////////////////////////////////////
// Name:        ChaptersDlg.cpp
// Purpose:     The chapters dialog
// Author:      Alex Thuering
// Created:     19.04.2010
// RCS-ID:      $Id: ChaptersDlg.cpp,v 1.6 2013/04/28 08:04:42 ntalex Exp $
// Copyright:   (c) Alex Thuering
// Licence:     GPL
/////////////////////////////////////////////////////////////////////////////

#include "ChaptersDlg.h"
#include "CellPropDlg.h"
#include "Utils.h"
#include "Config.h"
#include <wx/regex.h>
#include <wx/imaglist.h>
#include <wxVillaLib/utils.h>
#include <wxVillaLib/rc/video.png.h>
#include "rc/add.png.h"
#include "rc/remove.png.h"
#include "rc/preferences.png.h"

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

//(*IdInit(ChaptersDlg)
const long ChaptersDlg::ID_THUMBNAILS = wxNewId();
const long ChaptersDlg::ID_ADD_BT = wxNewId();
const long ChaptersDlg::ID_DEL_BT = wxNewId();
const long ChaptersDlg::ID_PROP_BT = wxNewId();
const long ChaptersDlg::ID_ADD_CELL_CHECK = wxNewId();
//*)

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

ChaptersDlg::ChaptersDlg(wxWindow* parent, DVD* dvd, int tsi, int pgci, int vobi, Vob* vob) {
	m_dvd = dvd;
	m_tsi = tsi;
	m_pgci = pgci;
	m_vobi = vobi;
	m_vob = vob;
	VECTOR_COPY(m_vob->GetCells(), m_cells, Cell);

	//(*Initialize(ChaptersDlg)
	wxBoxSizer* boxSizer1;
	wxBoxSizer* boxSizer2;
	wxStdDialogButtonSizer* stdDialogButtonSizer;
	wxStaticText* staticText1;
	wxBoxSizer* BoxSizer1;
	wxBoxSizer* mainSizer;

	Create(parent, wxID_ANY, _("Chapters"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER, _T("wxID_ANY"));
	SetClientSize(wxSize(400,380));
	mainSizer = new wxBoxSizer(wxVERTICAL);
	staticText1 = new wxStaticText(this, wxID_ANY, _("Chapters:"), wxDefaultPosition, wxDefaultSize, 0, _T("wxID_ANY"));
	mainSizer->Add(staticText1, 0, wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
	boxSizer1 = new wxBoxSizer(wxHORIZONTAL);
	m_thumbnails = new wxThumbnails(this,ID_THUMBNAILS);
	boxSizer1->Add(m_thumbnails, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
	boxSizer2 = new wxBoxSizer(wxVERTICAL);
	m_addBt = new wxBitmapButton(this, ID_ADD_BT, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, _T("ID_ADD_BT"));
	boxSizer2->Add(m_addBt, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 4);
	m_delBt = new wxBitmapButton(this, ID_DEL_BT, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, _T("ID_DEL_BT"));
	boxSizer2->Add(m_delBt, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 4);
	m_propBt = new wxBitmapButton(this, ID_PROP_BT, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, _T("ID_PROP_BT"));
	boxSizer2->Add(m_propBt, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
	boxSizer1->Add(boxSizer2, 0, wxEXPAND|wxALIGN_TOP|wxALIGN_CENTER_HORIZONTAL, 5);
	mainSizer->Add(boxSizer1, 1, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
	BoxSizer1 = new wxBoxSizer(wxHORIZONTAL);
	m_addCellAtBegin = new wxCheckBox(this, ID_ADD_CELL_CHECK, _("Add cell at begin if it doesn\'t exist"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_ADD_CELL_CHECK"));
	m_addCellAtBegin->SetValue(false);
	BoxSizer1->Add(m_addCellAtBegin, 0, 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();
	BoxSizer1->Add(stdDialogButtonSizer, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
	mainSizer->Add(BoxSizer1, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
	SetSizer(mainSizer);
	SetSizer(mainSizer);
	Layout();

	Connect(ID_ADD_BT,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&ChaptersDlg::OnAddBt);
	Connect(ID_DEL_BT,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&ChaptersDlg::OnDelBt);
	Connect(ID_PROP_BT,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&ChaptersDlg::OnPropBt);
	//*)
	Connect(ID_THUMBNAILS, EVT_COMMAND_THUMBNAILS_DCLICK, (wxObjectEventFunction)&ChaptersDlg::OnThumbDoubleClick);
	Connect(ID_THUMBNAILS, EVT_COMMAND_THUMBNAILS_SEL_CHANGED, (wxObjectEventFunction)&ChaptersDlg::OnSelectionChanged);
	m_thumbnails->Connect(wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(ChaptersDlg::OnKeyDown), (wxObject*) NULL, this);
	Connect(wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&ChaptersDlg::OnOkBt);
	stdDialogButtonSizer->GetAffirmativeButton()->SetDefault();

    SetIcon(((wxTopLevelWindow*)wxGetTopLevelParent(parent))->GetIcon());

	m_thumbnails->Clear();
	m_decoder.Load(m_vob->GetFilename());
	//m_decoder.BeginDecode();
	for (vector<Cell*>::const_iterator it = m_cells.begin(); it != m_cells.end(); it++) {
		AddThumbnail((*it));
	}

	m_addBt->SetBitmapLabel(wxBITMAP_FROM_MEMORY(add));
	m_delBt->SetBitmapLabel(wxBITMAP_FROM_MEMORY(remove));
	m_propBt->SetBitmapLabel(wxBITMAP_FROM_MEMORY(preferences));
	
	m_addCellAtBegin->SetValue(m_cells.size() == 0 || m_cells.front()->GetStart() == 0);
	
	if (m_thumbnails->GetItemCount() > 0)
		m_thumbnails->SetSelected(0);
	wxCommandEvent evt;
	OnSelectionChanged(evt);
    m_thumbnails->SetFocus();
}

ChaptersDlg::~ChaptersDlg() {
	//(*Destroy(ChaptersDlg)
	//*)
	m_decoder.Close();
}

wxImage ChaptersDlg::LoadFrame(long pos) {
	double dpos = ((double) pos)/1000;
	wxImage image;
	if (m_decoder.SetPosition(dpos >= 1 ? dpos - 1 : 0)) {
		for (int i = 0; i < 60; i++) {
			image = m_decoder.GetNextFrame();
			if (m_decoder.GetPosition() >= dpos)
				break;
		}
	}
	return image.Ok() ? image : wxBITMAP_FROM_MEMORY(video).ConvertToImage();
}

void ChaptersDlg::AddThumbnail(Cell* cell, int pos) {
	wxThumb* thumb = new wxThumb(wxT(""), cell->GetStartStr());
	thumb->SetImage(LoadFrame(cell->GetStart()));
	m_thumbnails->InsertItem(thumb, pos);
}

void ChaptersDlg::OnAddBt(wxCommandEvent& event) {
	long start = m_cells.size() > 0 ? m_cells.back()->GetStart() + s_config.GetDefChapterLength() * 60000 : 0;
	long duration = m_vob->GetResultDuration()*1000;
	Cell* cell = new Cell(start < duration ? start : duration);
	m_cells.push_back(cell);
	AddThumbnail(cell);
	m_thumbnails->Refresh();
}

void ChaptersDlg::OnDelBt(wxCommandEvent& event) {
	if (m_thumbnails->GetSelected() < 0)
		return;
	m_thumbnails->RemoveItemAt(m_thumbnails->GetSelected());
	m_cells.erase(m_cells.begin() + m_thumbnails->GetSelected());
	if (m_thumbnails->GetSelected() >= m_thumbnails->GetItemCount())
		m_thumbnails->SetSelected(m_thumbnails->GetItemCount() - 1);
	m_thumbnails->Refresh();
}

void ChaptersDlg::OnPropBt(wxCommandEvent& event) {
	int idx = m_thumbnails->GetSelected();
	if (idx < 0)
		return;
	Cell* cell = m_cells[idx];
	CellPropDlg dialog(this, m_dvd, m_tsi, m_pgci, m_vob, cell);
	if (dialog.ShowModal() != wxID_OK)
		return;
	int idx2 = idx;
	while (idx2 > 0 && cell->GetStart() < m_cells[idx2-1]->GetStart())
		idx2--;
	while (idx2 < (int) m_cells.size() - 1 && cell->GetStart() > m_cells[idx2+1]->GetStart())
		idx2++;
	if (idx2 != idx) {
		m_cells.erase(m_cells.begin() + idx);
		m_cells.insert(m_cells.begin() + idx2, cell);
		m_thumbnails->RemoveItemAt(idx);
		AddThumbnail(cell, idx2);
		m_thumbnails->SetSelected(idx2);
	}
	m_thumbnails->GetSelectedItem()->SetCaption(cell->GetStartStr());
	m_thumbnails->GetSelectedItem()->SetImage(LoadFrame(cell->GetStart()));
	m_thumbnails->GetSelectedItem()->Update();
	m_thumbnails->Refresh();
}

void ChaptersDlg::OnThumbDoubleClick(wxCommandEvent& event) {
	OnPropBt(event);
}

void ChaptersDlg::OnSelectionChanged(wxCommandEvent& event) {
	m_delBt->Enable(m_thumbnails->GetSelected() >= 0);
	m_propBt->Enable(m_thumbnails->GetSelected() >= 0);
}

void ChaptersDlg::OnKeyDown(wxKeyEvent& event) {
	switch (event.GetKeyCode()) {
	case WXK_DELETE: {
		wxCommandEvent evt;
		OnDelBt(evt);
		break;
	}
	default:
		event.Skip();
		break;
	}
}

void ChaptersDlg::OnOkBt(wxCommandEvent& event) {
	if (m_cells.size() == 0 && m_vobi == 0)
		m_cells.push_back(new Cell(0));
	else if (m_cells.size() && m_cells.front()->GetStart() != 0 && m_addCellAtBegin->GetValue())
		m_cells.insert(m_cells.begin(), new Cell(0, m_vobi == 0));
	m_vob->GetCells().swap(m_cells);
	EndModal(wxID_OK);
}
