/////////////////////////////////////////////////////////////////////////////
// Name:        MainWin.cpp
// Purpose:     Main window
// Author:      Alex Thuering
// Created:     10.10.2003
// RCS-ID:      $Id: MainWin.cpp,v 1.86 2008/03/16 11:26:22 ntalex Exp $
// Copyright:   (c) Alex Thuering
// Licence:     GPL
/////////////////////////////////////////////////////////////////////////////

#include "MainWin.h"
#include "BurnDlg.h"
#include "KeyDlg.h"
#include "ProgressDlg.h"
#include "About.h"
#include "NewProjectDlg.h"
#include "DVDPropDlg.h"
#include "SettingsDlg.h"
#include "Config.h"
#include "MPEG.h"
#include <wxVillaLib/VerticalToolbar.h>
#include <wxVillaLib/utils.h>
#include <wx/imaglist.h>
#include <wx/filename.h>
#include <wx/textfile.h>
#include "math.h"

#ifdef __WXMSW__
#include <wx/msw/registry.h>
#else
#define wxDirDialogDefaultFolderStr _T("~")
#endif

#include "rc/new.png.h"
#include "rc/open.png.h"
#include "rc/save.png.h"
#include "rc/run.png.h"
#ifndef __WXMSW__
#include "rc/folder1.png.h"
#include "rc/folder2.png.h"
#endif
#include "rc/files.png.h"

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

//////////////////////////// help functions //////////////////////////////////

wxBitmap SetDefaultMask(wxBitmap bitmap)
{
  wxImage tmp = bitmap.ConvertToImage();
  wxColour cmask(tmp.GetRed(0,0), tmp.GetGreen(0,0), tmp.GetBlue(0,0));
  bitmap.SetMask(new wxMask(bitmap, cmask));
  return bitmap;
}

//////////////////////////////// MainWin /////////////////////////////////////

enum 
{
  DIR_TREE_BT_ID = 2250,
  BACKGROUNS_BT_ID,
  BUTTONS_BT_ID,
  THUMBMENU_BACKGROUND_ID
};

BEGIN_EVENT_TABLE(MainWin, wxFrame)
  EVT_TREE_SEL_CHANGED(-1, MainWin::OnDirSelected)
  
  EVT_THUMBNAILS_DCLICK(THUMBNAILS_ID,  MainWin::OnThumbDoubleClick)
  EVT_THUMBNAILS_POINTED(THUMBNAILS_ID, MainWin::OnThumbInfo)
  EVT_THUMBNAILS_POINTED(TITLESET_MANAGER_ID, MainWin::OnTitleInfo)
  EVT_MENUEDITOR_OBJECT_POINTED(MENU_EDITOR_ID, MainWin::OnMenuObjectInfo)
  
  EVT_MENU_SELECTED(TITLESET_MANAGER_ID, MainWin::OnSelectMenu)
  EVT_DVD_CHANGED(TITLESET_MANAGER_ID, MainWin::OnChangedDVD)
  EVT_MENUEDITOR_MENU_CHANGED(MENU_EDITOR_ID, MainWin::OnChangedMenu)
  
  EVT_TOOL(DIR_TREE_BT_ID, MainWin::OnDirTreeBt)
  EVT_TOOL(BACKGROUNS_BT_ID, MainWin::OnBackgroundsBt)
  EVT_TOOL(BUTTONS_BT_ID, MainWin::OnButtonsBt)
  
  EVT_TOOL(wxID_NEW, MainWin::OnNew)
  EVT_TOOL(wxID_OPEN, MainWin::OnOpen)
  EVT_TOOL(wxID_SAVE, MainWin::OnSave)
  EVT_TOOL(wxID_SAVEAS, MainWin::OnSaveAs)
  EVT_TOOL(MENU_BURN_ID, MainWin::OnBurn)
  EVT_TOOL(wxID_EXIT, MainWin::OnExit)
  EVT_MENU(MENU_DVD_ADD_MENU_ID, MainWin::OnAddMenu)
  EVT_MENU(MENU_DVD_ADD_VMMENU_ID, MainWin::OnAddVmMenu)
  EVT_MENU(MENU_DVD_ADD_TITLESET_ID, MainWin::OnAddTitleset)
  EVT_UPDATE_UI(MENU_DVD_ADD_TITLESET_ID, MainWin::OnAddTitlesetUpdateUI)
  EVT_MENU(MENU_DVD_OPTIONS_ID, MainWin::OnDVDOptions)
  EVT_TOOL(MENU_SETTINGS_ID, MainWin::OnSettings)
  EVT_TOOL(wxID_ABOUT, MainWin::OnAbout)
  
  EVT_MENU(THUMBMENU_BACKGROUND_ID, MainWin::OnSetBackground)
  EVT_UPDATE_UI(THUMBMENU_BACKGROUND_ID, MainWin::OnUpdateUISetBackground)
  
  EVT_SIZE(MainWin::OnResize)
  EVT_SPLITTER_SASH_POS_CHANGED(SPLIITTER_TITLE_ID, MainWin::OnSplitterTitleSash)
  EVT_CLOSE(MainWin::OnClose)
