/******************************************************************************
 JXTextLink.cc

	Implements algorithms required to make portions of the text act
	like buttons.

	Derived classes must implement:

		GetLinkCount
			Returns the number of links in the text.

		GetLinkRange
			Returns the character range of the specified link.

		LinkClicked
			Take whatever action is appropriate for the specified link.

	BASE CLASS = JXTEBase

	Copyright © 1998 by John Lindal. All rights reserved.

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

#include <JXTextLink.h>

#include <JXDisplay.h>

#include <X11/cursorfont.h>

#include <jAssert.h>

/******************************************************************************
 Constructor

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

JXTextLink::JXTextLink
	(
	JXDisplay* 		display
	)
{
	itsLinkCursor     = display->CreateBuiltInCursor("XC_hand2", XC_hand2);
	itsMouseDownIndex = 0;
}

/******************************************************************************
 Destructor

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

JXTextLink::~JXTextLink()
{
}

/******************************************************************************
 LTAdjustCursor (virtual protected)

 If this returns kTrue, call DisplayCursor with the returned cursor, 
 otherwise, set the appropriate cursor.

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

JBoolean
JXTextLink::LTAdjustCursor
	(
	const JIndex 			charIndex,
	const JXKeyModifiers&	modifiers,
	const JIndexRange		selRange,
	JCursorIndex*			cursor
	)
{
	const JSize linkCount = GetLinkCount();
	if (linkCount > 0)
		{
		if (selRange.IsEmpty() || !selRange.Contains(charIndex))
			{
			for (JIndex i=1; i<=linkCount; i++)
				{
				const JIndexRange linkRange = GetLinkRange(i);
				if (linkRange.Contains(charIndex))
					{
					*cursor = itsLinkCursor;
					return kTrue;
					}
				}
			}
		}

	return kFalse;
}

/******************************************************************************
 LTHandleMouseDown (virtual protected)

 Call this if GetCaretLocation returns kTrue after handling the mouse.

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

void
JXTextLink::LTHandleMouseDown
	(
	const JIndex 			charIndex,
	const JXMouseButton		button,
	const JSize				clickCount,
	const JXButtonStates&	buttonStates,
	const JXKeyModifiers&	modifiers
	)
{
	itsMouseDownIndex = 0;
	if (button == kJXLeftButton && clickCount == 1 &&
		!modifiers.shift() && !modifiers.meta() && !modifiers.control())
		{
		itsMouseDownIndex = charIndex;
		}
}

/******************************************************************************
 LTHandleMouseUp (virtual protected)

 Call this if GetCaretLocation returns kTrue after handling the mouse.

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

void
JXTextLink::LTHandleMouseUp
	(
	const JIndex 			charIndex,
	const JXMouseButton		button,
	const JXButtonStates&	buttonStates,
	const JXKeyModifiers&	modifiers
	)
{
	if (charIndex == itsMouseDownIndex)
		{
		const JSize linkCount = GetLinkCount();
		for (JIndex i=1; i<=linkCount; i++)
			{
			const JIndexRange linkRange = GetLinkRange(i);
			if (linkRange.Contains(itsMouseDownIndex))
				{
				LinkClicked(i);
				break;
				}
			}
		}

	itsMouseDownIndex = 0;
}
