/***************************************************************************
 *   Copyright (C) 2005 by Joachim Friedrich                               *
 *   joachim.friedrich@biozentrum.uni-wuerzburg.de                         *
 *                                                                         *
 *   This file is part of profdist and cbcanalyzer                         *
 *                                                                         *
 *   Both profdist and cbcanalyzer are free software; you can redistribute * 
 *   it and/or modify it under the terms of the GNU General Public License * 
 *   as published by the Free Software Foundation; either version 2 of the * 
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   Profdist and cbcanalyzer are distributed in the hope that it will be  *
 *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty   *
 *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

/* This is a wxHyperlinksCtrl for static text boxes in wxWindows..
 * 
 * Copyright (C) 2001-2004 Angelo Mandato
 *
 * This code is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA
 */

/*//////////////// wxHyperlinksCtrl.cpp ///////////////////
	Last modified:	07/07/2004
	Author:			Angelo Mandato
	Version:		1.2
	Web:			http://www.spaceblue.com/code/
	Email:			angelo@spaceblue.com

	Note:			View wxHyperlinksCtrl.html for more information

	/// Contributors ///
	Name:			Mark McManus
	Email:			mmcmanus@scientificmetrics.com
	Notes:			Contributed code for the EVT_COMMAND_LINK_CLICKED event
					which is fired when AutoBrowse(false) is set and added
					DoPopup(false) to supress pop up menu to copy web link.
					Thanks Mark!

*/////////////////////////////////////////////////

#include "wxHyperlinksCtrl.h"
#include <wx/msgdlg.h>
#include <wx/mimetype.h>
#include <wx/app.h>
#include <wx/menu.h>
#include <wx/clipbrd.h>
#include <wx/wx.h>
#include <wx/event.h>
#include <wx/tooltip.h>

#ifdef __WIN32__
#include <windows.h>
#include <wx/msw/registry.h>
#endif



DEFINE_EVENT_TYPE(wxEVT_COMMAND_LINK_CLICKED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_LINK_MCLICKED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_LINK_RCLICKED)

BEGIN_EVENT_TABLE(wxHyperlinksCtrl, wxStaticText)
	EVT_MOUSE_EVENTS( wxHyperlinksCtrl::OnMouseEvent)
	EVT_MOTION(wxHyperlinksCtrl::OnMouseEvent)
  EVT_MENU(HYPERLINKS_POPUP_COPY, wxHyperlinksCtrl::OnPopUpCopy )
END_EVENT_TABLE()

wxHyperlinksCtrl::wxHyperlinksCtrl(wxWindow *parent, wxWindowID id, const wxString &label,
               const wxPoint &pos, const wxSize &size, int style, const wxString& name, const wxString& szURL )
			   : wxStaticText(parent, id, label, pos, size, style|wxPOPUP_WINDOW, name)
{
	if( szURL.IsEmpty() )
		m_szURL = label;
	else
		m_szURL = szURL;

	// Set Tooltip
	SetToolTip( m_szURL );

	// Set default properties
	ReportErrors(); // default: true
	SetUnderlines(); // default: true, true, true
	SetColours(); // default: blue, violet, blue
	SetVisited(); // default: false
	EnableRollover();// default: false
	SetBold(); // default: false
	SetLinkCursor(); // default: wxCURSOR_HAND

//**Added By Mark McManus
    AutoBrowse(); // default true
    DoPopup(); // default true
//**Mark McManus

  OpenInSameWindow(); // default false
	// Set control properties and refresh
	UpdateLink(true);
}

// Goto the specified URL
bool wxHyperlinksCtrl::GotoURL( const wxString &szUrl, const wxString &szBrowser, const bool &bReportErrors, const bool &bSameWinIfPossible )
{
  wxLogNull logOff;

	// Use the browser specified
	if(!szBrowser.IsEmpty() )
	{
		wxString szCmd = szBrowser;
		szCmd += " ";
		szCmd += szUrl; // URLs are encoded so no need to put them in quotes

		if( wxExecute( szCmd, FALSE) != 0 )
			return true;
		else
			DisplayError("Unable to launch specified browser.", bReportErrors);

    return false;
	}

#ifdef __WIN32__

  if( bSameWinIfPossible )
  {
	  HINSTANCE result = ShellExecute(NULL, _T("open"), szUrl.c_str(), NULL,NULL, SW_SHOW);

	  if( (unsigned int)result > HINSTANCE_ERROR )
		  return true;

	  // Hack for Firefox, it returns FNF, do not know why
	  if( (unsigned int)result == SE_ERR_FNF )
		  return true;
  }

	wxRegKey Regkey( "HKEY_CLASSES_ROOT\\http\\shell\\open\\command" );
	Regkey.Open();
	wxString szOpenWith = Regkey;

	wxString szCmd = "";
	if( szOpenWith.Find("%1") != -1 )
	{
		szCmd = szOpenWith;
		szCmd.Replace( "%1", "\"" + szUrl + "\"" );
	}
	else
	{
		// first strip the \" character from the front and parse out the string...
		szOpenWith.Trim(false);

		if( szOpenWith.GetChar(0) == '\"' )
		{
			szOpenWith.Remove(0, 1);
			int nEnd = szOpenWith.Find("\"");
			if( nEnd > 0 )
				szOpenWith.Remove(nEnd);
		}
		else
		{
			int nEnd = szOpenWith.Find(" ");
			if( nEnd > 0 )
				szOpenWith.Remove(nEnd);
		}
		
		szCmd.Printf("\"%s\" \"%s\"", szOpenWith.c_str(), szUrl.c_str() );
	}

	if( wxExecute( szCmd, FALSE) != 0 )
		return true;
	else
	{
		DisplayError("Unable to launch default browser.", bReportErrors);
		return false;
	}
	
#endif
	// Untested code follows
	wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension( wxT("html") );
	if ( !ft )
	{
		DisplayError("Impossible to determine the file type for extension html", bReportErrors);
		return false;
	}

	wxString cmd;
	bool bResult = ft->GetOpenCommand(&cmd, wxFileType::MessageParameters( szUrl, "" ));
	delete ft;

	if (!bResult)
	{
		DisplayError("Unable to retrieve command information", bReportErrors);
		return false;
	}

	bResult = (wxExecute( cmd, FALSE) != 0);
  if( !bResult )
    DisplayError("Unable to launch browser.", bReportErrors);

	return bResult;
}

