/////////////////////////////////////////////////////////////////////////////
// Name:        refeditdlg.cpp
// Purpose:     wxPackageReferenceEditDlg
// Author:      Francesco Montorsi
// Modified by:
// Created:     Thu 10 Aug 2006 18:49:40 CEST
// RCS-ID:      $Id: refeditdlg.cpp,v 1.4 2007/01/27 23:26:21 frm Exp $
// Copyright:   (c) 2006 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 <wx/url.h>
#include <wx/filename.h>
#include <wx/filesys.h>

#include "wx/miscutils.h"
#include "guipkg/refeditdlg.h"


// ----------------------------------------------------------------------------
// wxPackageReferenceEditDlg
// ----------------------------------------------------------------------------

IMPLEMENT_DYNAMIC_CLASS( wxPackageReferenceEditDlg, wxDialog )
BEGIN_EVENT_TABLE( wxPackageReferenceEditDlg, wxDialog )
    EVT_BUTTON( ID_REFEDIT_LOCALBROWSE, wxPackageReferenceEditDlg::OnLocalBrowse )
    EVT_BUTTON( wxID_OK, wxPackageReferenceEditDlg::OnOK )
END_EVENT_TABLE()

wxPackageReferenceEditDlg::wxPackageReferenceEditDlg( )
{
}

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

bool wxPackageReferenceEditDlg::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
{
////@begin wxPackageReferenceEditDlg member initialisation
    m_pLocal = NULL;
    m_pRemote = NULL;
////@end wxPackageReferenceEditDlg member initialisation

////@begin wxPackageReferenceEditDlg creation
    SetExtraStyle(GetExtraStyle()|wxWS_EX_BLOCK_EVENTS);
    wxDialog::Create( parent, id, caption, pos, size, style );

    CreateControls();
    if (GetSizer())
    {
        GetSizer()->SetSizeHints(this);
    }
    Centre();
////@end wxPackageReferenceEditDlg creation
    return true;
}

