///////////////////////////////////////////////////////////////////////////////
// Name:        opteditctrl.cpp
// Purpose:     wxOptionEditorCtrl
// Author:      Francesco Montorsi
// Modified by:
// Created:     10/7/2006
// RCS-ID:      $Id: opteditctrl.cpp,v 1.2 2007/02/01 20:11:27 frm Exp $
// Copyright:   (c) Francesco Montorsi
// Licence:     wxWindows licence
///////////////////////////////////////////////////////////////////////////////

// ============================================================================
// declarations
// ============================================================================

// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------

#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#include "guipm/opteditctrl.h"

#ifndef WX_PRECOMP
    #include "wx/log.h"
    #include "wx/combobox.h"
    #include "wx/dcclient.h"
    #include "wx/settings.h"
#endif

#include "wx/config.h"
#include "wxp/package.h"



// ============================================================================
// implementation
// ============================================================================

IMPLEMENT_DYNAMIC_CLASS( wxOptionEditorCtrl, wxPropertyGrid )
DEFINE_EVENT_TYPE(wxEVT_COMMAND_OPTIONS_CHANGED)

BEGIN_EVENT_TABLE( wxOptionEditorCtrl, wxPropertyGrid )
    EVT_PG_CHANGED(wxID_ANY, wxOptionEditorCtrl::OnOptionChanged)
END_EVENT_TABLE()

// ----------------------------------------------------------------------------
// wxOptionEditorCtrl
// ----------------------------------------------------------------------------

bool wxOptionEditorCtrl::Create(wxWindow* parent, wxWindowID id,
                                const wxPoint& pos, const wxSize& size,
                                long style, const wxString& name)
{
    long addstyle = wxSUNKEN_BORDER | wxPG_BOLD_MODIFIED |
                    wxPG_DESCRIPTION | wxPG_SPLITTER_AUTO_CENTER | wxPG_DEFAULT_STYLE;
    if (!wxPropertyGrid::Create(parent, id, pos, size, style|addstyle, name))
        return false;

    m_buildsys = wxPBST_INVALID;
    m_formats = wxGetFullPackageCompilerFormatList();
    m_stages = wxGetFullPackageBuildSystemStageList();

    return true;
}

/*
bool wxOptionEditorCtrl::Load(wxConfigBase *p, const wxString &path)
{
    Clear();

    int num = 0;
    if (!p->Read(path + wxT("/ComboStrNum"), &num))
        return false;

    wxString str;
    for (int i=0; i < num; i++)
        if (p->Read(path + wxString::Format(wxT("/ComboStr%d"), i), &str))
            Append(str);
    if (GetCount() > 0)
        Select(0);      // by default select first item

    // load was okay only if we could read all the saved strings
    return GetCount() == (size_t)num;
}

void wxOptionEditorCtrl::Save(wxConfigBase *p, const wxString &path) const
{
    // order is important !
    for (size_t i=0; i < GetCount(); i++)
        p->Write(path + wxString::Format(wxT("/ComboStr%d"), i),
                 GetString(i));
    p->Write(path + wxT("/ComboStrNum"), (long)GetCount());
}
*/

bool wxOptionEditorCtrl::TransferDataToWindow()
{
    // remove old options
    Clear();

    // add options related to this stage
    wxArrayString alreadyadded;
    for (size_t i=0; i<m_arr.GetCount(); i++)
    {
        if (!m_arr[i].GetCondition().IsValidForCurrentPlatform() ||
            (m_stages != 0 && !m_arr[i].GetCondition().IsValidForStages(m_stages)) ||
            (m_formats != 0 && !m_arr[i].GetCondition().IsValidForCompilers(m_formats)) ||
            (m_buildsys != wxPBST_INVALID && !m_arr[i].GetCondition().IsValidForBuildSys(m_buildsys)))
            continue;   // skip this

        // add option group if necessary
        if (alreadyadded.Index(m_arr[i].GetGroup()) == wxNOT_FOUND)
        {
            AppendCategory( m_arr[i].GetGroup() );
            alreadyadded.Add( m_arr[i].GetGroup() );
        }
        else
            SetCurrentCategory(m_arr[i].GetGroup());

        switch (m_arr[i].GetCategory())
        {
        case wxPCOC_LISTED_VALUES:
            {
                if (m_arr[i].IsBoolean())
                {
                    Append(wxBoolProperty( m_arr[i].GetName(), wxPG_LABEL,
                                           m_arr[i].GetBooleanValue() ));
                }
                else
                {
                    // use values descriptions, if available
                    wxArrayString values = m_arr[i].GetAllowedValuesDescArray();
                    if (values.GetCount() == 0)
                        values = m_arr[i].GetAllowedValuesArray();

                    wxArrayInt temp;
                    for (size_t j=0; j < values.GetCount(); j++)
                        temp.Add(j);

                    Append(wxEnumProperty(m_arr[i].GetName(), wxPG_LABEL, values,
                                          temp, m_arr[i].GetValueIndex()) );
                }
            }
            break;

        case wxPCOC_DIRECTORY:
            Append(wxDirProperty(m_arr[i].GetName(), wxPG_LABEL,
                                 m_arr[i].GetValue()));
            break;

        case wxPCOC_FILE:
            Append(wxFileProperty(m_arr[i].GetName(), wxPG_LABEL,
                                  m_arr[i].GetValue()));
            break;

        case wxPCOC_STRING:
            Append(wxStringProperty(m_arr[i].GetName(), wxPG_LABEL,
                                    m_arr[i].GetValue()));
            break;

        default:
            wxASSERT(0);
        }
    }

    if (!wxPropertyGrid::TransferDataToWindow())
        return false;

    Refresh();
    return true;
}

bool wxOptionEditorCtrl::TransferDataFromWindow()
{
    if (!wxPropertyGrid::TransferDataFromWindow())
        return false;

    // do nothing: any change to the options in the control is
    // always automatically transferred to the m_arr variable
    // by OnOptionChanged() event handler

    return true;
}



// ----------------------------------------------------------------------------
// wxOptionEditorCtrl - event handlers
// ----------------------------------------------------------------------------

void wxOptionEditorCtrl::OnOptionChanged(wxPropertyGridEvent &ev)
{
    wxPackageCommandOption &opt =
        m_arr.ItemByName(ev.GetPropertyName());
    wxASSERT(opt.IsOk());

    // update option's value
    switch (opt.GetCategory())
    {
    case wxPCOC_LISTED_VALUES:
        if (opt.IsBoolean())
            opt.SetValue(ev.GetPropertyValueAsBool() == 1 ? wxT("1") : wxT("0"));
        else
            opt.SetValue(ev.GetPropertyValueAsString());
        break;

    default:
        opt.SetValue(ev.GetPropertyValueAsString());
        break;
    }

    m_arr.SetDirty(true);

    // send our event
    wxCommandEvent optchanged(wxEVT_COMMAND_OPTIONS_CHANGED, GetId());
    GetEventHandler()->AddPendingEvent(optchanged);
}