END_EVENT_TABLE()

MainWin::MainWin(): wxFrame(NULL, -1, _T(""), wxDefaultPosition, wxDefaultSize,
		wxDEFAULT_FRAME_STYLE), m_dvd(NULL) {
    // begin wxGlade: MainWin::MainWin
    m_splitterTitle = new wxSplitterWindow(this, SPLIITTER_TITLE_ID, wxDefaultPosition, wxDefaultSize, wxCLIP_CHILDREN);
    m_splitterDir = new wxSplitterWindow(m_splitterTitle, -1, wxDefaultPosition, wxDefaultSize, wxCLIP_CHILDREN);
    m_splitterThumb = new wxSplitterWindow(m_splitterDir, -1, wxDefaultPosition, wxDefaultSize, wxCLIP_CHILDREN);
    m_thumbPanel = new wxPanel(m_splitterThumb, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL|wxCLIP_CHILDREN);
    m_menubar = new wxMenuBar();
    SetMenuBar(m_menubar);
    wxMenu* wxglade_tmp_menu_1 = new wxMenu();
    wxglade_tmp_menu_1->Append(wxID_NEW, _("&New"), wxT(""), wxITEM_NORMAL);
    wxglade_tmp_menu_1->Append(wxID_OPEN, _("&Open..."), wxT(""), wxITEM_NORMAL);
    wxglade_tmp_menu_1->Append(wxID_SAVE, _("&Save"), wxT(""), wxITEM_NORMAL);
    wxglade_tmp_menu_1->Append(wxID_SAVEAS, _("S&ave as..."), wxT(""), wxITEM_NORMAL);
    wxglade_tmp_menu_1->AppendSeparator();
    wxglade_tmp_menu_1->Append(MENU_BURN_ID, _("&Burn dvd..."), wxT(""), wxITEM_NORMAL);
    wxglade_tmp_menu_1->AppendSeparator();
    wxglade_tmp_menu_1->Append(wxID_EXIT, _("&Exit"), wxT(""), wxITEM_NORMAL);
    m_menubar->Append(wxglade_tmp_menu_1, _("&File"));
    wxMenu* wxglade_tmp_menu_2 = new wxMenu();
    wxMenu* wxglade_tmp_menu_2_sub = new wxMenu();
    wxglade_tmp_menu_2_sub->Append(MENU_DVD_ADD_MENU_ID, _("&Menu"), wxT(""), wxITEM_NORMAL);
    wxglade_tmp_menu_2_sub->Append(MENU_DVD_ADD_VMMENU_ID, _("&vmMenu"), wxT(""), wxITEM_NORMAL);
    wxglade_tmp_menu_2_sub->Append(MENU_DVD_ADD_TITLESET_ID, _("&Titleset"), wxT(""), wxITEM_NORMAL);
    wxglade_tmp_menu_2->Append(wxNewId(), _("&Add"), wxglade_tmp_menu_2_sub, wxT(""));
    wxglade_tmp_menu_2->AppendSeparator();
    wxglade_tmp_menu_2->Append(MENU_DVD_OPTIONS_ID, _("&Options..."), wxT(""), wxITEM_NORMAL);
    m_menubar->Append(wxglade_tmp_menu_2, _("&DVD"));
    wxMenu* wxglade_tmp_menu_3 = new wxMenu();
    wxglade_tmp_menu_3->Append(MENU_SETTINGS_ID, _("&Settings..."), wxT(""), wxITEM_NORMAL);
    m_menubar->Append(wxglade_tmp_menu_3, _("&Configuration"));
    wxMenu* wxglade_tmp_menu_4 = new wxMenu();
    wxglade_tmp_menu_4->Append(wxID_ABOUT, _("&About..."), wxT(""), wxITEM_NORMAL);
    m_menubar->Append(wxglade_tmp_menu_4, _("&Help"));
    m_statusbar = CreateStatusBar(2, 0);
    m_dirBar = new wxToolBar(this, -1, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxTB_VERTICAL|wxTB_FLAT);
    m_dirTree = new wxGenericDirCtrl(m_splitterDir, DIR_TREE_ID, wxDirDialogDefaultFolderStr, wxDefaultPosition, wxDefaultSize, wxDIRCTRL_DIR_ONLY );
    m_thumbLabel = new wxStaticText(m_thumbPanel, -1, _("Directory"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE|wxST_NO_AUTORESIZE);
    m_thumbnails = new wxThumbnails(m_thumbPanel, THUMBNAILS_ID);
    m_menuEditor = new MenuEditor(m_splitterThumb, MENU_EDITOR_ID);
    m_titlesetManager = new TitlesetManager(m_splitterTitle, TITLESET_MANAGER_ID);

    set_properties();
    do_layout();
    // end wxGlade
    
    m_menuEditor->SetTitlesetManager(m_titlesetManager);
    
    // set fiter
    m_thumbnails->AddCustomExtention(wxT("sub"));
    m_thumbnails->AddCustomExtention(wxT("srt"));
    m_thumbnails->AddCustomExtention(wxT("ssa"));
    m_thumbnails->AddCustomExtention(wxT("smi"));
    m_thumbnails->AddCustomExtention(wxT("rt"));
    m_thumbnails->AddCustomExtention(wxT("txt"));
    m_thumbnails->AddCustomExtention(wxT("aqt"));
    m_thumbnails->AddCustomExtention(wxT("jss"));
    m_thumbnails->AddCustomExtention(wxT("js"));
    m_thumbnails->AddCustomExtention(wxT("ass"));
    m_thumbnails->SetFilter(wxTHUMB_FILTER_IMAGES|wxTHUMB_FILTER_VIDEOS|wxTHUMB_FILTER_AUDIOS|wxTHUMB_FILTER_CUSTOM);
	
	// set file browser dir
	wxString fbDir = s_config.GetFileBrowserDir();
	if (fbDir.length() == 0)
		fbDir = s_config.GetFileBrowserLastDir();
	if (fbDir.length() == 0)
		fbDir = wxGetHomeDir();
	m_dirTree->SetPath(fbDir);
	m_lastDir = s_config.GetLastProjectDir();
	
	// show Backgrouns
	m_dirBar->ToggleTool(BACKGROUNS_BT_ID, true);
	wxCommandEvent evt;
	OnBackgroundsBt(evt);
	NewDVD(s_config.GetDefVolumeName(), (VideoFormat)s_config.GetDefVideoFormat(),
	  (AudioFormat)s_config.GetDefAudioFormat());
	
	// Restore frame size/position
	wxRect rect = s_config.GetMainWinLocation();
	if (rect.width > 0 && rect.height > 0)
	  SetSize(rect);
    
    wxMenu* thumbMenu = new wxMenu;
    thumbMenu->Append(THUMBMENU_BACKGROUND_ID, _("&Assign to background"));
    m_thumbnails->SetPopupMenu(thumbMenu);
}

void MainWin::set_properties()
{
    m_toolbar = new wxToolBar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_HORIZONTAL|wxTB_FLAT|wxTB_DOCKABLE);
	SetToolBar(m_toolbar);
    
    // begin wxGlade: MainWin::set_properties
    SetTitle(_("DVDStyler"));
    SetSize(wxSize(1000, 740));
    int m_statusbar_widths[] = { -1, 200 };
    m_statusbar->SetStatusWidths(2, m_statusbar_widths);
    const wxString m_statusbar_fields[] = {
        wxT(""),
        wxT("")
    };
    for(int i = 0; i < m_statusbar->GetFieldsCount(); ++i) {
        m_statusbar->SetStatusText(m_statusbar_fields[i], i);
    }
    m_dirBar->SetSize(wxSize(40, -1));
    m_thumbLabel->SetBackgroundColour(wxColour(90, 16, 198));
    m_thumbLabel->SetForegroundColour(wxColour(255, 255, 255));
    m_titlesetManager->SetSize(wxSize(955, 124));
    // end wxGlade
	
	m_thumbLabel->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
#ifndef __WXMSW__
    m_thumbLabel->SetForegroundColour(wxColour(0, 0, 0));
#endif
	
	// tool bar
	m_toolbar->AddTool(wxID_NEW,  wxT(""), wxBITMAP_FROM_MEMORY(new),  wxNullBitmap,
	  wxITEM_NORMAL, _("New"), wxT(""));
	m_toolbar->AddTool(wxID_OPEN, wxT(""), wxBITMAP_FROM_MEMORY(open), wxNullBitmap,
	  wxITEM_NORMAL, _("Open..."), wxT(""));
	m_toolbar->AddTool(wxID_SAVE, wxT(""), wxBITMAP_FROM_MEMORY(save), wxNullBitmap,
	  wxITEM_NORMAL, _("Save"), wxT(""));
	m_toolbar->AddTool(MENU_BURN_ID,  wxT(""), wxBITMAP_FROM_MEMORY(run),  wxNullBitmap,
	  wxITEM_NORMAL, _("Burn..."), wxT(""));
	m_toolbar->Realize();
	
	// dir tree
#ifndef __WXMSW__
	m_dirTree->GetTreeCtrl()->GetImageList()->Replace(0, SetDefaultMask(wxBITMAP_FROM_MEMORY(folder1)));
    m_dirTree->GetTreeCtrl()->GetImageList()->Replace(1, SetDefaultMask(wxBITMAP_FROM_MEMORY(folder2)));
#endif
	m_dirTree->SetWindowStyle(m_dirTree->GetWindowStyle() | wxCLIP_CHILDREN);
	
	// thumbnails
    m_thumbnails->SetLabelControl(m_thumbLabel);
	m_thumbnails->EnableDragging();
	
    // dir bar
    m_dirBar->SetMargins(4, 4);
    wxVerticalToolbar* vertToolBar = new wxVerticalToolbar(m_dirBar);
    vertToolBar->AddTool(DIR_TREE_BT_ID, _("Directories"), wxBITMAP_FROM_MEMORY(files),
	  wxITEM_RADIO);
    vertToolBar->AddTool(BACKGROUNS_BT_ID, _("Backgrounds"), wxNullBitmap,
	  wxITEM_RADIO);
	vertToolBar->AddTool(BUTTONS_BT_ID, _("Buttons"), wxNullBitmap,
	  wxITEM_RADIO);
    vertToolBar->Update();
    m_dirBar->Realize();
}


