/////////////////////////////////////////////////////////////////////////////
// Name:        wxHyperLink.cpp
// Purpose:     wxHyperLink
// Author:      Hans Van Leemputten
// Modified by:
// Created:     03/11/2001
// RCS-ID:      $Id: wxHyperLink.cpp,v 1.6 2001/04/23 21:52:10 vlabella Exp $
// Copyright:   (c) Hans Van Leemputten
// Licence:     wxWindows license
/////////////////////////////////////////////////////////////////////////////

#ifdef __GNUG__
#pragma implementation "wxHyperLink.h"
#endif

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

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

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

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

#ifdef __WXMSW__	
#include "wx/msw/registry.h"
#endif
#ifdef __GNUWIN32__
#include "windows.h"
#endif
#include "wx/stattext.h"
#include "wx/pmf/wxHyperLink.h"

// wxHyperLink.cpp : implementation file
//

IMPLEMENT_DYNAMIC_CLASS(wxHyperLink, wxStaticText)

BEGIN_EVENT_TABLE(wxHyperLink, wxStaticText)
    EVT_ENTER_WINDOW(wxHyperLink::OnActivate)
	EVT_LEAVE_WINDOW(wxHyperLink::OnDeActivate)
	EVT_LEFT_DOWN(wxHyperLink::OnClick)
	EVT_LEFT_UP(wxHyperLink::OnClick)
END_EVENT_TABLE()


/////////////////////////////////////////////////////////////////////////////
// wxHyperLink

/* Constructor */
wxHyperLink::wxHyperLink(wxWindow* parent, wxWindowID id, 
					 const wxString& url,
					 const wxString& label, 
					 const wxColour& normal,
					 const wxColour& active,
					 const wxPoint& pos, 
					 const wxSize& size, 
					 long style, 
					 const wxString& name)
{
	Create(parent, id, url, label, normal, active, pos, size, style, name);
}

/* Destructor */
wxHyperLink::~wxHyperLink()
{
}

bool wxHyperLink::Create(wxWindow* parent, wxWindowID id, 
					 const wxString& url,
					 const wxString& label, 
					 const wxColour& normal,
					 const wxColour& active,
					 const wxPoint& pos, 
					 const wxSize& size, 
					 long style, 
					 const wxString& name)
{	
	bool bReturn = false;
	
	bReturn = wxStaticText::Create(parent, id, label, pos, size, style, name);
	wxASSERT_MSG(bReturn, wxT("Failed to create wxStaticText, needed by wxHyperLink!"));	

	// Set the Mouse cursor to change to a hand when it passes over the lable...
	SetCursor(wxCURSOR_HAND);

	// Set the colour
	if (active == wxNullColour)
		bReturn = bReturn && SetForegroundColour(normal);
	else
		bReturn = bReturn && SetColour(normal, active);

	// Set the url and label
	SetURL(url, label);

	m_bActive = false;

	return bReturn;
}

/* Set 2 colours with the use of one colour. */
bool wxHyperLink::SetForegroundColour( const wxColour &colour )
{
	wxColour normal(*wxBLUE);

	// Make sure the colour is ok!
	if (colour != wxNullColour)
		normal = colour;

	//wxASSERT_MSG(colour!=wxNullColour, wxT("wxHyperLink colour can not be wxNullColour!"));
	
	wxColour active(CallcColour(normal.Red()), CallcColour(normal.Green()), CallcColour(normal.Blue()));
	return SetColour(normal, active);
}

bool wxHyperLink::SetColour( const wxColour &colourNormal, const wxColour &colourActive )
{
	wxASSERT_MSG(colourNormal!=wxNullColour && colourActive!=wxNullColour, 
					wxT("wxHyperLink colour can not be wxNullColour!"));

	// Set members...
	m_ColourNormal = colourNormal;
	m_ColourActive = colourActive;

	return wxStaticText::SetForegroundColour(m_ColourNormal);
}


// This can be a done a lot better... but for the moment I don't care!
unsigned char wxHyperLink::CallcColour(unsigned char colour)
{
	if (colour != 0)
	{
		if (colour > 127)
			return colour - 100;
		else
			return colour + 100;
	}
	else
		return 0;
}

