/// McPanel.cpp
/** Main user interface within McFrame.
*/

#if defined(__WXGTK__) || defined(__WXMOTIF__)
  #include <wx/wx.h>
#endif

#include <wx/wxprec.h>
#include <wx/statline.h>
#include <wx/treectrl.h>
#include <wx/dir.h>
#include <wx/config.h>
#include <wx/timer.h>
#include <wx/busyinfo.h>
#include <wx/progdlg.h>
#include <wx/spinctrl.h>
#include <wx/filename.h>
#include <wx/filedlg.h>
#include <wx/dirdlg.h>

#include <map>
#include <algorithm>

#include "MRIConvert.h"
#include "Converter.h"
#include "DicomTree.h"
#include "InfoFrame.h"
#include "DicomViewer.h"
#include "ImageView.h"
#include "OutputFactory.h"
#include "McPanel.h"
#include "MessageList.h"
#include "OutputterBase.h"
#include "NewSpmOutputter.h"
#include "NewMetaOutputter.h"
#include "NewBvOutputter.h"
#include "NiftiOutputter.h"
#include "AnalyzeOutputter.h"
#include "NoOptionsDlg.h"
#include "BvOptionsDlg.h"
#include "BasicOptionsDlg.h"
#include "AnalyzeOptionsDlg.h"
#include "NiftiOptionsDlg.h"
#include "SpmOptionsDlg.h"
#include "MetaOptionsDlg.h"
#include "OverrideDlg.h"
#include "ConfigValues.h"

using namespace jcs;

wxDEFINE_EVENT(DROP_EVENT, wxCommandEvent);

BEGIN_EVENT_TABLE(McPanel, wxPanel)

EVT_BUTTON(COMMAND_NEW,               McPanel::OnNew)
EVT_BUTTON(COMMAND_ADD_FILES,         McPanel::OnAddFiles)
EVT_BUTTON(COMMAND_ADD_DIR,           McPanel::OnAddDir)
EVT_BUTTON(COMMAND_DIRECTORY,         McPanel::OnDirectory)
EVT_BUTTON(COMMAND_CONVERT,           McPanel::OnConvert)
EVT_BUTTON(COMMAND_REMOVE,            McPanel::OnRemove)
EVT_BUTTON(COMMAND_RENAME,            McPanel::OnRename)
EVT_BUTTON(COMMAND_OPTIONS,           McPanel::OnOptions)
EVT_BUTTON(wxID_EXIT,                 McPanel::OnQuit)

EVT_CHOICE(CHOICE_OUTPUT,             McPanel::OnChoiceOutput)

EVT_TREE_SEL_CHANGED(SOURCE_CTRL,     McPanel::OnSourceSelect)
EVT_TREE_SEL_CHANGED(OUTPUT_CTRL,     McPanel::OnOutputSelect)

//EVT_TREE_END_LABEL_EDIT(OUTPUT_CTRL,  McPanel::OnEditEnd)

EVT_CONTEXT_MENU(                     McPanel::OnContextMenu)

EVT_MENU(COMMAND_REMOVE,              McPanel::OnRemove)
EVT_MENU(COMMAND_INFO,                McPanel::OnInfo)
EVT_MENU(COMMAND_DICOM,               McPanel::OnDicom)
EVT_MENU(COMMAND_IMAGE,               McPanel::OnImage)
EVT_MENU(COMMAND_DIRECTORY,           McPanel::OnDirectory)
EVT_MENU(COMMAND_RENAME,              McPanel::OnRename)

//EVT_DROP_FILES(                       McPanel::OnDropFiles)
//EVT_COMMAND(wxID_ANY, DROP_EVENT, McPanel::OnDropFiles)

END_EVENT_TABLE()