void MainWin::do_layout()
{
    // begin wxGlade: MainWin::do_layout
    wxBoxSizer* mainWinSizer = new wxBoxSizer(wxHORIZONTAL);
    wxBoxSizer* thumbSizer = new wxBoxSizer(wxVERTICAL);
    mainWinSizer->Add(m_dirBar, 0, wxEXPAND, 0);
    thumbSizer->Add(m_thumbLabel, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 0);
    thumbSizer->Add(m_thumbnails, 1, wxEXPAND, 0);
    m_thumbPanel->SetAutoLayout(true);
    m_thumbPanel->SetSizer(thumbSizer);
    thumbSizer->Fit(m_thumbPanel);
    thumbSizer->SetSizeHints(m_thumbPanel);
    m_splitterThumb->SplitVertically(m_thumbPanel, m_menuEditor, 189);
    m_splitterDir->SplitVertically(m_dirTree, m_splitterThumb, 10);
    m_splitterTitle->SplitHorizontally(m_splitterDir, m_titlesetManager, 560);
    mainWinSizer->Add(m_splitterTitle, 1, wxEXPAND, 0);
    SetAutoLayout(true);
    SetSizer(mainWinSizer);
    Layout();
    Centre();
    // end wxGlade
	
	// splitters
	m_thumbPanel->SetSizeHints(
	  m_thumbnails->GetMinWidth(), m_thumbnails->GetMinHeight());
	m_splitterDirSash = 200;
	m_splitterDir->Unsplit(m_dirTree);
	m_splitterThumb->SetSashPosition(238);
	m_splitterDir->SetMinimumPaneSize(1);
    m_splitterThumb->SetMinimumPaneSize(1);
	m_splitterTitle->SetMinimumPaneSize(1);
	m_splitterTitleSash = 0;
}

