/////////////////////////////////////////////////////////////////////////////
// Name:        MenuObjectPropDlg.cpp
// Purpose:     DVD menu button properties dialog
// Author:      Alex Thuering
// Created:	20.11.2003
// RCS-ID:      $Id: MenuObjectPropDlg.cpp,v 1.15 2008/03/02 18:59:37 ntalex Exp $
// Copyright:   (c) Alex Thuering
// Licence:     GPL
/////////////////////////////////////////////////////////////////////////////
 
#include "MenuObjectPropDlg.h"
#include <wx/statline.h>
#include <wx/tokenzr.h>
#include <stdint.h>

enum
{
  JUMP_ACTION_RADIO_ID = 7900,
  CUSTOM_ACTION_RADIO_ID,
  TSI_CHOICE_ID,
  PGCI_CHOICE_ID,
  AUTO_SIZE_RADIO_ID,
  CUSTOM_SIZE_RADIO_ID,
  IMAGE_RADIO_ID,
  VIDEOFRAME_RADIO_ID,
  VIDEOFRAME_CHOICE_ID
};

BEGIN_EVENT_TABLE(MenuObjectPropDlg, wxPropDlg)
	EVT_RADIOBUTTON(JUMP_ACTION_RADIO_ID, MenuObjectPropDlg::OnJumpActionSelected)
	EVT_RADIOBUTTON(CUSTOM_ACTION_RADIO_ID, MenuObjectPropDlg::OnCustomActionSelected)
	EVT_RADIOBUTTON(AUTO_SIZE_RADIO_ID, MenuObjectPropDlg::OnDefaultSizeSelected)
	EVT_RADIOBUTTON(CUSTOM_SIZE_RADIO_ID, MenuObjectPropDlg::OnCustomSizeSelected)
	EVT_CHOICE(TSI_CHOICE_ID, MenuObjectPropDlg::OnChangeTitleset)
	EVT_CHOICE(PGCI_CHOICE_ID, MenuObjectPropDlg::OnChangeTarget)
	EVT_CHOICE(VIDEOFRAME_CHOICE_ID, MenuObjectPropDlg::OnSelectVideoFrame)
END_EVENT_TABLE()

MenuObjectPropDlg::MenuObjectPropDlg(wxWindow* parent,
  wxString id, Menu* menu, DVD* dvd, int tsi, int pgci):
    wxPropDlg(parent), m_id(id), m_menu(menu), m_dvd(dvd),
    m_tsi(tsi), m_pgci(pgci), m_videoFrameRadio(NULL)
{
  m_object = menu->GetObject(id);
  Create();
}

