///////////////////////////////////////////////////////////////////////////////
// Name:        optlistctrl.cpp
// Purpose:     wxOptionListCtrl
// Author:      Francesco Montorsi
// Modified by:
// Created:     10/7/2006
// RCS-ID:      $Id: optlistctrl.cpp,v 1.1.1.1 2006/12/12 09:38:28 frm Exp $
// Copyright:   (c) Francesco Montorsi
// Licence:     wxWindows licence
///////////////////////////////////////////////////////////////////////////////

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

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

#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#include "guipkg/optlistctrl.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"


// the number of columns to show
#define NUMCOLUMNS      3




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

IMPLEMENT_DYNAMIC_CLASS( wxOptionListCtrl, wxTreeListCtrl )
DEFINE_EVENT_TYPE(wxEVT_COMMAND_OPTION_DCLICK)
BEGIN_EVENT_TABLE( wxOptionListCtrl, wxTreeListCtrl )
    EVT_TREE_ITEM_ACTIVATED( wxID_ANY, wxOptionListCtrl::OnItemActivated )
END_EVENT_TABLE()

// ----------------------------------------------------------------------------
// wxOptionListCtrl
// ----------------------------------------------------------------------------

bool wxOptionListCtrl::Create(wxWindow* parent, wxWindowID id,
                                const wxPoint& pos, const wxSize& size,
                                long WXUNUSED(style), const wxString& name)
{
    if (!wxTreeListCtrl::Create(parent, id, pos, size,
         wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_NO_LINES|wxTR_FULL_ROW_HIGHLIGHT,
                                wxDefaultValidator, name))
        return false;

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

    AddColumn(wxT("Name"), 150, wxALIGN_LEFT);
    AddColumn(wxT("Allowed values"), 100, wxALIGN_CENTER);
    AddColumn(wxT("Default"), 100, wxALIGN_CENTER);

#if NUMCOLUMNS >= 3
    AddColumn(wxT("Stages"), 100, wxALIGN_CENTER);
#endif
#if NUMCOLUMNS >= 4
    AddColumn(wxT("Formats"), 100, wxALIGN_RIGHT);
#endif
    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 wxOptionListCtrl::TransferDataToWindow()
{
    if (!wxTreeListCtrl::TransferDataToWindow())
        return false;

    // remove old options
    DeleteRoot();

    // add our hidden root
    wxTreeItemId root = AddRoot(wxT("Options"));

    // add options related to this stage & compiler
    wxArrayString alreadyadded;
    wxArrayTreeItemIds groupsid;
    wxString str;
    for (size_t i=0; i<m_arr.GetCount(); i++)
    {
        // NB: here we won't do the check on the platforms supported by the
        //     option as we want to list all options, even for platforms != current.
        if ((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
        wxTreeItemId id;
        if (alreadyadded.Index(m_arr[i].GetGroup()) == wxNOT_FOUND)
        {
            id = AppendItem( root, m_arr[i].GetGroup() );
            alreadyadded.Add( m_arr[i].GetGroup() );
            groupsid.Add( id );
        }
        else
        {
            int idx = alreadyadded.Index(m_arr[i].GetGroup());
            wxASSERT(idx != wxNOT_FOUND);
            id = groupsid[idx];
        }

        // option name
        wxTreeItemId item = AppendItem(id, m_arr[i].GetName());

        // allowed values
        str = m_arr[i].GetAllowedValues();
        str.Replace(wxT(","), wxT(", "));
        SetItemText(item, 1, str);

        // default value
        SetItemText(item, 2, m_arr[i].GetDefaultValue());

#if NUMCOLUMNS >= 3
        // stage
        if (m_arr[i].GetCondition().GetStages() ==
                    wxGetFullPackageBuildSystemStageList())
            str = wxT("All");
        else
        {
            str = m_arr[i].GetCondition().GetStagesStr();
            str.Replace(wxT(","), wxT(", "));
        }

        SetItemText(item, 3, str);
#endif

#if NUMCOLUMNS >= 4
        // formats
        if (m_arr[i].GetCondition().GetFormats() ==
            wxGetFullPackageCompilerFormatList())
            str = wxT("All");
        else
        {
            str = m_arr[i].GetCondition().GetFormatsStr();
            str.Replace(wxT(","), wxT(", "));
        }

        SetItemText(item, 4, str);
#endif
    }

    ExpandAll(GetRootItem());
    Refresh();
    return true;
}

bool wxOptionListCtrl::TransferDataFromWindow()
{
    if (!wxTreeListCtrl::TransferDataFromWindow())
        return false;

    // do nothing:the user cannot edit the options shown in this control
    // thus m_arr does not need any update

    return true;
}

void wxOptionListCtrl::DeleteSelected()
{
    int n = m_arr.IndexByName(GetSelectedOptName());
    wxASSERT(n != wxNOT_FOUND);

    // remove this option from our array
    m_arr.RemoveAt(n);

    // and update the control; we can't just do a
    // Delete(GetSelection()) because if this option is the last option
    // of its group, we would leave behind an empty group...
    TransferDataToWindow();
}

wxString wxOptionListCtrl::GetSelectedOptName() const
{
    wxASSERT(GetSelection().IsOk());

    // if this is an option group, then it's not an option!
    if (GetItemParent(GetSelection()) == GetRootItem())
        return wxEmptyString;     // skip this

    // the first column always contains the name of the option
    return GetItemText(GetSelection(), 0);
}


// ----------------------------------------------------------------------------
// wxOptionListCtrl - event handlers
// ----------------------------------------------------------------------------

void wxOptionListCtrl::OnItemActivated(wxTreeEvent &ev)
{
    // did the user clicked on the name of an option group ?
    if (GetItemParent(ev.GetItem()) == GetRootItem())
        return;     // skip this

    wxCommandEvent optdclick(wxEVT_COMMAND_OPTION_DCLICK, GetId());

    // set in the command event's string the name of the option double clicked
    optdclick.SetString(GetItemText(ev.GetItem(), 0));
    GetEventHandler()->AddPendingEvent(optdclick);
}