void MainWin::ShowDirTree(bool show)
{
  m_dirBar->ToggleTool(DIR_TREE_BT_ID, show);
  if (show)
  {
    if (!m_splitterDir->IsSplit())
    {
      m_splitterDir->SplitVertically(m_dirTree, m_splitterThumb, m_splitterDirSash);
      m_dirTree->Show(true);
    }
  }
  else
  {
    if (m_splitterDir->IsSplit())
    {
      m_splitterDirSash = m_splitterDir->GetSashPosition();
      
      // animate unsplitting
      m_dirTree->Freeze();
      wxStopWatch sw;
      float step = 0;
      int pos = m_splitterDirSash - 10;
      while (pos > 0)
      {
        m_splitterDir->SetSashPosition(pos);
        while (wxTheApp->Pending())
          wxTheApp->Dispatch();
        if (step == 0)
          step = sw.Time();
        pos -= int(step);
      }
      m_splitterDir->Unsplit(m_dirTree);
      m_dirTree->SetSize(0,0);
      m_dirTree->Thaw();
    }
  }
}

void MainWin::OnDirTreeBt(wxCommandEvent& event)
{
  if (!m_splitterDir->IsSplit())
  {
	ShowDirTree(true);
	wxTreeEvent evt;
	OnDirSelected(evt);
  }
  else
	ShowDirTree(false);
}