void MenuObjectPropDlg::CreatePropPanel(wxSizer* sizer)
{
  wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
  wxFlexGridSizer* grid = NULL;
  
  // action
  if (m_object->IsButton())
  {
    AddStaticLine(mainSizer, _("Action"));
    grid = new wxFlexGridSizer(2, 2, 4, 16);
    grid->AddGrowableCol(1);
    AddRadioProp(grid, _("Jump to"), !m_object->HasCustomAction(), wxRB_GROUP,
      false, JUMP_ACTION_RADIO_ID);
    wxBoxSizer* jumpSizer = new wxBoxSizer(wxHORIZONTAL);
    AddChoiceProp(jumpSizer, wxT(""), wxT(""), wxArrayString(), -1, true, TSI_CHOICE_ID);
    m_titlesetChoice = (wxChoice*) m_controls[m_controls.Count()-1];
    UpdateTitlesets();
    AddChoiceProp(jumpSizer, wxT(""), wxT(""), wxArrayString(), -1, true, PGCI_CHOICE_ID);
    m_targetChoice = (wxChoice*) m_controls[m_controls.Count()-1];
    UpdateTargets();
    AddChoiceProp(jumpSizer, wxT(""), wxT(""), wxArrayString());
    m_chapterChoice = (wxChoice*) m_controls[m_controls.Count()-1];
    UpdateChapters();
    jumpSizer->Add(16,8);
    AddCheckProp(jumpSizer, _("Play All"), m_object->IsPlayAll());
    grid->Add(jumpSizer);
    
    wxString customAction = m_object->GetCustomAction();
    if (!customAction.length())
    {
      // check if selection was ok, otherwise set this action as custom action
      int tsi = m_object->GetActionTsi() > -2 ? m_object->GetActionTsi() : m_tsi;
      if (GetTsi() != tsi || GetPgci() != m_object->GetActionPgci() ||
          GetChapter() != m_object->GetActionChapter())
        customAction = m_object->GetAction();
    }
    AddRadioProp(grid, _("Custom"), customAction.length(), 0,
      false, CUSTOM_ACTION_RADIO_ID);
    AddTextProp(grid, wxT(""), customAction);
    m_customActionEdit = (wxTextCtrl*) m_controls[m_controls.Count()-1];
    mainSizer->Add(grid, 0, wxEXPAND|wxBOTTOM, 8);
    wxCommandEvent evt;
    if (customAction.length())
      OnCustomActionSelected(evt);
    else
      OnJumpActionSelected(evt);
    
    grid = new wxFlexGridSizer(3, 4, 4, 16);
    grid->AddGrowableCol(0);
    grid->Add(10,10); AddText(grid, _("Focus")); AddDirectionProp(grid, bdUP);   grid->Add(10,10);
    grid->Add(10,10); AddDirectionProp(grid, bdLEFT); grid->Add(10,10); AddDirectionProp(grid, bdRIGHT);
    grid->Add(10,10); grid->Add(10,10); AddDirectionProp(grid, bdDOWN); grid->Add(10,10);
    mainSizer->Add(grid, 0, wxEXPAND|wxALL, 10);
  }
  
  // object look parameters
  if (m_object->GetObjectParamsCount()>0)
    AddStaticLine(mainSizer, _("Look"));
  bool lastChangeable = false;
  for (int i=0; i<m_object->GetObjectParamsCount(); i++)
  {
    MenuObjectParam* param = m_object->GetObjectParam(i);
    
    if (i == 0 || param->changeable != lastChangeable)
    {
      if (param->changeable)
      {
        grid = new wxFlexGridSizer(3, 4, 4, 16);
        AddText(grid, wxT(""));
        AddText(grid, _("Normal"));
        AddText(grid, _("Highlighted"));
        AddText(grid, _("Selected"));
      }
      else
      {
        grid = new wxFlexGridSizer(2, 4, 16);
        grid->AddGrowableCol(1);
      }
      if (i==0)
        mainSizer->Add(grid, 0, wxEXPAND|wxTOP|wxBOTTOM, 8);
      else
        mainSizer->Add(grid, 0, wxEXPAND|wxBOTTOM, 8);
      lastChangeable = param->changeable;
    }
    
    wxString title = wxGetTranslation((const wxChar*)param->title.GetData()) + wxString(wxT(":"));
    
    if (param->changeable && param->type == _T("colour"))
    {
      AddColourProp(grid, title, m_object->GetParamColour(param->name));
      AddColourProp(grid, wxT(""), m_object->GetParamColour(param->name, mbsHIGHLIGHTED));
      AddColourProp(grid, wxT(""), m_object->GetParamColour(param->name, mbsSELECTED));
    }
    else
    {
      if (param->type == _T("text"))
      {
        AddText(grid, title);
        wxBoxSizer* sizer2 = new wxBoxSizer(wxHORIZONTAL);
        AddTextProp(sizer2, wxT(""), m_object->GetParam(param->name));
        AddFontProp(sizer2, wxT(""), m_object->GetParamFont(param->name), _("Font..."));
        grid->Add(sizer2, 0, wxEXPAND);
      } else if (param->type == _T("string")) {
        AddTextProp(grid, title, m_object->GetParam(param->name));
      } else if (param->type == _T("decimal")) {
        AddTextProp(grid, title, m_object->GetParam(param->name), false, 100);
      } else if (param->type.Mid(0,7) == _T("integer")) {
        long min = 0, max = 999;
        if (param->type.Find(wxT('(')) != -1 && param->type.Find(wxT(')')) != -1)
        {
          param->type.AfterFirst(wxT('(')).BeforeFirst(wxT(',')).Strip(wxString::both).ToLong(&min);
          param->type.BeforeFirst(wxT(')')).AfterFirst(wxT(',')).Strip(wxString::both).ToLong(&max);
        }
        AddSpinProp(grid, title, m_object->GetParamInt(param->name), min, max,
        		max < 1000 ? 54 : 80);
      } else if (param->type == _T("image")) {
    	  wxString imageFile = m_object->GetParam(param->name);
    	  if (m_object->IsButton()) {
	          bool hasVideo = GetVideoFilename().length();
	          wxString fname = imageFile.Find(wxT('#')) != -1 ? imageFile.BeforeLast(wxT('#')) : imageFile;
	          bool image = !hasVideo || fname != GetVideoFilename();
	          AddRadioProp(grid, wxString(_("Image")) + wxT(":"), image, wxRB_GROUP, false, IMAGE_RADIO_ID);
	          AddFileProp(grid, wxT(""), image ? imageFile : wxT(""), wxFD_OPEN, wxT("..."),
	    		_("Image Files ") + wxImage::GetImageExtWildcard()
	     		+ wxT("|") + wxString(_("All Files")) + wxT(" (*.*)|*.*"));
	          AddRadioProp(grid, wxString(_("Video Frame")) + wxT(":"), !image, 0, false, VIDEOFRAME_RADIO_ID);
	          m_videoFrameRadio = (wxRadioButton*) m_controls[m_controls.Count()-1];
	          if (!hasVideo)
	            m_videoFrameRadio->Enable(false);
	          bool videoFrameAuto = imageFile == GetVideoFilename(true);
	          const wxString frameChoices[] = { _("Auto"), _("Custom")};
	          wxSizer* frameSizer = AddChoiceProp(grid, wxT(""), frameChoices[videoFrameAuto ? 0 : 1],
	        		  wxArrayString(2, frameChoices), 100, false, VIDEOFRAME_CHOICE_ID);
	          ((wxWindow*) m_controls[m_controls.Count()-1])->SetName(
	        		  wxString::Format(wxT("%d"), m_controls.Count()-1));
	          frameSizer->AddSpacer(4);
	          long videoFrame = 0;
	          if (!image) {
	        	  wxString vf = imageFile.Find(wxT('#')) != -1 ? imageFile.AfterLast(wxT('#')) : wxT("");
	        	  if (vf.length() > 0)
	        		  vf.ToLong(&videoFrame);
	          }
	          wxSizer* frameSizer2 = AddSpinProp(frameSizer, wxT(""), videoFrame, 0, 9999999, 100, false);
	          ((wxWindow*) m_controls[m_controls.Count()-1])->SetName(
	        		  wxString::Format(wxT("videoFrame_%d"), m_controls.Count()-2));
	          ((wxWindow*) m_controls[m_controls.Count()-1])->Enable(!videoFrameAuto);
	          frameSizer2->AddSpacer(4);
	          AddText(frameSizer2, wxT("ms"));
	          frameSizer2->Add(0, 0, 1, wxEXPAND);
	      } else
	    	  AddFileProp(grid, title, imageFile, wxFD_OPEN,
	        		wxT("..."), _("Image Files ") + wxImage::GetImageExtWildcard()
	        		+ wxT("|") + wxString(_("All Files")) + wxT(" (*.*)|*.*"));
      }
      else if (param->type == _T("colour")) {
    	  int opacity = 100;
    	  wxString opacityStr = m_object->GetParam(param->name, wxT("-opacity"));
    	  if (opacityStr.length() > 0) {
    		  double dval;
    		  opacityStr.ToDouble(&dval);
    		  opacity = (int) (dval*100);
    	  }
    	  AddColourProp(grid, title, m_object->GetParamColour(param->name), opacity);
      }
    }
  }
  
  // object location
  AddStaticLine(mainSizer, _("Location and size"));
  grid = new wxFlexGridSizer(1, 4, 4, 16);
  AddSpinProp(grid, _("x:"), m_object->GetX(), 0, m_menu->GetResolution().GetWidth()-8);
  AddSpinProp(grid, _("y:"), m_object->GetY(), 0, m_menu->GetResolution().GetHeight()-8);
  mainSizer->Add(grid, 0, wxEXPAND|wxBOTTOM, 8);
  
  // object size
  grid = new wxFlexGridSizer(2, 6, 4, 16);
  grid->AddGrowableCol(5);
  AddRadioProp(grid, _("Default width and height"), m_object->IsDefaultSize(),
    wxRB_GROUP, false, AUTO_SIZE_RADIO_ID);
  grid->Add(10,10); grid->Add(10,10); grid->Add(10,10); grid->Add(10,10); grid->Add(10,10);
  AddRadioProp(grid, _("Custom"), !m_object->IsDefaultSize(), 0,
    false, CUSTOM_SIZE_RADIO_ID);
  AddSpinProp(grid, _("width:"), m_object->GetWidth(), 0, m_menu->GetResolution().GetWidth());
  m_widthEdit = (wxTextCtrl*) m_controls[m_controls.Count()-1];
  AddSpinProp(grid, _("height:"), m_object->GetHeight(), 0, m_menu->GetResolution().GetHeight());
  m_heightEdit = (wxTextCtrl*) m_controls[m_controls.Count()-1];
  grid->Add(10,10);
  mainSizer->Add(grid, 0, wxEXPAND|wxBOTTOM, 8);
  wxCommandEvent evt;
  if (m_object->IsDefaultSize())
    OnDefaultSizeSelected(evt);
  else
    OnCustomSizeSelected(evt);
  
  mainSizer->Add(10, 10, 1, wxEXPAND);
  sizer->Add(mainSizer, 1, wxEXPAND|wxALL, 10);
}