class DnDFile;
///
/**
*/
McPanel::McPanel(wxWindow* parent) : wxPanel(parent, -1)
{
  m_output_type = 0;
  mpConverter = new Converter(m_output_type);

  // create sizer for panel
  wxBoxSizer* panelSizer = new wxBoxSizer(wxVERTICAL);

  panelSizer->Add(new wxStaticLine(this, -1), 0, wxEXPAND);

  // create sizer for source list
  wxBoxSizer* sSizer = new wxBoxSizer(wxHORIZONTAL);

  // add title
  panelSizer->Add(new wxStaticText(this, -1, _("DICOM series to convert"),
  wxDefaultPosition), 0, wxLEFT|wxTOP, 20);

  panelSizer->Add(0, 10, 0, wxEXPAND);

  // add list box
  mpSourceCtrl = new DicomTreeCtrl(this, SOURCE_CTRL, wxTR_MULTIPLE);
  sSizer->Add(mpSourceCtrl, 1, wxEXPAND);

  // add buttons
  wxBoxSizer* sSizer_buttons = new wxBoxSizer(wxVERTICAL);

  sSizer_buttons->Add(new ttButton(this, COMMAND_ADD_FILES, _("Add files"),
  _("Add files to convert")), 0, wxBOTTOM, 10);

  sSizer_buttons->Add(new ttButton(this, COMMAND_ADD_DIR, _("Add folder"),
  _("Add directory of files to convert")), 0, wxBOTTOM, 10);
  
  mpRemoveButton = new ttButton(this, COMMAND_REMOVE, _("Remove"),
  _("Remove series from list"));
  sSizer_buttons->Add(mpRemoveButton, 0, wxBOTTOM, 10);
  
  sSizer->Add(sSizer_buttons, 0, wxLEFT, 20);

  // add source list box sizer to panel sizer
  panelSizer->Add(sSizer, 1, wxEXPAND|wxLEFT|wxRIGHT, 20);  

  // add output selector
  mpOutputChooser = new wxChoice(this, CHOICE_OUTPUT);
  for (int i = 0; i < OutputFactory::GetNumberOfTypes(); ++i) {
    mpOutputChooser->Append(wxString(OutputFactory::GetDescription(i), wxConvLocal));
  }
  
  mpOutputChooser->SetSize(mpOutputChooser->GetBestSize());
  mpOutputChooser->SetSelection(m_output_type);

  panelSizer->Add(mpOutputChooser, 0, wxLEFT|wxTOP, 20);

  panelSizer->Add(0, 10, 0, wxEXPAND);
  
  // create sizer for output tree control
  wxBoxSizer* oSizer = new wxBoxSizer(wxHORIZONTAL);

  // add output tree control
  wxString rootdir;
  wxConfig::Get()->Read(CFG_dir, &rootdir);

  while (!wxDir::Exists(rootdir)) {
    rootdir = wxDirSelector(_("Choose a directory for output"));
    if (rootdir.empty()) {
      GetParent()->Close(false);
    }
  }
  
  mpOutputCtrl = new NewOutputTreeCtrl(this, OUTPUT_CTRL, rootdir);

  oSizer->Add(mpOutputCtrl, 1, wxEXPAND);

  // add buttons
  wxBoxSizer* oSizer_buttons = new wxBoxSizer(wxVERTICAL);

  mpOptionsButton = new ttButton(this, COMMAND_OPTIONS,
  _("Options"), _("Options for this format"));
  oSizer_buttons->Add(mpOptionsButton, 0, wxBOTTOM, 10);

  oSizer_buttons->Add(new ttButton(this, COMMAND_DIRECTORY, 
  _("Directory"), _("Select directory for converted files")),
  0, wxBOTTOM, 10);

  mpRenameButton = new ttButton(this, COMMAND_RENAME, _("Rename"),
  _("Change names of output files/directories"));
  oSizer_buttons->Add(mpRenameButton);

  oSizer->Add(oSizer_buttons, 0, wxLEFT, 20);

  // add output control sizer to panel sizer
  panelSizer->Add(oSizer, 1, wxEXPAND|wxLEFT|wxRIGHT, 20);

 // mpPathInfo = new wxStaticText(this, -1, ::wxGetCwd());
//  panelSizer->Add(mpPathInfo, 0, wxALL, 20);

//  panelSizer->Add(new wxStaticLine(this, -1), 0, wxEXPAND);

  // create button sizer
  wxBoxSizer* buttonSizer = new wxBoxSizer(wxHORIZONTAL);

  // add buttons to button sizer
  buttonSizer->Add(new ttButton(this, COMMAND_NEW, 
  _("New session"), _("Clear list and start new session")),
  0, wxRIGHT, 20);

  buttonSizer->Add(new ttButton(this, COMMAND_CONVERT, 
  _("Convert all"), _("Convert all files")), 0, wxRIGHT, 20);

  buttonSizer->Add(new ttButton(this, wxID_EXIT, _("Quit"),
  _("Quit the application")));

  // add button sizer to panel sizer
  panelSizer->Add(0, 10, 0, wxEXPAND);
  panelSizer->Add(buttonSizer, 0, wxALIGN_RIGHT|wxRIGHT, 20);
  panelSizer->Add(0, 10, 0, wxEXPAND);

  // set the sizer and layout
  SetSizer(panelSizer);

  mpOutputCtrl->SetOutputter(mpConverter->GetOutputter());

  #if defined(__WXMSW__) 
//  DragAcceptFiles(true); // oh look at one point I knew this.
  #endif

  this->SetDropTarget(new DnDFile(this));
  //Bind(DROP_EVENT, &McPanel::OnDropFiles, this, wxID_ANY);

  if (wxGetApp().argc > 1) {
    for (int i = 1; i < wxGetApp().argc; ++i) {
      wxFileName filename(wxGetApp().argv[i]);
      if (filename.FileExists()) {
        mpConverter->AddFile(filename.GetFullPath());
      }
      else if (filename.DirExists()) {
        wxArrayString files;
        wxDir::GetAllFiles(filename.GetFullPath(), &files);
        mAddSomeFilesDialog(files);
      }
    }

    mpConverter->UpdateOutput();
    ResetOutput();
    RefreshSourceCtrl();
    ShowMessageBox();

    ::wxGetTopLevelParent(this)->Raise();
  }
}