void MainWin::OnBackgroundsBt(wxCommandEvent& event)
{
  ShowDirTree(false);
  m_thumbnails->ShowFileNames(false);
  m_thumbnails->ShowDir(BACKGROUNDS_DIR);
  m_thumbnails->SetCaption(_("Backgrounds"));
}

void MainWin::OnButtonsBt(wxCommandEvent& event)
{
  wxArrayString buttons;
  wxTextFile file;
  if (file.Open(BUTTONS_DIR + wxT("buttons.lst")))
  {
    for (int i=0; i<(int)file.GetLineCount(); i++)
    {
      wxFileName fileName(file[i]);
      if (fileName.IsRelative())
        fileName.MakeAbsolute(BUTTONS_DIR);
      if (wxFile::Exists(fileName.GetFullPath()))
        buttons.Add(fileName.GetFullPath());
    }
  }
  wxString fname = wxFindFirstFile(BUTTONS_DIR + _T("*.xml"));
  while (!fname.IsEmpty())
  {
	if (buttons.Index(fname) == -1)
      buttons.Add(fname);
    fname = wxFindNextFile();
  }
  
  ShowDirTree(false);
  m_thumbnails->Clear();
  Menu menu;
  for (int i=0; i<(int)buttons.Count(); i++)
  {
	wxThumb* thumb = new wxThumb(buttons[i]);
	MenuObject bt(&menu, buttons[i], 0, 0, _("button"));
	thumb->SetImage(bt.GetImage(m_thumbnails->GetThumbWidth(),
	  m_thumbnails->GetThumbHeight()));
    m_thumbnails->InsertItem(thumb);
  }
  m_thumbnails->SetCaption(_("Buttons"));
}

void MainWin::OnDirSelected(wxTreeEvent& event)
{
  if (!m_dvd)
    return;
  m_thumbnails->ShowFileNames();
  m_thumbnails->ShowDir(m_dirTree->GetPath());
  s_config.SetFileBrowserLastDir(m_dirTree->GetPath());
}