int MenuObjectPropDlg::GetTsi()
{
  if (m_titlesetChoice->GetSelection() >= 0)
    return ((intptr_t) m_titlesetChoice->GetClientData(m_titlesetChoice->GetSelection()))-1;
  return 0;
}

int MenuObjectPropDlg::GetPgci()
{
  if (m_targetChoice->GetSelection() >= 0)
    return (intptr_t) m_targetChoice->GetClientData(m_targetChoice->GetSelection());
  return 0;
}

int MenuObjectPropDlg::GetChapter()
{
  if (m_chapterChoice->GetSelection() >= 0)
    return m_chapterChoice->GetSelection();
  return 0;
}

void MenuObjectPropDlg::UpdateTitlesets()
{
  int sel = 0;
  wxChoice* ctrl = m_titlesetChoice;
  int tsi = m_object->GetActionTsi() > -2 ? m_object->GetActionTsi() : m_tsi;
  ctrl->Clear();
  if (m_dvd->GetVmgm().GetCount()>0)
	ctrl->Append(_("video manager"), (void*) 0);
  for (int i=0; i<(int)m_dvd->GetTitlesets().Count(); i++)
  {
    if (!m_dvd->IsJumppadsEnabled() && m_tsi >= 0 && i != m_tsi)
      continue;
    ctrl->Append(wxString::Format(_("titleset %d"), i+1), (void*) (i+1));
    if (i == tsi)
      sel = ctrl->GetCount()-1; 
  }
  ctrl->SetSelection(sel);
  ctrl->Enable(ctrl->GetCount()>1);
}