///
/**
*/
McPanel::~McPanel()
{
  wxString rootdir = mpOutputCtrl->GetItemText(mpOutputCtrl->GetRootItem());
  wxConfig::Get()->Write(CFG_dir, rootdir);
  delete mpConverter;
}


// kindof annoying this way, but okay for now
///
/**
*/
void
McPanel::RefreshSourceCtrl()
{
  std::vector<std::string> sv = mpConverter->GetSeriesList();
  std::vector<std::string>::iterator it = sv.begin();
  std::vector<std::string>::iterator it_end = sv.end();
  for (; it != it_end; ++it) {
    SeriesHandler* series = mpConverter->GetHandler(*it);
    mpSourceCtrl->AddSeries(series);
  } 
}


///
/**
*/
void
McPanel::ResetOutput()
{
  wxBusyCursor busy;
  mpOutputCtrl->Reset();
  mpOutputCtrl->RefreshList();
}


///
/**
*/
void
McPanel::SetSplitDirs(bool split)
{
  mpOutputCtrl->SplitDirectories(split);
}


///
/**
*/
void
McPanel::SetSplitSubj(bool split)
{
  mpOutputCtrl->SplitSubjects(split);
}


///
/**

void
McPanel::SetPathInfo(wxString path)
{
  wxTreeItemId item = mpOutputCtrl->GetSelection();
  wxTreeItemId root = mpOutputCtrl->GetRootItem();

  if (!item.IsOk() || item == root) {
    path = mpOutputCtrl->GetItemText(root);
  }
  else {
    while(item != root) {
      item = mpOutputCtrl->GetItemParent(item);
      path.Prepend(wxFileName::GetPathSeparator());
      path.Prepend(mpOutputCtrl->GetItemText(item));
    }
  }
//  mpPathInfo->SetLabel(path);
}
*/

///
/**
*/
void
McPanel::ShowMessageBox()
{
  if (!mpConverter->messages.empty()) {
    wxWindowDisabler disableAll;
    MessageListDlg lmd(_("Finished adding files"));
    Message m;
    m.push_back(_("File name"));
    m.push_back(_("Status"));
    m.push_back(_("Information"));
    lmd.SetColumns(m);
    lmd.AddMessages(mpConverter->messages);
    lmd.ShowModal();
    mpConverter->messages.clear();
  }
}


