// -*- c-basic-offset: 4 -*-

/** @file HDRMergeOptionDialog.cpp
 *
 *	@brief implementation of dialog for hdrmerge options
 *
 *  @author Thomas Modes
 *
 *  $Id$
 *
 */

/*  This is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This software is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public
 *  License along with this software. If not, see
 *  <http://www.gnu.org/licenses/>.
 *
 */

#include "hugin/HDRMergeOptionDialog.h"
#include "base_wx/wxPlatform.h"
#ifdef __APPLE__
#include "panoinc_WX.h"
#include "panoinc.h"
#endif
#include <hugin/config_defaults.h>
#include "hugin/huginApp.h"
#include "base_wx/wxutils.h"

// somewhere SetDesc gets defined.. this breaks wx/cmdline.h on OSX
#ifdef SetDesc
#undef SetDesc
#endif

#include <wx/cmdline.h>

HDRMergeOptionsDialog::HDRMergeOptionsDialog(wxWindow *parent)
{
    wxXmlResource::Get()->LoadDialog(this, parent, "hdrmerge_options_dialog");

    m_mode=XRCCTRL(*this,"hdrmerge_option_mode",wxChoice);
    m_mode->Bind(wxEVT_CHOICE, &HDRMergeOptionsDialog::OnModeChanged, this);
    m_panel_avg=XRCCTRL(*this,"hdrmerge_option_panel_avg",wxPanel);
    m_panel_avgslow=XRCCTRL(*this,"hdrmerge_option_panel_avgslow",wxPanel);
    m_panel_khan=XRCCTRL(*this,"hdrmerge_option_panel_khan",wxPanel);
    m_option_c=XRCCTRL(*this,"hdrmerge_option_c",wxCheckBox);
    m_khan_iter=XRCCTRL(*this,"hdrmerge_option_khan_iter",wxSpinCtrl);
    m_khan_iter->SetRange(1,100);
    m_khan_sigma=XRCCTRL(*this,"hdrmerge_option_khan_sigma",wxTextCtrl);
    m_option_khan_af=XRCCTRL(*this,"hdrmerge_option_khan_af",wxCheckBox);
    m_option_khan_ag=XRCCTRL(*this,"hdrmerge_option_khan_ag",wxCheckBox);
    m_option_khan_am=XRCCTRL(*this,"hdrmerge_option_khan_am",wxCheckBox);
    this->CenterOnParent();
    Bind(wxEVT_BUTTON, &HDRMergeOptionsDialog::OnOk, this, wxID_OK);
};

void HDRMergeOptionsDialog::SetCommandLineArgument(wxString cmd)
{
    m_cmd=cmd;
    if (m_cmd.IsEmpty())
        m_cmd=HUGIN_HDRMERGE_ARGS;
    m_cmd.LowerCase();
	// parse arguments
    static const wxCmdLineEntryDesc cmdLineDesc[] =
    {
        { wxCMD_LINE_OPTION, "m", NULL, NULL, wxCMD_LINE_VAL_STRING },
        { wxCMD_LINE_SWITCH, "c", NULL, NULL},
        { wxCMD_LINE_OPTION, "i", NULL, NULL, wxCMD_LINE_VAL_NUMBER },
        { wxCMD_LINE_OPTION, "s", NULL, NULL, wxCMD_LINE_VAL_STRING },
        { wxCMD_LINE_OPTION, "a", NULL, NULL, wxCMD_LINE_VAL_STRING },
        { wxCMD_LINE_NONE }
    };
    wxCmdLineParser parser;
    parser.SetDesc(cmdLineDesc);
    parser.SetCmdLine(m_cmd);
    parser.Parse(false);
    wxString param;
    if(parser.Found("m",&param))
    {
        if(param.CmpNoCase("avg_slow")==0)
            m_mode->SetSelection(1);
        else
        {
            if(param.CmpNoCase("khan")==0)
                m_mode->SetSelection(2);
            else
                m_mode->SetSelection(0);
        };
    }
    else
        m_mode->SetSelection(0);
    m_option_c->SetValue(parser.Found("c"));
    long i;
    if(parser.Found("i",&i))
        m_khan_iter->SetValue(i);
    else
        m_khan_iter->SetValue(4);
    if(parser.Found("s",&param))
    {
        //change locale for correct numeric output
        char * p = setlocale(LC_NUMERIC,NULL);
        char * old_locale = strdup(p);
        setlocale(LC_NUMERIC,"C");
        double sigma=0.0;
        param.ToDouble(&sigma);
        //reset locale
        setlocale(LC_NUMERIC,old_locale);
        free(old_locale);
        //using current locale for value in GUI
        m_khan_sigma->SetValue(wxString::Format("%.2f",sigma));
    }
    else
        m_khan_sigma->SetValue("30");
    if(parser.Found("a",&param))
    {
        m_option_khan_af->SetValue(param.Contains("f"));
        m_option_khan_ag->SetValue(param.Contains("g"));
        m_option_khan_am->SetValue(param.Contains("m"));
    }
    wxCommandEvent dummy;
    OnModeChanged(dummy);
};

