/////////////////////////////////////////////////////////////////////////////
// Name:        proppanel_licensing.cpp
// Purpose:     wxPackagePropertiesPanel
//              (stuff for handling the "licensing" page)
// Author:      Francesco Montorsi
// Modified by:
// Created:     28/06/2006 19:22:47
// RCS-ID:      $Id: proppanel_licensing.cpp,v 1.7 2007/01/02 19:33:00 frm Exp $
// Copyright:   (c) 2006 Julian Smart, 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 "guipkg/proppanel.h"

#include "wxp/package.h"
#include "wxp/wxp.h"
#include "wxp/packagewxp.h"

#include "wx/miscutils.h"



// ----------------------------------------------------------------------------
// Global helpers
// ----------------------------------------------------------------------------

#define NUM_STANDARD_LICENSES     3

struct wxLicenseData
{
    wxString strName;
    wxString remoteRef;
    wxPackageLicenseType type;

} g_standardLicense[3] =
{
    { wxT("wxWidgets license"), 
      wxT("http://www.opensource.org/licenses/wxwindows.php"), wxPLT_OPENSOURCE },

    { wxT("GNU General Public License (GPL)"), 
      wxT("http://www.opensource.org/licenses/gpl-license.php"), wxPLT_OPENSOURCE },

    { wxT("GNU Lesser General Public License (LGPL)"), 
      wxT("http://www.opensource.org/licenses/lgpl-license.php"), wxPLT_OPENSOURCE }
};


// some globals author/maintainer helpers

wxString wxGetHrefFromListbox(wxListBox *lb, unsigned int idx)
{ return ((wxStringClientData *)lb->GetClientObject(idx))->GetData(); }

void wxUpdateHrefInListbox(wxListBox *lb, unsigned int idx, const wxString &href)
{ ((wxStringClientData *)lb->GetClientObject(idx))->SetData(href); }

wxString wxGetAuthorOrMaintainerLabelFor(const wxString &name, const wxString &href)
{
    if (!href.IsEmpty())
        return name + wxT(", <") + href + wxT(">");
    return name;
}

wxString wxGetAuthorOrMaintainerNameFrom(const wxString &itemtext)
{
    return itemtext.BeforeFirst(wxT(','));
}


// ----------------------------------------------------------------------------
// wxPackagePropertiesPanel - licensing stuff - I/O
// ----------------------------------------------------------------------------

void wxPackagePropertiesPanel::InitLicensingPage()
{
    m_pLicenseType->Append(wxArrayString(wxPLT_MAX, wxPackageLicenseTypeName));
    m_pLicenseType->Select(0);

    // append most common license names
    for (size_t j=0; j<NUM_STANDARD_LICENSES; j++)
        m_pLicense->Append(g_standardLicense[j].strName);
}

void wxPackagePropertiesPanel::GetLicensingPackageInfo(wxPackageInfo &ret) const
{
    // LICENSING info
    ret.SetLicenseRef(m_license);
    ret.SetLicenseType((wxPackageLicenseType)m_pLicenseType->GetSelection());
    ret.SetOrganization(m_pOrganization->GetValue(), m_pOrganizationWebsite->GetValue());
    ret.SetCost(m_pCost->GetValue());
    ret.SetCopyright(m_pCopyright->GetValue());
    ret.SetCredits(m_pCredits->GetValue());

    for (size_t i=0; i<m_pAuthors->GetCount(); i++)
        ret.AddAuthor(wxGetAuthorOrMaintainerNameFrom(m_pAuthors->GetString(i)),
                      wxGetHrefFromListbox(m_pAuthors, i));
    for (size_t i=0; i<m_pMaintainers->GetCount(); i++)
        ret.AddMaintainer(wxGetAuthorOrMaintainerNameFrom(m_pMaintainers->GetString(i)),
                          wxGetHrefFromListbox(m_pMaintainers, i));
}

void wxPackagePropertiesPanel::DoSetLicensingPackageInfo(const wxPackageInfo &p)
{
    // LICENSING info
    m_license = p.GetLicenseRef();
    m_pLicense->SetValue(m_license.GetData());
    m_pLicenseType->SetSelection(p.GetLicenseType());
    m_pOrganization->SetValue(p.GetOrganization());
    m_pOrganizationWebsite->SetValue(p.GetOrganizationHref());
    m_pCost->SetValue(p.GetCost());
    m_pCopyright->SetValue(p.GetCopyright());
    m_pCredits->SetValue(p.GetCredits());

    m_pAuthors->Clear();
    for (size_t i=0; i<p.GetAuthors().GetCount(); i++)
    {
        wxString name = p.GetAuthors().Item(i), href = p.GetAuthorsHref().Item(i);
        m_pAuthors->Append(wxGetAuthorOrMaintainerLabelFor(name, href),
                           new wxStringClientData(href));
    }

    m_pMaintainers->Clear();
    for (size_t i=0; i<p.GetMaintainers().GetCount(); i++)
    {
        wxString name = p.GetMaintainers().Item(i), href = p.GetMaintainersHref().Item(i);
        m_pMaintainers->Append(wxGetAuthorOrMaintainerLabelFor(name, href),
                               new wxStringClientData(href));
    }
}
bool wxPackagePropertiesPanel::IsLicensingPageOk() const
{
    bool isok = true;

    wxString l(m_pLicense->GetValue());
    if (l.IsEmpty())
    {
        wxLogError(wxT("The package license is not optional"));
        isok = false;
    }

    return isok;
}