///
/** Helper method for adding files. Handles display of a progress dialog.
    Local variable tuneParam controls the period of dialog update.
    \param files List of files to add.
    \param msg Message to display. This is also logged.
*/
void
McPanel::mAddSomeFilesDialog(wxArrayString files, const wxChar* msg)
{
  wxLogStatus(msg);
  unsigned int nfiles = files.GetCount();
  // Dialog is updated twenty times.
  unsigned int tuneParam = 20;
  unsigned int tuneUpdate = std::max(tuneParam, nfiles / tuneParam);
  
  wxProgressDialog* p_dlg = new wxProgressDialog(_("Progress"), 
  msg, 
  nfiles,
  this,
  wxPD_CAN_ABORT | wxPD_APP_MODAL | wxPD_SMOOTH);
  
  files.Sort();
  wxArrayString::iterator it = files.begin();
  wxArrayString::iterator it_end = files.end();
  for (unsigned int i = 0; it != it_end; ++it, ++i) {
    wxFileName filename(*it);
    mpConverter->AddFile(filename.GetFullPath());
    if (i % tuneUpdate == 0) {
      if (!p_dlg->Update(i)) {
        break;
      }
    }
  }
  p_dlg->Destroy();
  wxLogStatus(_("Finished."));
}


// EVENT HANDLERS
///
/**
*/
void
McPanel::OnQuit(wxCommandEvent& event)
{
  GetParent()->Close(false);
}


///
/**
*/
void
McPanel::OnContextMenu(wxContextMenuEvent& event)
{
  wxPoint pos = event.GetPosition();

  wxTreeItemId item = mpSourceCtrl->HitTest(mpSourceCtrl->ScreenToClient(pos));
  if (item.IsOk()) {
    wxMenu menu;
    switch (mpSourceCtrl->GetItemType(item)) {

    case dtFILE :
      menu.Append(COMMAND_DICOM, _("View DICOM"));
      menu.Append(COMMAND_IMAGE, _("View Image"));
      menu.Append(COMMAND_INFO, _("Series Info"));
      break;

    case dtSERIES : 
      menu.Append(COMMAND_INFO, _("Series Info"));

      default : 
      menu.Append(COMMAND_REMOVE, _("Remove"));
      break;
    }
    PopupMenu(&menu, ScreenToClient(pos));
  }
}


///
/**
*/
void
McPanel::OnChoiceOutput(wxCommandEvent& event)
{
  if (m_output_type != mpOutputChooser->GetSelection()) {
    m_output_type = mpOutputChooser->GetSelection();

    mpConverter->SetOutput(m_output_type);

    mpOutputCtrl->SetOutputter(mpConverter->GetOutputter());
    mpOutputCtrl->SetItemTextColour(mpOutputCtrl->GetRootItem(),
    mpOutputCtrl->GetForegroundColour());
  }
}


///
/**
*/
void
McPanel::OnSourceSelect(wxTreeEvent& event)
{
  // I think we used to enable/disable buttons here...
}


///
/**
*/
void
McPanel::OnOutputSelect(wxTreeEvent& event)
{ 
  // Only do anything if this is a "select" event
  wxTreeItemId item = mpOutputCtrl->GetSelection();
  if (item.IsOk()) {
//    SetPathInfo(mpOutputCtrl->GetStringSelection());
    mpSourceCtrl->UnselectAll();
  }
}


///
/**
*/
void
McPanel::OnEditBegin(wxTreeEvent& event)
{
}


///
/**

void
McPanel::OnEditEnd(wxTreeEvent& event)
{
  if (!event.IsEditCancelled()) {
//    SetPathInfo(event.GetLabel());
  }
}
*/

///
/** Handler for adding user-chosen set of files.
*/
void
McPanel::OnAddFiles(wxCommandEvent& event)
{
  wxString lastDir;
  wxConfig::Get()->Read(CFG_lastdir, &lastDir);

  wxFileDialog dlg(this,
  _("Choose files"),
  lastDir,
  _T(""), _("*"),
  wxFD_OPEN|wxFD_MULTIPLE|wxRESIZE_BORDER);

  if (dlg.ShowModal() == wxID_OK) {
    wxBusyCursor busy;
    wxLogStatus(_("Searching directories..."));
    wxArrayString files;
    dlg.GetPaths(files);
    mAddSomeFilesDialog(files);

    // These three lines permit saving the user's last directory
    // in their config file.
    wxFileName fn(files[0]);
    lastDir = fn.GetPath();
    wxConfig::Get()->Write(CFG_lastdir, lastDir);
    
    mpConverter->UpdateOutput();
    wxLogStatus(_("Creating tree..."));
    RefreshSourceCtrl();
    ResetOutput();
  }

  wxLogStatus(_("Finished."));
  ShowMessageBox();
  ::wxGetTopLevelParent(this)->Raise();
}