void MainWin::OnThumbInfo(wxCommandEvent& event)
{
  wxString text;
  if (m_thumbnails->GetPointed() != -1)
  {
	if (m_dirBar->GetToolState(BACKGROUNS_BT_ID))
		text = _("Double click to set the background.");
	else if (m_dirBar->GetToolState(BUTTONS_BT_ID))
		text = m_thumbnails->GetPointedItem()->GetFilename().AfterLast(wxFILE_SEP_PATH);
	else
		text = m_thumbnails->GetPointedItem()->GetFilename();
  }
  m_statusbar->SetStatusText(text, 0);
}

void MainWin::OnTitleInfo(wxCommandEvent& event)
{
  wxString text;
  if (m_titlesetManager->GetPointed() != -1)
  {
	int id = m_titlesetManager->GetPointedId();
	Vob* vob = m_dvd->GetVob(DVD::GetTsi(id), DVD::IsMenu(id),
	  DVD::GetPgci(id), DVD::GetVobi(id));
	if (vob)
	{
	  text = vob->GetFilename();
	  if (!text.length())
		text = vob->GetVideoFilename();
      for (unsigned int i=0; i<vob->GetAudioFilenames().Count(); i++)
        text += _T(" + ") + vob->GetAudioFilenames()[i];
      for (unsigned int i=0; i<vob->GetSubtitles().Count(); i++)
        text += _T(" + ") + vob->GetSubtitles()[i]->GetFilename();
	  if (text.length())
	  {
		int size = vob->GetSize();
		if (size>=1024)
		  text += wxString::Format(_(" (%dMB)"), size/1024);
		else if (size > 0)
		  text += wxString::Format(_(" (%dKB)"), size);
	  }
	}
  }
  m_statusbar->SetStatusText(text, 0);
}

void MainWin::OnMenuObjectInfo(wxCommandEvent& event)
{
  wxString text;
  wxString objId = m_menuEditor->GetPointed();
  if (objId.length())
  {
	MenuObject* obj = m_menuEditor->GetMenu()->GetObject(objId);
    text = obj->GetId();
    if (obj->IsButton())
      text = _("button") + wxString(wxT(" ")) + text.Mid(7) + wxT(": ") +
        obj->GetAction();
    else
      text = _("object") + wxString(wxT(" ")) + text.Mid(3);
  }
  m_statusbar->SetStatusText(text, 0);
}

void MainWin::OnThumbDoubleClick(wxCommandEvent& event)
{
  if (m_thumbnails->GetSelected() == -1)
    return;
  wxString filename = m_thumbnails->GetSelectedItem()->GetFilename();
  if (wxImage::FindHandler(filename.AfterLast(wxT('.')).Lower(), -1) ||
      MPEG::IsValid(filename))
    m_menuEditor->SetBackground(filename);
}

void MainWin::OnSetBackground(wxCommandEvent& event)
{
  wxString filename = m_thumbnails->GetSelectedItem()->GetFilename();
  m_menuEditor->SetBackground(filename);
}

void MainWin::OnUpdateUISetBackground(wxUpdateUIEvent& event)
{
  if (m_thumbnails->GetSelected() == -1)
    event.Enable(false);
  else
  {
    wxString filename = m_thumbnails->GetSelectedItem()->GetFilename();
    event.Enable(
      wxImage::FindHandler(filename.AfterLast(wxT('.')).Lower(), -1) ||
      MPEG::IsValid(filename));
  }
}

void MainWin::OnSplitterTitleSash(wxSplitterEvent &event)
{
  int width, height;
  GetClientSize(&width, &height);
  m_splitterTitleSash = height - m_splitterTitle->GetSashPosition();
}

void MainWin::OnResize(wxSizeEvent &event)
{
  wxFrame::OnSize(event);
  if (m_splitterTitle)
  {
    int width, height;
	GetClientSize(&width, &height);
	m_splitterTitle->SetSashPosition(height - m_splitterTitleSash);
  }
}

void MainWin::OnClose(wxCloseEvent &event)
{
  if (!TestSaved())
	return;
  s_config.SetMainWinLocation(GetRect());
  Destroy();
}