void MenuObjectPropDlg::UpdateTargets()
{
  int sel = 0;
  wxChoice* ctrl = m_targetChoice;
  int tsi = GetTsi();
  int pgci = ctrl->GetCount() ? GetPgci() : m_object->GetActionPgci();
  ctrl->Clear();
  PgcArray& pgcs = m_dvd->GetPgcArray(tsi, true);
  for (int i=0; i<(int)pgcs.Count(); i++)
  {
    if (!m_dvd->IsJumppadsEnabled() && m_tsi==-1 && tsi>=0 && i>0)
      continue;
    ctrl->Append(wxString::Format(_("menu %d"), i+1), (void*) (i*2));
    if (i*2 == pgci)
      sel = ctrl->GetCount()-1;
  }
  if (tsi>=0 && (m_dvd->IsJumppadsEnabled() || m_tsi>=0))
  {
    PgcArray& pgcs = m_dvd->GetPgcArray(tsi, false);
    for (int i=0; i<(int)pgcs.Count(); i++)
    {
      ctrl->Append(wxString::Format(_("title %d"), i+1), (void*) (i*2+1));
      if (i*2+1 == pgci)
        sel = ctrl->GetCount()-1;
    }
  }
  ctrl->SetSelection(sel);
  if (m_videoFrameRadio)
    m_videoFrameRadio->Enable(GetVideoFilename().length());
}