/** Handler for drag-and-drop.
*/
/* Old way, windows only
void
McPanel::OnDropFiles(wxDropFilesEvent& event)
{
  int nfiles = event.GetNumberOfFiles();
  wxString* dropfiles = event.GetFiles();
  
  for (int i = 0; i < nfiles; ++i) {
    wxFileName filename(dropfiles[i]);
    if (filename.FileExists()) {
      mpConverter->AddFile(filename.GetFullPath());
    }
    else if (filename.DirExists()) {
      wxArrayString files;
      wxDir::GetAllFiles(filename.GetFullPath(), &files);
      mAddSomeFilesDialog(files);
    }
  }

  mpConverter->UpdateOutput();
  ResetOutput();
  RefreshSourceCtrl();
  ShowMessageBox();
  ::wxGetTopLevelParent(this)->Raise();
}
*/

void
McPanel::OnDropFiles(const wxArrayString& dropfiles)
{

   int nfiles = dropfiles.GetCount();
  
  for (int i = 0; i < nfiles; ++i) {
    wxFileName filename(dropfiles[i]);
    if (filename.FileExists()) {
      mpConverter->AddFile(filename.GetFullPath());
    }
    else if (filename.DirExists()) {
      wxArrayString files;
      wxDir::GetAllFiles(filename.GetFullPath(), &files);
      mAddSomeFilesDialog(files);
    }
  }

  mpConverter->UpdateOutput();
  ResetOutput();
  RefreshSourceCtrl();
  ShowMessageBox();
  ::wxGetTopLevelParent(this)->Raise();
}


bool 
DnDFile::OnDropFiles(wxCoord, wxCoord, const wxArrayString& filenames)
{
// 	m_pOwner->droppedFiles = filenames;
 m_pOwner->OnDropFiles(filenames);
 /*
	wxCommandEvent event(DROP_EVENT, wxID_ANY);
	event.SetEventObject(m_pOwner);
	m_pOwner->ProcessWindowEvent(event);
	*/
  return true;
}


///
/** Handler for adding files from a user-chosen directory.
*/
void
McPanel::OnAddDir(wxCommandEvent& event)
{
  wxString lastDir;
  wxConfig::Get()->Read(CFG_lastdir, &lastDir);

  wxDirDialog dlg(this,
  _("Select a directory of files to convert"),
  lastDir,
  wxRESIZE_BORDER);

  if (dlg.ShowModal() == wxID_OK) {
    wxBusyCursor busy;
    wxLogStatus(_("Searching directories..."));
    wxArrayString files;
    wxDir::GetAllFiles(dlg.GetPath(), &files);
    mAddSomeFilesDialog(files);

    lastDir = dlg.GetPath();
    wxConfig::Get()->Write(CFG_lastdir, dlg.GetPath());
    
    //mpConverter->UpdateOutput();
    //RefreshSourceCtrl();
    //ResetOutput();
  }
  // The next three lines should happen only on wxID_OK...
  mpConverter->UpdateOutput();
  ResetOutput();
  RefreshSourceCtrl();
  
  wxLogStatus(_("Finished."));
  ShowMessageBox();
  ::wxGetTopLevelParent(this)->Raise();
}


///
/** Shows DICOM header information for selected items.
*/
void
McPanel::OnDicom(wxCommandEvent& event)
{
  wxArrayTreeItemIds selecteds;
  unsigned int n_selected = mpSourceCtrl->GetSelected(selecteds);

  for (unsigned int i = 0; i < n_selected; ++i) {
    if (mpSourceCtrl->GetItemType(selecteds[i]) == dtFILE) {
      wxString filename = mpSourceCtrl->GetStringSelection(selecteds[i]);
      DicomViewer* viewer = new DicomViewer(this, filename.mb_str(wxConvLocal)); 
      viewer->Show();
    }
  }
}