void MainWin::NewDVD(wxString volumeName, VideoFormat videoFormat, AudioFormat audioFormat)
{
  if (m_dvd)
    delete m_dvd;
  m_dvd = new DVD;
  m_dvd->SetName(volumeName);
  m_dvd->SetVideoFormat(videoFormat);
  m_dvd->SetAudioFormat(audioFormat);
  m_dvd->AddTitleset();
  m_dvd->AddMenu(videoFormat, 0);
  m_filename = _T("");
  UpdateDVD();
  SetChanged(false);
}

void MainWin::Open(wxString filename)
{
  DVD* dvd = new DVD;
  if (dvd->Open(filename))
  {
    delete m_dvd;
    m_dvd = dvd;
    m_filename = filename;
    m_lastDir = wxPathOnly(m_filename);
    s_config.SetLastProjectDir(m_lastDir);
	UpdateDVD();
	SetChanged(false);
  }
  else
  {
	delete dvd;
    wxLogError(_("Error opening '%s'"), filename.c_str());
  }
}

void MainWin::UpdateDVD()
{
  m_titlesetManager->SetDVD(m_dvd);
  m_titlesetManager->UpdateItems();
  m_titlesetManager->SelectFirstMenu();
}


void MainWin::SetChanged(bool changed)
{
  m_changed = changed;
  m_toolbar->EnableTool(wxID_SAVE, changed);
  m_menubar->GetMenu(0)->Enable(wxID_SAVE, changed);
  wxString fname = m_filename;
  if (!fname.length())
	fname = _("Untitled");
  SetTitle(_T("DVDStyler - ") + fname +
    (m_changed || !m_filename.length() ? _T("*") : _T("")));
}

void MainWin::OnChangedMenu(wxCommandEvent& event)
{
  SetChanged(true);
  if (m_titlesetManager->GetSelectedMenu()<0)
	return;
  m_titlesetManager->GetItem(m_titlesetManager->GetSelectedMenu())->Update();
  m_titlesetManager->Refresh();
}

void MainWin::OnSelectMenu(wxCommandEvent& event)
{
  bool changed = GetChanged();
  int tsi = 0;
  int pgci = 0;
  if (m_titlesetManager->GetSelectedMenu()>=0)
  {
    int id = m_titlesetManager->GetSelectedMenuId();
    tsi = DVD::GetTsi(id);
    pgci = DVD::GetPgci(id);
  }
  Menu* menu = m_dvd->GetMenu(tsi, pgci);
  m_menuEditor->SetMenu(m_dvd, menu, tsi, pgci);
  m_menuEditor->Update();
  SetChanged(changed);
}

void MainWin::OnChangedDVD(wxCommandEvent& event)
{
  SetChanged(true);
  m_statusbar->SetStatusText(wxString::Format(_("Total size: %dMB"),
    m_dvd->GetSize()/1024), 1);
}

bool MainWin::TestSaved()
{
  if (m_changed)
  {
	wxString fname = m_filename;
	if (!fname.length())
	  fname = _("Untitled");
	int save = wxMessageBox(
	  wxString::Format(_("The file '%s' was modified, save changes?"), fname.c_str()),
	  _("Confirm"), wxYES_NO|wxCANCEL|wxICON_QUESTION, this);
	if (save == wxYES)
	{
	  wxCommandEvent event;
	  OnSave(event);
	  if (m_changed)
		return false;
	}
	else if (save == wxCANCEL)
	  return false;
  }
  return true;
}

void MainWin::OnNew(wxCommandEvent& event)
{
  if (!TestSaved())
    return;
  NewProjectDlg dialog(this);
  if (dialog.ShowModal() == wxID_OK)
	NewDVD(dialog.GetVolumeName(), dialog.GetVideoFormat(), dialog.GetAudioFormat());
}

void MainWin::OnOpen(wxCommandEvent& event)
{
  if (!TestSaved())
	return;
  wxFileDialog dlg( this, _("Open a DVDStyler project file"), m_lastDir,
	_T(""), _T("*.xml"), wxOPEN);
  dlg.Centre();
  if (dlg.ShowModal() == wxID_OK)
	Open(dlg.GetPath());
}