void MenuObjectPropDlg::UpdateChapters()
{
  wxChoice* ctrl = m_chapterChoice;
  int tsi = GetTsi();
  int pgci = GetPgci();
  int chapter = ctrl->GetCount() ? GetChapter() : m_object->GetActionChapter();
  ctrl->Clear();
  ctrl->Append(wxString::Format(_("chapter %d"), 1));
  if (tsi>=0 && pgci%2 == 1)
  {
    PgcArray& pgcs = m_dvd->GetPgcArray(tsi, false);
    if (pgci/2 < (int)pgcs.Count())
    {
      Pgc& pgc = *pgcs[pgci/2];
      for (int i=0; i<(int)pgc.GetVobs().Count(); i++)
      {
        Vob& vob = *pgc.GetVobs()[i];
        if (vob.GetSlideshow())
        {
          for (int i=0; i<(int)vob.GetSlideshow()->Count()-1; i++)
            ctrl->Append(wxString::Format(_("chapter %d"), ctrl->GetCount()+1));
        }
        else
        {
          wxStringTokenizer tkz(vob.GetChapters(), _T(","));
          while (tkz.HasMoreTokens())
          {
            wxString token = tkz.GetNextToken();
            if (token != _T("0"))
              ctrl->Append(wxString::Format(_("chapter %d"), ctrl->GetCount()+1));
          }
        }
      }
    }
  }
  ctrl->SetSelection(chapter);
  ctrl->Enable(ctrl->GetCount()>1);
  if (m_videoFrameRadio)
    m_videoFrameRadio->Enable(GetVideoFilename().length());
}

void MenuObjectPropDlg::OnJumpActionSelected(wxCommandEvent& WXUNUSED(evt))
{
  m_titlesetChoice->Enable(m_titlesetChoice->GetCount()>1);
  m_targetChoice->Enable(true);
  m_chapterChoice->Enable(m_chapterChoice->GetCount()>1);
  m_customActionEdit->Enable(false);
}

void MenuObjectPropDlg::OnCustomActionSelected(wxCommandEvent& WXUNUSED(evt))
{
  m_titlesetChoice->Enable(false);
  m_targetChoice->Enable(false);
  m_chapterChoice->Enable(false);
  m_customActionEdit->Enable(true);
  if (m_customActionEdit->GetValue().length() == 0)
  {
    int tsi = m_object->GetActionTsi();
    m_object->SetActionTsi(GetTsi() != m_tsi ? GetTsi() : -2);
    m_customActionEdit->SetValue(m_object->GetAction());
    m_object->SetActionTsi(tsi);
  }
}