// Capture mouse events for Cursor, Link colors and Underlines
void wxHyperlinksCtrl::OnMouseEvent(wxMouseEvent& event)
{
	if ( !event.Moving() )
  {
    if ( event.Entering() )
		{
			SetCursor( m_crHand ); //wxCursor( wxCURSOR_HAND ) );

			if( m_bEnableRollover )
			{
				SetForegroundColour(m_crLinkRolloverColor);
				wxFont fontTemp = GetFont();
				fontTemp.SetUnderlined( m_bRolloverUnderline );
				if( m_bBold )
					fontTemp.SetWeight(wxBOLD);

				SetFont( fontTemp );
				Refresh(true);
			}
		}
    else if ( event.Leaving() )
		{
			SetCursor( wxNullCursor );
			if( m_bEnableRollover )
				UpdateLink(true);
		}
    else if( !event.Moving() )
    {
      if ( event.LeftUp() ) 
      {
				if( m_bAutoBrowse )
        {
					GotoURL( m_szURL, m_szBrowserPath, m_bReportErrors, m_bSameWinIfPossible );
        }
        else
        {
          wxPoint posOnParent = GetPosition();
          posOnParent.x += event.GetPosition().x;
          posOnParent.y += event.GetPosition().y;

				  wxHyperlinkEvent eventOut(wxEVT_COMMAND_LINK_CLICKED, GetId());
				  eventOut.SetEventObject(this);
				  eventOut.SetPosition( posOnParent );
				  wxPostEvent( GetParent(), eventOut );
        }

				SetVisited( true );
      }
      else if ( event.RightUp() )
      {
				//**Modified By Mark McManus, enhanced by Angelo Mandato
        if( m_bDoPopup )
        {
					wxMenu *menuPopUp = new wxMenu("", wxMENU_TEAROFF);
					menuPopUp->Append(HYPERLINKS_POPUP_COPY, "Copy");
					PopupMenu( menuPopUp, wxPoint( event.m_x, event.m_y ) );
					delete menuPopUp; // ADDED 06/30/2004 (prevents memory leaks)
        }
				else
				{
          wxPoint posOnParent = GetPosition();
          posOnParent.x += event.GetPosition().x;
          posOnParent.y += event.GetPosition().y;

				  wxHyperlinkEvent eventOut(wxEVT_COMMAND_LINK_RCLICKED, GetId());
				  eventOut.SetEventObject(this);
				  eventOut.SetPosition( posOnParent );
				  wxPostEvent( GetParent(), eventOut );
				}
        //**Mark McManus
      }
      else if( event.MiddleUp() )
      {
        wxPoint posOnParent = GetPosition();
        posOnParent.x += event.GetPosition().x;
        posOnParent.y += event.GetPosition().y;

				wxHyperlinkEvent eventOut(wxEVT_COMMAND_LINK_MCLICKED, GetId());
				eventOut.SetEventObject(this);
				eventOut.SetPosition( posOnParent );
				wxPostEvent( GetParent(), eventOut );
      }
    }
  }

	event.Skip();
}

void wxHyperlinksCtrl::OnPopUpCopy( wxCommandEvent &event )
{
  wxTheClipboard->UsePrimarySelection();

  if (!wxTheClipboard->Open())
    return;

  wxTextDataObject *data = new wxTextDataObject( m_szURL );
  wxTheClipboard->SetData( data );
  wxTheClipboard->Close();
}

void wxHyperlinksCtrl::UpdateLink(const bool &bRefresh)
{
	wxFont fontTemp = GetFont();

	if( m_bVisited )
	{
		SetForegroundColour( m_crVisitedColour );
		fontTemp.SetUnderlined( m_bVisitedUnderline );
	}
	else
	{
		SetForegroundColour( m_crLinkColour );
		fontTemp.SetUnderlined( m_bLinkUnderline );
	}

	if( m_bBold )
		fontTemp.SetWeight(wxBOLD);

	SetFont( fontTemp );
	Refresh( bRefresh );
}

#ifdef __WIN95__
long wxHyperlinksCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{
	if (nMsg == WM_NCHITTEST)
		return (long)HTCLIENT;

	return wxStaticText::MSWWindowProc( nMsg, wParam, lParam );
}
#endif

void wxHyperlinksCtrl::DisplayError( const wxString &szError, const bool &bReportErrors )
{
	if( bReportErrors )
		wxMessageBox( szError, "Hyperlink Error", wxOK | wxCENTRE | wxICON_ERROR  );
}
