/////////////////////////////////////////////////////////////////////////////
// Name:        filterpanel.cpp
// Purpose:     wxPackageFilterPanel
// Author:      Julian Smart, Francesco Montorsi
// Modified by:
// Created:     04/06/2006 11:57:15
// RCS-ID:      $Id: filterpanel.cpp,v 1.2 2007/01/01 20:06:21 frm Exp $
// Copyright:   (c) 2004 Francesco Montorsi
// Licence:     wxWidgets license
/////////////////////////////////////////////////////////////////////////////


// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "guipm/filterpanel.h"
#include "wxp/package.h"
#include <wx/tokenzr.h>


// ----------------------------------------------------------------------------
// wxPackageFilterPanel
// ----------------------------------------------------------------------------

IMPLEMENT_DYNAMIC_CLASS( wxPackageFilterPanel, wxPanel )
DEFINE_EVENT_TYPE(wxEVT_COMMAND_FILTER_PACKAGES)
BEGIN_EVENT_TABLE( wxPackageFilterPanel, wxPanel )
    EVT_TEXT_ENTER(ID_FILTER_KEYWORDS, wxPackageFilterPanel::OnFilterUpdate)
    EVT_TEXT(ID_FILTER_KEYWORDS, wxPackageFilterPanel::OnFilterUpdate)
    EVT_CHOICE(wxID_ANY, wxPackageFilterPanel::OnFilterUpdate)
END_EVENT_TABLE()

wxPackageFilterPanel::wxPackageFilterPanel( )
{
}

wxPackageFilterPanel::wxPackageFilterPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
{
    Create(parent, id, pos, size, style);
}

bool wxPackageFilterPanel::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
{
    SetExtraStyle(GetExtraStyle()|wxWS_EX_BLOCK_EVENTS);
    wxPanel::Create( parent, id, pos, size, style );

    CreateControls();
    GetSizer()->Fit(this);
    GetSizer()->SetSizeHints(this);

    return true;
}

void wxPackageFilterPanel::CreateControls()
{
    wxPackageFilterPanel* itemPanel1 = this;

    wxStaticBox* itemStaticBoxSizer2Static = new wxStaticBox(itemPanel1, wxID_ANY, _("Filters"));
    wxStaticBoxSizer* itemStaticBoxSizer2 = new wxStaticBoxSizer(itemStaticBoxSizer2Static, wxVERTICAL);
    itemPanel1->SetSizer(itemStaticBoxSizer2);

    wxFlexGridSizer* itemFlexGridSizer3 = new wxFlexGridSizer(2, 2, 0, 0);
    itemFlexGridSizer3->AddGrowableCol(1);
    itemStaticBoxSizer2->Add(itemFlexGridSizer3, 1, wxGROW, 5);

    wxStaticText* itemStaticText4 = new wxStaticText( itemPanel1, wxID_STATIC, _("Platform:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemFlexGridSizer3->Add(itemStaticText4, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);

    m_pSupportedPort = new wxChoice( itemPanel1, ID_FILTER_SUPPORTED_WXPORT, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
    itemFlexGridSizer3->Add(m_pSupportedPort, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxStaticText* itemStaticText6 = new wxStaticText( itemPanel1, wxID_STATIC, _("Category:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemFlexGridSizer3->Add(itemStaticText6, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);

    m_pCategory = new wxChoice( itemPanel1, ID_FILTER_CATEGORY, wxDefaultPosition, wxDefaultSize, wxPC_MAX, wxPackageCategoryName, 0 );
    itemFlexGridSizer3->Add(m_pCategory, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxStaticText* itemStaticText8 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Keywords:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemFlexGridSizer3->Add(itemStaticText8, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);

    m_pKeywords = new wxTextCtrl( itemPanel1, ID_FILTER_KEYWORDS, _T(""), wxDefaultPosition, wxDefaultSize, 0 );
    itemFlexGridSizer3->Add(m_pKeywords, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);

    for (size_t i=0; i<wxPORT_MAX; i++)
        m_pSupportedPort->Append(wxPlatformInfo::GetPortIdName((wxPortId)(1 << i), false));

    // NB: the "any" values will be mapped to the wxPC_MAX and wxPORT_MAX values

    m_pSupportedPort->Append(_("Any"));
    m_pSupportedPort->SetStringSelection(_("Any"));

    m_pCategory->Append(_("Any"));
    m_pCategory->SetStringSelection(_("Any"));
}

bool wxPackageFilterPanel::IsToPreserve(const wxPackage &p) const
{
#define wxPORT_ANY            (1 << wxPORT_MAX)

    // wxPackagePlatform enum values are power of two
    // since they can be combined with OR
    wxPortId port = (wxPortId)(1 << m_pSupportedPort->GetCurrentSelection());
    if (port != wxPORT_ANY &&
        (p.GetSupportedPortFlag() & port) == 0)
        return false;

    wxPackageCategory cat = (wxPackageCategory)m_pCategory->GetCurrentSelection();
    if (cat != wxPC_MAX &&
        p.GetPrimaryCategory() != cat &&
        p.GetSecondaryCategory() != cat)
        return false;

    // all keywords should be present
    wxArrayString arr = wxString2Array(m_pKeywords->GetValue());
    for (size_t i=0; i<arr.GetCount(); i++)
        if (!p.GetKeywordsStr().Contains(arr[i]))
            return false;

    // all checks were passed
    return true;
}


// ----------------------------------------------------------------------------
// wxPackageFilterPanel - event handlers
// ----------------------------------------------------------------------------

void wxPackageFilterPanel::OnFilterUpdate(wxCommandEvent & WXUNUSED(ev))
{
    // tell our owner that it needs to refilter the packages
    wxCommandEvent update(wxEVT_COMMAND_FILTER_PACKAGES, GetId());

    // NB: we must send the event to the parent not to GetEventHandler()!
    GetParent()->AddPendingEvent(update);
}