wxString MenuObjectPropDlg::GetVideoFilename(bool withTimestamp, long position)
{
  if (!GetBool(0))
    return wxT("");
  if (GetPgci() % 2 == 0)
    return wxT("");
  Vob* vob = m_dvd->GetVob(GetTsi(), false, GetPgci()/2, 0);
  if (!vob)
	  return wxT("");
  if (!withTimestamp)
	  return vob->GetVideoFrameUri(-1);
  return vob->GetVideoFrameUri(GetChapter(), position);
}

void MenuObjectPropDlg::OnSelectVideoFrame(wxCommandEvent& evt) {
	long idx = 0;
	((wxWindow*)evt.GetEventObject())->GetName().ToLong(&idx);
	wxWindow* videoFrameSpin = this->FindWindowByName(
			wxString::Format(wxT("videoFrame_%d"), idx));
	videoFrameSpin->Enable(evt.GetSelection() == 1);
}

void MenuObjectPropDlg::OnDefaultSizeSelected(wxCommandEvent& WXUNUSED(evt)) {
	m_widthEdit->Enable(false);
	m_heightEdit->Enable(false);
}

void MenuObjectPropDlg::OnCustomSizeSelected(wxCommandEvent& WXUNUSED(evt)) {
	m_widthEdit->Enable(true);
	m_heightEdit->Enable(true);
}


void MenuObjectPropDlg::AddStaticLine(wxSizer* sizer, wxString caption)
{
  wxBoxSizer* sizer2 = new wxBoxSizer(wxHORIZONTAL);
  wxStaticText* staticText = new wxStaticText(this, -1, caption);
  staticText->SetFont(wxFont(12, wxDEFAULT, wxNORMAL, wxBOLD, 0, _T("")));
  sizer2->Add(staticText, 0, wxRIGHT|wxTOP|wxBOTTOM, 5);
  sizer2->Add(new wxStaticLine(this, -1), 1, wxALIGN_CENTER_VERTICAL, 5);
  sizer->Add(sizer2, 0, wxEXPAND, 0);
}

void MenuObjectPropDlg::AddDirectionProp(wxSizer* sizer, ButtonDirCommand dir)
{
  wxFlexGridSizer* grid = new wxFlexGridSizer(2, 1, 4, 16);
  AddChoiceProp(grid, wxT(""), wxT(""), wxArrayString());
  wxChoice* ctrl = (wxChoice*) m_controls[m_controls.Count()-1];
  
  // add all buttons except current
  ctrl->Append(_("auto"), new wxString);
  int sel = 0;
  for (int i=0; i<m_menu->GetObjectsCount(); i++)
  {
    MenuObject* obj = m_menu->GetObject(i);
    if (obj->IsButton() && obj != m_object)
    {
      wxString id = obj->GetId();
      if (m_object->GetDirection(dir-bdLEFT) == id)
        sel = ctrl->GetCount();
      wxString text = _("button") + wxString::Format(wxT(" ")) + id.Mid(7);
      if (obj->GetParam(wxT("text")).length())
        text += wxT(": ") + obj->GetParam(_T("text"));
      ctrl->Append(text, new wxString(id));
    }
  }
  for (int i=0; i<m_menu->GetActionsCount(); i++)
  {
    MenuAction* action = m_menu->GetAction(i);
    wxString id = action->GetId();
    if (m_object->GetDirection(dir-bdLEFT) == id)
       sel = ctrl->GetCount();
    ctrl->Append(id, new wxString(id));
  }
  ctrl->SetSelection(sel);
  ctrl->SetSizeHints(ctrl->GetSize().GetWidth()*3/2, -1, ctrl->GetSize().GetWidth()*3/2, -1);
  sizer->Add(grid, 0, 0, 0);
}

