/////////////////////////////////////////////////////////////////////////////
// Name:        src/generic/hyperlink.cpp
// Purpose:     Hyperlink control
// Author:      David Norris <danorris@gmail.com>, Otto Wyss
// Modified by: Ryan Norton, Francesco Montorsi
// Created:     04/02/2005
// RCS-ID:      $Id: hyperlink.cpp,v 1.7 2006/06/08 18:27:40 RD Exp $
// Copyright:   (c) 2005 David Norris
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

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

//---------------------------------------------------------------------------
// Pre-compiled header stuff
//---------------------------------------------------------------------------

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

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#if wxUSE_HYPERLINKCTRL

//---------------------------------------------------------------------------
// Includes
//---------------------------------------------------------------------------

#include "wx/hyperlink.h"

#ifndef WX_PRECOMP
    #include "wx/utils.h" // for wxLaunchDefaultBrowser
    #include "wx/dcclient.h"
    #include "wx/menu.h"
    #include "wx/log.h"
#endif

#include "wx/clipbrd.h"
#include "wx/dataobj.h"

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

IMPLEMENT_DYNAMIC_CLASS(wxHyperlinkCtrl, wxControl)
IMPLEMENT_DYNAMIC_CLASS(wxHyperlinkEvent, wxCommandEvent)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_HYPERLINK)

// reserved for internal use only
#define wxHYPERLINKCTRL_POPUP_COPY_ID           16384

// ----------------------------------------------------------------------------
// wxHyperlinkCtrl
// ----------------------------------------------------------------------------

BEGIN_EVENT_TABLE(wxHyperlinkCtrl, wxControl)
    EVT_PAINT(wxHyperlinkCtrl::OnPaint)
    EVT_LEFT_DOWN(wxHyperlinkCtrl::OnLeftDown)
    EVT_LEFT_UP(wxHyperlinkCtrl::OnLeftUp)
    EVT_RIGHT_UP(wxHyperlinkCtrl::OnRightUp)
    EVT_ENTER_WINDOW(wxHyperlinkCtrl::OnEnterWindow)
    EVT_LEAVE_WINDOW(wxHyperlinkCtrl::OnLeaveWindow)

    // for the context menu
    EVT_MENU(wxHYPERLINKCTRL_POPUP_COPY_ID, wxHyperlinkCtrl::OnPopUpCopy)
END_EVENT_TABLE()

bool wxHyperlinkCtrl::Create(wxWindow *parent, wxWindowID id,
    const wxString& label, const wxString& url, const wxPoint& pos,
    const wxSize& size, long style, const wxString& name)
{
    wxASSERT_MSG(!url.empty() || !label.empty(),
                 wxT("Both URL and label are empty ?"));

    if (!wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name))
        return false;

    // set to non empty strings both the url and the label
    if(url.empty())
        SetURL(label);
    else
        SetURL(url);

    if(label.empty())
        SetLabel(url);
    else
        SetLabel(label);

    // by default the cursor to use in this window is wxCURSOR_HAND
    SetCursor(wxCursor(wxCURSOR_HAND));

    m_rollover = false;
    m_clicking = false;
    m_visited = false;

    // colours
    m_normalColour = *wxBLUE;
    m_hoverColour = *wxRED;
    SetForegroundColour(m_normalColour);

    // by default the font of an hyperlink control is underlined
    wxFont f = GetFont();
    f.SetUnderlined(true);
    SetFont(f);

    CacheBestSize(DoGetBestSize());
    SetMinSize(GetBestSize());
    SetSize (DoGetBestSize());

    return true;
}

wxSize wxHyperlinkCtrl::DoGetBestSize() const
{
    int w, h;

    wxClientDC dc((wxWindow *)this);
    dc.SetFont(GetFont());
    dc.GetTextExtent(GetLabel(), &w, &h);

    return wxSize(w, h);
}

void wxHyperlinkCtrl::DoGetSize(int *width, int *height) const
{
    if (width) *width = GetBestSize().GetWidth();
    if (height) *height = GetBestSize().GetHeight();
}

void wxHyperlinkCtrl::SetNormalColour(const wxColour &colour)
{
    m_normalColour = colour;
    if (!m_visited)
    {
        SetForegroundColour(m_normalColour);
        Refresh();
    }
}

void wxHyperlinkCtrl::SetVisitedColour(const wxColour &colour)
{
    m_visitedColour = colour;
    if (m_visited)
    {
        SetForegroundColour(m_visitedColour);
        Refresh();
    }
}

void wxHyperlinkCtrl::DoContextMenu(const wxPoint &pos)
{
    wxMenu *menuPopUp = new wxMenu(wxEmptyString, wxMENU_TEAROFF);
    menuPopUp->Append(wxHYPERLINKCTRL_POPUP_COPY_ID, wxT("Copy URL"));
    PopupMenu( menuPopUp, pos );
    delete menuPopUp;
}



// ----------------------------------------------------------------------------
// wxHyperlinkCtrl - event handlers
// ----------------------------------------------------------------------------

void wxHyperlinkCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
{
    wxPaintDC dc(this);
    dc.SetFont(GetFont());
    dc.SetTextForeground(GetForegroundColour());
    dc.SetTextBackground(GetBackgroundColour());
    dc.DrawText(GetLabel(), 0, 0);
}

void wxHyperlinkCtrl::OnLeftDown(wxMouseEvent& WXUNUSED(event))
{
    m_clicking = true;
}

void wxHyperlinkCtrl::OnLeftUp(wxMouseEvent& WXUNUSED(event))
{
    if (!m_clicking) return;

    SetForegroundColour(m_visitedColour);
    m_visited = true;
    m_clicking = false;

    // send the event
    wxHyperlinkEvent linkEvent(this, GetId(), m_url);
    if (!GetEventHandler()->ProcessEvent(linkEvent))     // was the event skipped ?
        if (!wxLaunchDefaultBrowser(m_url))
            wxLogWarning(wxT("Could not launch the default browser with url '%s' !"), m_url.c_str());
}

void wxHyperlinkCtrl::OnRightUp(wxMouseEvent& event)
{
    if( GetWindowStyle() & wxHL_CONTEXTMENU )
        DoContextMenu(wxPoint(event.m_x, event.m_y));
}

void wxHyperlinkCtrl::OnEnterWindow(wxMouseEvent& WXUNUSED(event))
{
    SetForegroundColour(m_hoverColour);
    m_rollover = true;
    Refresh();
}

void wxHyperlinkCtrl::OnLeaveWindow(wxMouseEvent& WXUNUSED(event))
{
    if (m_rollover)
    {
        SetForegroundColour(!m_visited ? m_normalColour : m_visitedColour);
        m_rollover = false;
        Refresh();
    }
}

void wxHyperlinkCtrl::OnPopUpCopy( wxCommandEvent& WXUNUSED(event) )
{
#if wxUSE_CLIPBOARD
    if (!wxTheClipboard->Open())
        return;

    wxTextDataObject *data = new wxTextDataObject( m_url );
    wxTheClipboard->SetData( data );
    wxTheClipboard->Close();
#endif // wxUSE_CLIPBOARD
}

#endif // wxUSE_HYPERLINKCTRL
