/// BasicOptionsDlg.cpp
/**
 */

#include <string>
#include <wx/wxprec.h>
#include <wx/spinctrl.h>
#include <wx/statline.h>

#include "BasicOptionsDlg.h"
#include "OutputterBase.h"
#include "Basic3DOutputter.h"

using namespace jcs;

BEGIN_EVENT_TABLE(BasicOptionsDlg, wxDialog)
//EVT_CLOSE(BasicOptionsDlg::OnClose)
//EVT_LISTBOX(wxID_ANY, BasicOptionsDlg::CmdEvtHandler)
//EVT_CHECKLISTBOX(wxID_ANY, BasicOptionsDlg::CmdEvtHandler)
END_EVENT_TABLE()


/// A basic panel for our Options dialog.
/**
 */
BasicOptionsDlg::BasicPanel::BasicPanel(wxWindow* parent) 
  : wxPanel(parent) 
{
  wxBoxSizer* panelSizer = new wxBoxSizer(wxVERTICAL);

  panelSizer->Add(new wxStaticText(this, -1, _("Items for default file names")),
		  0, wxTOP|wxLEFT|wxRIGHT, 10);

  mpNameFields = new wxCheckListBox(this, -1);
  mpNameFields->Connect(wxID_ANY, wxEVT_RIGHT_UP, wxMouseEventHandler(BasicOptionsDlg::OnRightClick), NULL, this);
  
  panelSizer->Add(mpNameFields, 0, wxEXPAND|wxALL, 10);

  mpSplitSubjCheck = new wxCheckBox(this, -1, 
				    _("Save each subject in separate directory"));
  panelSizer->Add(mpSplitSubjCheck, 0, wxALL, 10);
  //====================
  mpSplitDirsCheck = new wxCheckBox(this, -1, _("Save each series in separate directory"));
  panelSizer->Add(mpSplitDirsCheck, 0, wxLEFT|wxRIGHT|wxBOTTOM, 10);

  mpDimCheck = new wxCheckBox(this, -1,
			      _("Save multivolume series as 4D files"));
  panelSizer->Add(mpDimCheck, 0, wxLEFT|wxRIGHT|wxBOTTOM, 10);

  panelSizer->Add(new wxStaticText(this, -1,
				   _("Skip volumes for multivolume series:")), 
		  0, wxLEFT|wxRIGHT|wxBOTTOM, 10);
  mpSkipSpin = new wxSpinCtrl(this, -1, _T("0"));
  panelSizer->Add(mpSkipSpin, 0, wxLEFT|wxRIGHT|wxBOTTOM, 10);

  mpRescaleCheck = new wxCheckBox(this, -1,
				  _("Apply rescale slope and intercept to data"));
  panelSizer->Add(mpRescaleCheck, 0, wxALL, 10);

  SetSizer(panelSizer);
  panelSizer->Fit(this);

}


BasicOptionsDlg::BasicOptionsDlg(const wxString& title, Basic3DOutputter* outputter)
  : wxDialog(NULL, -1, title), mOutputter(outputter)
{
  myPanel = new BasicPanel(this);
  myPanel->mpSplitDirsCheck->SetValue(mOutputter->GetSplit());
  myPanel->mpSplitSubjCheck->SetValue(mOutputter->GetSplitSubj());
  myPanel->mpDimCheck->SetValue(mOutputter->GetDimensionality() == 4);
  myPanel->mpSkipSpin->SetValue(mOutputter->GetSkip());
  myPanel->mpRescaleCheck->SetValue(mOutputter->GetRescale());

  OutputterBase::FieldMap::iterator it = mOutputter->defaultNameFields.begin();
  OutputterBase::FieldMap::iterator it_end = mOutputter->defaultNameFields.end();
  for (int i = 0; it != it_end; it++, i++) {
    myPanel->mpNameFields->Append(wxString(it->second.name.c_str(), wxConvLocal));
    myPanel->mpNameFields->Check(i, it->second.value);
  }

  // default min size has extra white space vertically
  wxSize boxSize = myPanel->mpNameFields->GetEffectiveMinSize();
  boxSize.SetHeight(boxSize.GetHeight()*3/4);
  myPanel->mpNameFields->SetMinSize(boxSize);

}


bool
BasicOptionsDlg::SplitDirs() const 
{ return myPanel->mpSplitDirsCheck->GetValue(); }


bool
BasicOptionsDlg::SplitSubj() const 
{ return myPanel->mpSplitSubjCheck->GetValue(); }


int
BasicOptionsDlg::Dimensionality() const 
{ return (myPanel->mpDimCheck->GetValue()) ? 4 : 3; }


int
BasicOptionsDlg::Skip() const 
{ return myPanel->mpSkipSpin->GetValue(); }


bool
BasicOptionsDlg::Rescale() const
{ return myPanel->mpRescaleCheck->GetValue(); }


void
BasicOptionsDlg::OnRightClick(wxMouseEvent &event)
{
  //std::cout << "right click" << std::endl;
}
//...


///
/** All sub-classes of BasicOptionsDlg want these actions done.
 */
void
BasicOptionsDlg::OnOkay(wxCommandEvent& event)
{
  mOutputter->SetSplit (SplitDirs());
  mOutputter->SetSplitSubj (SplitSubj());
  mOutputter->SetDimensionality (Dimensionality());
  mOutputter->SetSkip (Skip());
  mOutputter->SetRescale (Rescale());
}


void
BasicOptionsDlg::OnClose(wxCloseEvent& event)
{
  //std::cout << "dialog closed" << std::endl;
  event.Skip();
}


void
BasicOptionsDlg::CmdEvtHandler(wxCommandEvent &evt)
{
  //std::cout << "CmdEvtHandler" << std::endl;
  evt.Skip();
}


bool
BasicOptionsDlg::Rebuild() const
{
  return ((SplitDirs()      != mOutputter->GetSplit()) || 
	  (SplitSubj()      != mOutputter->GetSplitSubj()) ||
	  (Dimensionality() != mOutputter->GetDimensionality()) || 
	  (Skip()           != mOutputter->GetSkip()));
}


bool
BasicOptionsDlg::SaveNameFields()
{
  bool needsRebuild = false;
  for (unsigned int i = 0; i < myPanel->mpNameFields->GetCount(); ++i) {
    std::string name(myPanel->mpNameFields->GetString(i).mb_str(wxConvLocal));
    bool value = myPanel->mpNameFields->IsChecked(i);
    OutputterBase::FieldMap::iterator it = mOutputter->defaultNameFields.begin();
    OutputterBase::FieldMap::iterator it_end = mOutputter->defaultNameFields.end();
    for (;it != it_end; ++it) {
      if (it->second.name == name) {
        if (it->second.value != value) {
	  needsRebuild = true;
	}
        it->second.value = value;
        break;
      }
    }
  }
  return needsRebuild;
}