void MainWin::OnSave(wxCommandEvent& event)
{
  if (m_filename.length())
  {
	if (m_dvd->Save(m_filename))
	  SetChanged(false);
  }
  else
	OnSaveAs(event);
}

void MainWin::OnSaveAs(wxCommandEvent& event)
{
  if (m_dvd->GetTitlesets().Count() ||
      m_dvd->GetVmgm().Count())
  {
	wxFileDialog dlg(this, _("Save a DVDStyler project file"), m_lastDir,
	  _T("dvd.xml"), _T("*.xml"), wxSAVE | wxOVERWRITE_PROMPT);
	dlg.Centre();
	if (dlg.ShowModal() == wxID_OK)
	{
	  m_filename = dlg.GetPath();
	  m_lastDir = wxPathOnly(m_filename);
	  s_config.SetLastProjectDir(m_lastDir);
	  if (m_dvd->Save(m_filename))
		SetChanged(false);
	}
  }
  else
	wxLogError(_("Nothing to save"));
}

void MainWin::OnBurn(wxCommandEvent& event)
{
  int vobcnt = 0;
  for (int tsi = 0; tsi<(int)m_dvd->GetTitlesets().Count(); tsi++)
  {
	Titleset* ts = m_dvd->GetTitlesets()[tsi];
	for (int pgci = 0; pgci<(int)ts->GetTitles().Count(); pgci++)
	{
	  if (ts->GetTitles()[pgci]->GetVobs().Count()>0)
	  {
		vobcnt = 1;
		break;
	  }
	}
  }
  // check if user added some titles
  if (vobcnt == 0) {
	wxMessageBox(
	  _("There are no titles specified. To add a title please drag\n a video file into the bottom section of the window."),
	  _("Burn"), wxOK|wxICON_ERROR, this);
	return;
  }
  // check if the last title doesn't contain only video
  PgcArray& pgcs = m_dvd->GetTitlesets().Last()->GetTitles();
  Pgc* pgc = pgcs.Count()>0 ? pgcs.Last() : NULL;
  Vob* vob = pgc && pgc->GetVobs().Count()>0 ? pgc->GetVobs().Last() : NULL;
  if (vob && vob->GetVideoFilename().length() && !vob->GetAudioFilenames().Count()) {
	  wxMessageBox(wxString(_("The last title isn't complete.\n")) +
			  _("Please add an audio track to it."),
			  _("Burn"), wxOK|wxICON_ERROR, this);
	  return;
  }
  
  KeyDlg keyDlg(this);
  if (keyDlg.ShowModal() != wxID_OK)
	return;
  
  BurnDlg burnDlg(this);
  if (burnDlg.ShowModal() != wxID_OK)
	return;
  
  // Progress dialog
  ProgressDlg progressDlg(this);
  progressDlg.Start(&burnDlg, m_dvd);
}

void MainWin::OnExit(wxCommandEvent& event)
{
  Close(true);
}

void MainWin::OnAddMenu(wxCommandEvent& WXUNUSED(event))
{
  m_titlesetManager->SetSelected(-1);
  m_titlesetManager->AddMenu();
}

void MainWin::OnAddVmMenu(wxCommandEvent& WXUNUSED(event))
{
  m_titlesetManager->AddVmMenu();
}

void MainWin::OnAddTitleset(wxCommandEvent& WXUNUSED(event))
{
  m_titlesetManager->AddTitleset();
}

void MainWin::OnAddTitlesetUpdateUI(wxUpdateUIEvent& event)
{
  int cnt = m_dvd->GetTitlesets().Count();
  event.Enable(cnt>0 &&	m_dvd->GetTitlesets()[cnt-1]->GetTitles().Count());
}

void MainWin::OnDVDOptions(wxCommandEvent& event)
{
  DVDPropDlg dlg(this, m_dvd);
  if (dlg.ShowModal() == wxID_OK) {
	SetChanged(true);
	m_menuEditor->Update();
	m_titlesetManager->UpdateItems();
  }
}

void MainWin::OnSettings(wxCommandEvent& event)
{
  SettingsDlg dlg(this);
  dlg.ShowModal();
}

void MainWin::OnAbout(wxCommandEvent& WXUNUSED(event))
{
  About(this);
}