///
/** Shows DICOM image for selected items.
*/
void
McPanel::OnImage(wxCommandEvent& event)
{
  wxArrayTreeItemIds selecteds;
  unsigned int n_selected = mpSourceCtrl->GetSelected(selecteds);
  
  for (unsigned int i = 0; i < n_selected; ++i) {
    if (mpSourceCtrl->GetItemType(selecteds[i]) == dtFILE) {
      wxString filename = mpSourceCtrl->GetStringSelection(selecteds[i]);

      DicomFile dfile(filename.mb_str(wxConvLocal));
      int frames = 1;
      dfile.Find("NumberOfFrames", frames);
      if (frames > 1) {
        MultiFrameImageViewer* viewer = new MultiFrameImageViewer(this, filename);
        viewer->Show();
      }
      else {
        std::vector<wxString> filenames = mpSourceCtrl->GetFilesInSeries(selecteds[i]);
        ImageViewer* viewer = new ImageViewer(this, filenames, filename);
        viewer->Show();
      }
    }
    // Blank the status bar.
    wxLogStatus(_T(""));
  }
}


///
/** Shows Series information for selected items.
*/
void
McPanel::OnInfo(wxCommandEvent& event)
{
  wxTreeItemId selected;
  wxArrayTreeItemIds selecteds;
  unsigned int n_selected = mpSourceCtrl->GetSelected(selecteds);

  for (unsigned int i = 0; i < n_selected; ++i) {

    wxTreeItemId selection = selecteds[i];
    int type = mpSourceCtrl->GetItemType(selection);

    if ((type == dtSERIES) || (type == dtFILE)) {
      wxBusyCursor busy;
      std::string series_uid;
      if (type == dtSERIES) {
        series_uid = mpSourceCtrl->GetItemUid(selection);
      }
      else if (type == dtFILE) {
        wxTreeItemId series = mpSourceCtrl->GetItemParent(selection);
        series_uid = mpSourceCtrl->GetItemUid(series);
      }
      std::vector<std::string> info = mpConverter->GetStringInfo(series_uid);
      InfoFrame* infoFrame = new InfoFrame(this, info);
      infoFrame->Show();
    }
  }
}


///
/** Processes removal of item(s) selected in the list of added
    DICOM files and directories.
*/
void
McPanel::OnRemove(wxCommandEvent& event)
{
  wxTreeItemId selected;
  wxArrayTreeItemIds selecteds;
  unsigned int n_selected = mpSourceCtrl->GetSelected(selecteds);

  for (unsigned int i = 0; i < n_selected; ++i) {
    selected = selecteds[i];
    if (selected.IsOk()) {
      if (mpSourceCtrl->GetSelectionType() == dtFILE) {
        wxLogError(_("Sorry, you'll have to remove the whole series."));
        return;
      }

      std::vector<std::string> series_vector = mpSourceCtrl->GetChildSeries(selected);

      std::vector<std::string>::iterator it = series_vector.begin();
      std::vector<std::string>::iterator it_end = series_vector.end();
      for (; it < it_end; ++it) {
        mpConverter->RemoveSeries(*it);
        mpOutputCtrl->RemoveSeries(*it);
      }

      mpSourceCtrl->RemoveBranch(selected);
    } else {
      return;
    }
  }
}


///
/**
*/
void
McPanel::OnOptions(wxCommandEvent& event)
{
  if (ShowOptionsDlg(m_output_type, mpConverter->GetOutputter())) {
    mpConverter->UpdateAllOutput();
    ResetOutput();
  }
}


///
/**
*/
void
McPanel::OnDirectory(wxCommandEvent& event)
{
  mpOutputCtrl->ChooseRootDir();
}


///
/**
*/
void
McPanel::OnNew(wxCommandEvent& event)
{
  delete mpConverter;
  mpConverter = new Converter(m_output_type);
  mpSourceCtrl->Reset();
  mpOutputCtrl->Reset();
  mpOutputCtrl->SetOutputter(mpConverter->GetOutputter());
  mpOutputCtrl->SetItemTextColour(mpOutputCtrl->GetRootItem(),
  mpOutputCtrl->GetForegroundColour());
}


///
/**
*/
void
McPanel::OnConvert(wxCommandEvent& event)
{
  wxWindowDisabler disableAll;
  wxBusyCursor cursor;
  wxBusyInfo wait(_("Converting files, please wait..."));
  mpConverter->ConvertAll();
  wxLogStatus(_("Finished."));
  ShowMessageBox();
  ::wxGetTopLevelParent(this)->Raise();
}