bool HDRMergeOptionsDialog::BuildCommandLineArgument()
{
    int selection=m_mode->GetSelection();
    m_cmd.Clear();
    bool correct_input=true;
    double i = 0;
    wxString errorstring(_("Invalid input\n"));
    switch(selection)
    {
        case 0:
            m_cmd.Append("-m avg");
            if(m_option_c->IsChecked())
                m_cmd.Append(" -c");
            break;
        case 1:
            m_cmd.Append("-m avg_slow");
            break;
        case 2:
            m_cmd.Append("-m khan");
            if(m_khan_iter->GetValue())
            {
                m_cmd.Append(wxString::Format(" -i %d",m_khan_iter->GetValue()));
            }
            else
            {
                correct_input=false;
                errorstring.Append(wxString::Format(_("Input \"%s\" for %s is not a valid number\n"),
                    m_khan_iter->GetValue(),_("Iteration")));
            };
            if(m_khan_sigma->GetValue().ToDouble(&i))
            {
                //change locale for correct numeric output
                char * p = setlocale(LC_NUMERIC,NULL);
                char * old_locale = strdup(p);
                setlocale(LC_NUMERIC,"C");
                m_cmd.Append(wxString::Format(" -s %f",i));
                //reset locale
                setlocale(LC_NUMERIC,old_locale);
                free(old_locale);
            }
            else
            {
                correct_input=false;
                errorstring.Append(wxString::Format(_("Input \"%s\" for %s is not a valid number\n"),
                    m_khan_iter->GetValue(),_("Sigma")));
            };
            if(m_option_khan_af->IsChecked() || m_option_khan_ag->IsChecked() || 
                m_option_khan_am->IsChecked())
            {
                m_cmd.Append(" -a ");
                if(m_option_khan_af->IsChecked())
                    m_cmd.Append("f");
                if(m_option_khan_ag->IsChecked())
                    m_cmd.Append("g");
                if(m_option_khan_am->IsChecked())
                    m_cmd.Append("m");
            }
            break;
    };
    if(!correct_input)
        hugin_utils::HuginMessageBox(errorstring,_("Hugin"),wxOK | wxICON_INFORMATION, this);
    return correct_input;
};

void HDRMergeOptionsDialog::OnModeChanged(wxCommandEvent & e)
{
    int selection=m_mode->GetSelection();
    m_panel_avg->Show(selection==0);
    m_panel_avgslow->Show(selection==1);
    m_panel_khan->Show(selection==2);
    GetSizer()->Fit(this);
};

void HDRMergeOptionsDialog::OnOk(wxCommandEvent & e)
{
    if(BuildCommandLineArgument())
        this->EndModal(wxOK);
};