// ----------------------------------------------------------------------------
// wxPackagePropertiesPanel - licensing stuff
// ----------------------------------------------------------------------------

bool wxPackagePropertiesPanel::GetAuthorOrMaintainer(bool isauthor,
                                                     wxString *ret,
                                                     wxString *rethref,
                                                     const wxString &defname,
                                                     const wxString &defhref)
{
    // NB: we don't want to use wxGetAuthorOrMaintainerLabelFor() here:
    wxString newentry = defname + wxT(" ") + defhref;
    size_t i;

    do
    {
        newentry = wxGetTextFromUser(
            wxString::Format(wxT("Please type the name of the new %s.\n\nNote that you can give after the name also an email address or\nmore generally an URL which allows to the users to get in touch\nwith that person (e.g. 'Isaac Newton isaac.newton@physics.net')..."), isauthor ? wxT("author") : wxT("maintainer")),
            wxT("Input text"),
            newentry,
            this);
        if (newentry.IsEmpty())
            return false;     // user hit cancel

        // is the name, except for spaces, using only valid chars ?
        wxArrayString temp = wxStringTokenize(newentry, wxT(' '));
        for (i=0; i < temp.GetCount() - 1; i++)
        {
            if (!wxIsPlainWord(temp[i]))
            {
                wxLogError(wxT("Invalid name '%s'.\nYou can use only the following characters:\n%s"),
                           temp[i].c_str(), wxGetPlainWordAllowedCharacters().c_str());
                break;
            }
        }

        if (i == temp.GetCount() - 1)
            break;      // all words except the last one (which can be a URL) are okay

    } while (1);

    // did the user included an email address at the end of the text ?
    wxString last = newentry.AfterLast(wxT(' ')), href;
    if (last.Contains(wxT("www")) ||
        last.Contains(wxT("://")) ||
        last.Contains(wxT("@")))
    {
        href = last;
        newentry = newentry.BeforeLast(wxT(' '));

        // now, set newentry so that it uses angular brackets around the URL
        newentry = wxGetAuthorOrMaintainerLabelFor(newentry, href);
    }

    if (ret) *ret = newentry;
    if (rethref) *rethref = href;

    return true;
}



// ----------------------------------------------------------------------------
// wxPackagePropertiesPanel - event handlers
// ----------------------------------------------------------------------------

void wxPackagePropertiesPanel::OnLicensingButton(wxCommandEvent &ev)
{
    OnUserChange();

    switch (ev.GetId())
    {
    case ID_PROP_NEW_AUTHOR:
    case ID_PROP_NEW_MAINTAINER:
        {
            wxString newentry, href;
            if (GetAuthorOrMaintainer(ev.GetId() == ID_PROP_NEW_AUTHOR, &newentry, &href))
            {
                wxListBox *p = ev.GetId() == ID_PROP_NEW_AUTHOR ? m_pAuthors : m_pMaintainers;
                p->Append(newentry, new wxStringClientData(href));
            }
        }
        break;

    case ID_PROP_DELETE_AUTHOR:
    case ID_PROP_DELETE_MAINTAINER:
        {
            wxListBox *p = NULL;
            switch (ev.GetId())
            {
                case ID_PROP_DELETE_AUTHOR: p=m_pAuthors; break;
                case ID_PROP_DELETE_MAINTAINER: p=m_pMaintainers; break;
                case ID_PROP_DELETE_DOWNLOADLINK: p=m_pDownloadLinks; break;
                default: wxASSERT(0);
            }
            wxASSERT(p->GetSelection() != wxNOT_FOUND);
            p->Delete(p->GetSelection());
        }
        break;
    }
}

void wxPackagePropertiesPanel::OnLicensingListBoxDClick(wxCommandEvent &ev)
{
    OnUserChange();

    switch (ev.GetId())
    {
        case ID_PROP_AUTHORS:
        case ID_PROP_MAINTAINERS:
        {
            wxListBox *p = ev.GetId() == ID_PROP_AUTHORS ? m_pAuthors : m_pMaintainers;
            int idx = p->GetSelection();
        
            if (idx == wxNOT_FOUND)
            {
                // this may happen on wxMSW 's listboxes when they have > 0 items
                // and the user clicks on the empty space
                return;
            }

            wxString newentry, href,
                     initialname = wxGetAuthorOrMaintainerNameFrom(p->GetString(idx)),
                     initialhref = wxGetHrefFromListbox(p, idx);

            if (GetAuthorOrMaintainer(ev.GetId() == ID_PROP_AUTHORS, &newentry, &href,
                                      initialname, initialhref))
            {
                p->SetString(idx, newentry);
                wxUpdateHrefInListbox(p, idx, href);
            }
        }
        break;
    }
}

void wxPackagePropertiesPanel::OnLicenseSelected(wxCommandEvent &ev)
{
    OnUserChange();

    // if the user choose a standard license, update all other
    // fields whose value is already known
    for (size_t i=0; i < NUM_STANDARD_LICENSES; i++)
    {
        if (ev.GetString() == g_standardLicense[i].strName)
        {
            m_pLicenseType->Select(g_standardLicense[i].type);
            m_license.SetHref(g_standardLicense[i].remoteRef);
            return;
        }
    }
}

void wxPackagePropertiesPanel::OnLicensingPageUpdateUI(wxUpdateUIEvent &WXUNUSED(ev))
{
    DisableIfNoSelection(ID_PROP_DELETE_AUTHOR, m_pAuthors);
    DisableIfNoSelection(ID_PROP_DELETE_MAINTAINER, m_pMaintainers);
}