///
/**
*/
void
McPanel::OnRename(wxCommandEvent& event)
{
  mpOutputCtrl->OnMenuRename(event);
/*  wxString pathInfo = mpOutputCtrl->GetStringSelection();
  if (pathInfo != _T("error")) {
    SetPathInfo(pathInfo);
  }
  */
}


///
/**
*/
void
McPanel::OnMenuOverride()
{
  wxCommandEvent nullEvent(0,0);
  mpOutputCtrl->OnMenuOverride(nullEvent);
}


///
/**
*/
void
McPanel::OnOverride(const std::string& seriesUid)
{
  if (ShowOverride(m_output_type, mpConverter->GetOutputter(), seriesUid)) {
    mpConverter->UpdateAllOutput();
    ResetOutput();
  }
}


///
/**
*/
bool
McPanel::ShowOptionsDlg(int type, OutputterBase* outputter)
{
  bool needsRebuild = false;

  switch (type) {

  case OutputFactory::SPM : {
        SpmOptionsDlg* dlg = new SpmOptionsDlg(dynamic_cast<NewSpmOutputter*>(outputter));
        if (dlg->ShowModal() == wxID_OK) {
          needsRebuild = dlg->NeedsRebuild();
        }
        dlg->Destroy();
      }
    break;

  case OutputFactory::META : {
      MetaOptionsDlg* dlg = new MetaOptionsDlg(dynamic_cast<NewMetaOutputter*>(outputter));
      if (dlg->ShowModal() == wxID_OK) {
        needsRebuild = dlg->NeedsRebuild();
      }
      dlg->Destroy();
      }
    break;

  case OutputFactory::NIFTI : {
      NiftiOptionsDlg* dlg = new NiftiOptionsDlg(dynamic_cast<NiftiOutputterBase*>(outputter));
      if (dlg->ShowModal() == wxID_OK) {
        needsRebuild = dlg->NeedsRebuild();
      }
      dlg->Destroy();
      }
    break;

  case OutputFactory::ANALYZE : {
      AnalyzeOptionsDlg* dlg = new AnalyzeOptionsDlg(dynamic_cast<AnalyzeOutputter*>(outputter));
      if (dlg->ShowModal() == wxID_OK) {
        needsRebuild = dlg->NeedsRebuild();
      }
      dlg->Destroy();
      }
    break;

  case OutputFactory::FSL : {
      NiftiOptionsDlg* dlg = new NiftiOptionsDlg(dynamic_cast<NiftiOutputterBase*>(outputter));
      if (dlg->ShowModal() == wxID_OK) {
        needsRebuild = dlg->NeedsRebuild();
      }
      dlg->Destroy();
      }
    break;

  case OutputFactory::BV : {
      BvOptionsDlg* dlg = new BvOptionsDlg(dynamic_cast<NewBvOutputter*>(outputter));
      if (dlg->ShowModal() == wxID_OK) {
        needsRebuild = dlg->NeedsRebuild();
      }
      dlg->Destroy();
      }
    break;

    default : {
      NoOptionsDlg* dlg = new NoOptionsDlg();
      dlg->ShowModal();
      dlg->Destroy();
      }
  }
  return needsRebuild;
}


///
/**
*/
bool 
McPanel::ShowOverride(int type, OutputterBase* outputter, const std::string& series_uid)
{
  bool needsRebuild = false;
  if (type == OutputFactory::BV) {
    wxLogMessage(_("It is not possible to override default options for BrainVoyager output."));
    return needsRebuild;
  }
  Basic3DOutputter* basicOutputter = dynamic_cast<Basic3DOutputter*>(outputter);
  OverrideDlg dlg;
  dlg.dimCheck->SetValue(basicOutputter->GetDimensionality(series_uid) == 4);
  dlg.skipSpin->SetValue(basicOutputter->GetSkip(series_uid));
  if (dlg.ShowModal() == wxID_OK) {
    if (dlg.dimCheck->GetValue()) {
      basicOutputter->SetDimensionality(series_uid, 4);
    }
    else {
      basicOutputter->SetDimensionality(series_uid, 3);
    }
    basicOutputter->SetSkip(series_uid, dlg.skipSpin->GetValue());
    needsRebuild = true;
  }
  return needsRebuild;  
}