bool wxHyperLink::LoadLink()
{
	bool bResult = false;

#if defined(__WXMSW__)
	// First try ShellExecute()
    HINSTANCE result = ShellExecute(NULL, wxT("open"), m_strURL.c_str(), NULL, NULL, SW_SHOW);

    // If it failed, get the .htm regkey and lookup the program
    if ((UINT)result <= HINSTANCE_ERROR) 
	{
		wxRegKey Reg;
		wxString KeyPath;
		wxString RegRoot(wxT("HKEY_CLASSES_ROOT\\"));

		KeyPath = RegRoot + wxT(".htm");
		Reg.SetName(KeyPath);
        if (Reg.Exists()) 
		{
			KeyPath = RegRoot + Reg.GetName() + wxT("\\shell\\open\\command");
			Reg.SetName(KeyPath);

            if (Reg.Exists())
			{
				wxString cmd(Reg.GetName());
				int index;
				
				index = cmd.Find(wxT("\"%1\""));	// Check for this
				if (index > -1) cmd.Remove(index);  // If found remove the parameter
				index = cmd.Find(wxT("%1"));		// Check for the same thing, without quotes
				if (index > -1) cmd.Remove(index);	// If found remove the parameter
				
				cmd.Append(wxT(" "));
                cmd.Append(m_strURL);
                result = (HINSTANCE) WinExec(cmd.c_str(), SW_SHOW);
            }
        }
    }
	bResult = (((UINT)result) > HINSTANCE_ERROR);
#else /* __WXMSW__ */

//#define _FORCE_BUILD	
#ifdef _FORCE_BUILD // define _FORCE_BUILD to make it compile :-)
	wxMessageBox(wxT("wxHyperLink is not yet implemented for this OS.\nYou need to implement the LoadLink function for your OS."), 
				wxT("wxHyperLink load problem"), wxOK | wxICON_EXCLAMATION);
#else
	#error 'This interface has not been completely tested yet!'
#endif

	bResult = false;
#endif /* __WXMSW__ */

	return bResult;
}

void wxHyperLink::SetURL(const wxString &url, const wxString &label)
{
	// Should never be empty, if it is why do you need this?
	wxASSERT(!url.IsEmpty());

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

	m_strURL = url;
}

void wxHyperLink::GetURL(wxString &url, wxString &label)
{
	label = GetLabel();
	url = m_strURL;
}

void wxHyperLink::SetUnderline(bool bUnderline, bool bAlways)
{
	m_bUnderline = bUnderline;
	m_bUndelineAlways = bAlways;

	if (m_bUndelineAlways)
	{
		wxFont fontLink = wxControl::GetFont();
		fontLink.SetUnderlined(m_bUnderline);
		wxControl::SetFont(fontLink);
	}
	else
	{
		// test if we are not active.
		if (!m_bActive)
		{
			// if we are not active disable the line.
			wxFont fontLink = wxControl::GetFont();
			fontLink.SetUnderlined(false);
			wxControl::SetFont(fontLink);
		}		
	}
}

bool wxHyperLink::GetUnderline()
{
	if (m_bUndelineAlways && m_bUnderline)
		return true;
	else
	{
		// Test if we are currently active
		// Depending on the result we return our restult
		return (m_bActive && m_bUndelineAlways && m_bUnderline);	
	}

	// Default...
//	return false;  // cannot be reached
}

/////////////////////////////////////////////////////////////////////////////
// wxHyperLink message handlers

void wxHyperLink::OnActivate(wxMouseEvent &event)
{
	if (!m_bUndelineAlways && m_bUnderline)
	{
		wxFont fontLink = wxControl::GetFont();
		fontLink.SetUnderlined(true);
		wxControl::SetFont(fontLink);
	}

	wxStaticText::SetForegroundColour(m_ColourActive);
	// ReDraw to correct the color
	Refresh();

	m_bActive = true;
}

void wxHyperLink::OnDeActivate(wxMouseEvent &event)
{
	if (!m_bUndelineAlways && m_bUnderline)
	{
		wxFont fontLink = wxControl::GetFont();
		fontLink.SetUnderlined(false);
		wxControl::SetFont(fontLink);
	}

	wxStaticText::SetForegroundColour(m_ColourNormal);
	// ReDraw to correct the color
	Refresh();	

	m_bActive = false;
}

void wxHyperLink::OnClick(wxMouseEvent &event)
{
	// Needed to check if mouse Click is valid.
	// I know it is not foolproof...
	// Just a fast way to put some restriction on a Click
	static bool bButtonDown = false;

	if (event.ButtonDown(1))
		bButtonDown = true;

	if (event.ButtonUp(1) && bButtonDown)
	{
		LoadLink();
		bButtonDown = false;
	}
}