void wxPackageReferenceEditDlg::CreateControls()
{
////@begin wxPackageReferenceEditDlg content construction
    wxPackageReferenceEditDlg* itemDialog1 = this;

    wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
    itemDialog1->SetSizer(itemBoxSizer2);

    wxStaticText* itemStaticText3 = new wxStaticText( itemDialog1, wxID_STATIC, _("The wxWidgets package format allows you to specify two types of links for the same \nresource: a local and a remote reference."), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer2->Add(itemStaticText3, 0, wxGROW|wxALL|wxADJUST_MINSIZE, 5);

    wxStaticBox* itemStaticBoxSizer4Static = new wxStaticBox(itemDialog1, wxID_ANY, _("Local reference"));
    wxStaticBoxSizer* itemStaticBoxSizer4 = new wxStaticBoxSizer(itemStaticBoxSizer4Static, wxVERTICAL);
    itemBoxSizer2->Add(itemStaticBoxSizer4, 0, wxGROW|wxALL, 5);

    wxStaticText* itemStaticText5 = new wxStaticText( itemDialog1, wxID_STATIC, _("The local reference will be used when the package has been downloaded and \nthus must be a path relative to the root directory of the WXZ package."), wxDefaultPosition, wxDefaultSize, 0 );
    itemStaticBoxSizer4->Add(itemStaticText5, 0, wxGROW|wxALL|wxADJUST_MINSIZE, 5);

    wxBoxSizer* itemBoxSizer6 = new wxBoxSizer(wxHORIZONTAL);
    itemStaticBoxSizer4->Add(itemBoxSizer6, 0, wxGROW, 5);

    wxStaticText* itemStaticText7 = new wxStaticText( itemDialog1, wxID_STATIC, _("Local reference:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer6->Add(itemStaticText7, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);

    m_pLocal = new wxTextCtrl( itemDialog1, ID_REFEDIT_LOCAL, _T(""), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer6->Add(m_pLocal, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxButton* itemButton9 = new wxButton( itemDialog1, ID_REFEDIT_LOCALBROWSE, _("Browse"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer6->Add(itemButton9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxStaticBox* itemStaticBoxSizer10Static = new wxStaticBox(itemDialog1, wxID_ANY, _("Remote reference"));
    wxStaticBoxSizer* itemStaticBoxSizer10 = new wxStaticBoxSizer(itemStaticBoxSizer10Static, wxVERTICAL);
    itemBoxSizer2->Add(itemStaticBoxSizer10, 0, wxGROW|wxALL, 5);

    wxStaticText* itemStaticText11 = new wxStaticText( itemDialog1, wxID_STATIC, _("The remote reference will be used when the package has not been downloaded \nyet and thus must be an URL to a remote resource."), wxDefaultPosition, wxDefaultSize, 0 );
    itemStaticBoxSizer10->Add(itemStaticText11, 0, wxGROW|wxALL|wxADJUST_MINSIZE, 5);

    wxBoxSizer* itemBoxSizer12 = new wxBoxSizer(wxHORIZONTAL);
    itemStaticBoxSizer10->Add(itemBoxSizer12, 0, wxGROW, 5);

    wxStaticText* itemStaticText13 = new wxStaticText( itemDialog1, wxID_STATIC, _("Remote reference:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer12->Add(itemStaticText13, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);

    m_pRemote = new wxTextCtrl( itemDialog1, ID_REFEDIT_REMOTE, _T(""), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer12->Add(m_pRemote, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxStdDialogButtonSizer* itemStdDialogButtonSizer15 = new wxStdDialogButtonSizer;

    itemBoxSizer2->Add(itemStdDialogButtonSizer15, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
    wxButton* itemButton16 = new wxButton( itemDialog1, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
    itemStdDialogButtonSizer15->AddButton(itemButton16);

    wxButton* itemButton17 = new wxButton( itemDialog1, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
    itemStdDialogButtonSizer15->AddButton(itemButton17);

    itemStdDialogButtonSizer15->Realize();

////@end wxPackageReferenceEditDlg content construction

    m_pLocal->SetValue(wxPACKAGEREF_DEFAULT_LOCALREF);
    m_pRemote->SetValue(wxPACKAGEREF_DEFAULT_HREF);
    m_strWildcard = wxT("*");
}

bool wxPackageReferenceEditDlg::ShowToolTips()
{
    return true;
}



// ----------------------------------------------------------------------------
// wxPackageReferenceEditDlg - event handlers
// ----------------------------------------------------------------------------

void wxPackageReferenceEditDlg::OnLocalBrowse(wxCommandEvent &WXUNUSED(ev))
{
    // choose the default path to show
    wxString v = m_pLocal->GetValue();
    wxString defpath = (v.IsEmpty() || v == wxPACKAGEREF_DEFAULT_LOCALREF) ?
                m_strRoot : wxFileSystem::URLToFileName(v).GetFullPath();

    wxFileDialog dlg(this, wxT("Choose the local file"),
                     defpath, wxEmptyString, m_strWildcard,
                     wxFD_DEFAULT_STYLE|wxFD_FILE_MUST_EXIST);

    wxFileName lref, root = wxFileName::DirName(m_strRoot);
    if (!root.IsOk() || !root.DirExists())
    {
        wxLogError(wxT("Invalid project root directory '%s'.\nCorrect it and retry."), 
                   m_strRoot.c_str());
        return;
    }

    bool valid;
    do
    {
        valid = true;
        if (dlg.ShowModal() == wxID_CANCEL)
            return;

        valid = wxIsSubfolderOf(root, dlg.GetPath());

        if (!valid)
        {
            wxASSERT(!m_strRoot.IsEmpty());
            wxString str = wxString::Format(
                wxT("As local reference you must select a file located under the project root directory '%s'..."),
                m_strRoot.c_str());
            wxMessageBox(str, wxT("Error"), wxOK|wxICON_ERROR);
        }

    } while (!valid);

    // we have a valid ref!
    // make it relative to the project root directory
    lref = dlg.GetPath();
    if (root.GetDirCount() > 0)
        root.RemoveLastDir();
    lref.MakeRelativeTo(root.GetPath());
    wxASSERT(lref.IsRelative());

    // wxFileSystem::FileNameToURL will make the filename absolute while we
    // want to avoid this; thus we'll do our own wxFileName --> URL conversion
    m_pLocal->SetValue(wxT("file:///") + lref.GetFullPath(wxPATH_UNIX));
}

void wxPackageReferenceEditDlg::OnOK(wxCommandEvent &WXUNUSED(ev))
{
    wxString r(m_pRemote->GetValue()), l(m_pLocal->GetValue());

    // both empty are not allowed!
    if ((r.IsEmpty() || r == wxPACKAGEREF_DEFAULT_HREF) &&
        (l.IsEmpty() || l == wxPACKAGEREF_DEFAULT_LOCALREF))
    {
        wxLogError(wxT("Please insert at least one of the required URLs."));
        return;
    }

    // check remote URL
    if (!r.IsEmpty())
    {
        wxURL u(r);
        if (u.GetError() != wxURL_NOERR)
        {
            wxLogError(wxT("Invalid remote URL: %s"), r.c_str());
            return;
        }
        else if (u.GetScheme() != wxT("http"))
        {
            wxLogError(wxT("Unknown '%s' protocol used in the remote URL. Please use the HTTP protocol."), u.GetScheme().c_str());
            return;
        }
    }

    // check local URL
    if (!l.IsEmpty())
    {
        wxURL u(l);
        if (u.GetError() != wxURL_NOERR)
        {
            wxLogError(wxT("Invalid local URL: %s"), l.c_str());
            return;
        }
        else if (u.GetScheme() != wxT("file"))
        {
            wxLogError(wxT("Unknown '%s' protocol used in the local URL. Please use the FILE protocol."), u.GetScheme().c_str());
            return;
        }
    }

    // all checks passed
    EndModal(wxID_OK);
}