bool MenuObjectPropDlg::SetValues()
{
  // check Action
  if (m_object->IsButton())
  {
    if (!m_dvd->IsJumppadsEnabled() && m_tsi<0 && GetString(0).Find(_T("chapter"))>=0)
    {
      wxMessageBox(_("You cannot jump from vmgMenu to a chapter."),
        GetTitle(), wxOK|wxICON_ERROR, this);
      return false;
    }
    if (GetBool(5) && GetString(6).length() == 0) // empty custom action
    {
      wxMessageBox(_("Please enter the action command."),
        GetTitle(), wxOK|wxICON_ERROR, this);
      return false;
    }
  }
  
  int n = 0;
  
  // set action
  if (m_object->IsButton())
  {
    n++;
    int tsi = ((intptr_t)GetClientData(n++))-1;
    m_object->SetActionTsi(tsi != m_tsi ? tsi : -2);
    m_object->SetActionPgci((intptr_t)GetClientData(n++));
    m_object->SetActionChapter(GetInt(n++));
    m_object->SetPlayAll(GetBool(n++));
    if (GetBool(n++))
    {
      if (GetString(n) == wxT("jump title 1;"))
      {
        m_object->SetActionTsi(-2);
        m_object->SetActionPgci(1);
        m_object->SetActionChapter(0);
        m_object->SetCustomAction(_T(""));
      }
      else
        m_object->SetCustomAction(GetString(n));
    }
    else
      m_object->SetCustomAction(_T(""));
    n++;
    
    wxString* id = (wxString*) GetClientData(n++);
    m_object->SetDirection(2, *id);
    delete id;
    id = (wxString*) GetClientData(n++);
    m_object->SetDirection(0, *id);
    delete id;
    id = (wxString*) GetClientData(n++);
    m_object->SetDirection(1, *id);
    delete id;
    id = (wxString*) GetClientData(n++);
    m_object->SetDirection(3, *id);
    delete id;
  }
  
  // set look parameters
  for (int i=0; i<m_object->GetObjectParamsCount(); i++)
  {
    MenuObjectParam* param = m_object->GetObjectParam(i);
    if (param->changeable && param->type == _T("colour"))
    {
      m_object->SetParamColour(param->name, GetColour(n++));
      m_object->SetParamColour(param->name, GetColour(n++), mbsHIGHLIGHTED);
      m_object->SetParamColour(param->name, GetColour(n++), mbsSELECTED);
    }
    else
    {
      if (param->type == _T("text"))
      {
        m_object->SetParam(param->name, GetString(n++));
        m_object->SetParamFont(param->name, GetFont(n++).GetChosenFont());
      }
      else if (param->type == _T("string") || param->type == _T("decimal"))
        m_object->SetParam(param->name, GetString(n++));
      else if (param->type.Mid(0,7) == _T("integer"))
        m_object->SetParamInt(param->name, GetInt(n++));
      else if (param->type == _T("colour")) {
        m_object->SetParamColour(param->name, GetColour(n++));
        wxString opacity = wxString::Format(wxT("%g"), (double)GetInt(n++)/100);
        m_object->SetParam(param->name, opacity, wxT("-opacity"));
      }
      else if (param->type == _T("image"))
      {
        if (m_object->IsButton())
        {
          bool image = GetBool(n++);
          wxString imgFile = GetString(n++);
          n++;
          if (!image) {
        	  int videoFrame = -1;
        	  if (GetInt(n++) == 1) // custom frame
        		  videoFrame = GetInt(n++);
        	  else
        		  n++;
        	  imgFile = GetVideoFilename(true, videoFrame);
          } else
        	  n += 2;
          m_object->SetParam(param->name, imgFile);
        }
        else
          m_object->SetParam(param->name, GetString(n++));
      }
    }
  }
  
  // set position
  m_object->SetX(GetInt(n++));
  m_object->SetY(GetInt(n++));
  
  // set size
  m_object->SetDefaultSize(GetBool(n++));
  if (!m_object->IsDefaultSize())
  {
    // set size manual by user
    n++;
    m_object->SetWidth(GetInt(n++));
    m_object->SetHeight(GetInt(n++));
  }
  m_object->UpdateSize();
  
  return true;
}
