/******************************************************************************
 TestTextEditor.cc

	BASE CLASS = JXTextEditor

	Written by John Lindal.

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

#include "TestTextEditor.h"
#include <JXTextMenu.h>
#include <JXPSPrinter.h>
#include <JString.h>
#include <jAssert.h>

// Edit menu

static const JCharacter* kAutoIndentStr   = "Auto-indent";
static const JCharacter* kUndoDepthPrefix = "Undo depth ";

static const JSize kUndoDepth[] = { 1, 2, 3, 100 };
const JSize kUndoDepthCount     = sizeof(kUndoDepth)/sizeof(JSize);

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

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

TestTextEditor::TestTextEditor
	(
	const JBoolean		editable,
	JXMenuBar*			menuBar,
	JXScrollbarSet*		scrollbarSet,
	JXContainer*		enclosure,
	const HSizingOption	hSizing,
	const VSizingOption	vSizing,
	const JCoordinate	x,
	const JCoordinate	y,
	const JCoordinate	w,
	const JCoordinate	h
	)
	:
	JXTextEditor(menuBar, JXMenu::kWindowsStyle, scrollbarSet,
				 enclosure, hSizing, vSizing, x,y, w,h)
{
	if (!editable)
		{
		SetType(kSelectableText);
		}

	itsPrinter = new JXPSPrinter(GetDisplay(), GetColormap());
	assert( itsPrinter != NULL );
	SetPSPrinter(itsPrinter);

	// adjust the edit menu

	JXTextMenu* editMenu;
	const JBoolean ok = GetEditMenu(&editMenu);
	assert( ok );
	const JSize editCount = editMenu->GetItemCount();
	editMenu->ShowSeparatorAfter(editCount);

	itsAutoIndentCmdIndex = editCount + 1;
	editMenu->AppendItem(kAutoIndentStr, kTrue);

	editMenu->ShowSeparatorAfter(itsAutoIndentCmdIndex);
	itsFirstUndoDepthCmdIndex = itsAutoIndentCmdIndex + 1;
	for (JIndex i=0; i<kUndoDepthCount; i++)
		{
		JString undoDepthStr(kUndoDepth[i], 0);
		undoDepthStr.Prepend(kUndoDepthPrefix);
		editMenu->AppendItem(undoDepthStr, kTrue, kTrue);
		}
}

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

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

TestTextEditor::~TestTextEditor()
{
	delete itsPrinter;
}

/******************************************************************************
 Receive (virtual protected)

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

void
TestTextEditor::Receive
	(
	JBroadcaster*	sender,
	const Message&	message
	)
{
	JXTextMenu* editMenu;
	const JBoolean ok = GetEditMenu(&editMenu);
	assert( ok );

	if (sender == editMenu && message.Is(JXMenu::kNeedsUpdate))
		{
		UpdateCustomEditMenuItems();
		}
	else if (sender == editMenu && message.Is(JXMenu::kItemSelected))
		{
		const JXMenu::ItemSelected* selection =
			dynamic_cast(const JXMenu::ItemSelected*, &message);
		assert( selection != NULL );
		if (HandleCustomEditMenuItems(selection->GetIndex()))
			{
			return;
			}
		}

	JXTextEditor::Receive(sender, message);
}

/******************************************************************************
 UpdateCustomEditMenuItems (private)

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

void
TestTextEditor::UpdateCustomEditMenuItems()
{
	JXTextMenu* editMenu;
	const JBoolean ok = GetEditMenu(&editMenu);
	assert( ok );

	editMenu->EnableItem(itsAutoIndentCmdIndex);
	if (WillAutoIndent())
		{
		editMenu->CheckItem(itsAutoIndentCmdIndex);
		}

	const JSize undoDepth = GetUndoDepth();
	for (JIndex i=0; i<kUndoDepthCount; i++)
		{
		const JIndex itemIndex = itsFirstUndoDepthCmdIndex + i;
		editMenu->EnableItem(itemIndex);
		if (undoDepth == kUndoDepth[i])
			{
			editMenu->CheckItem(itemIndex);
			}
		}
}

/******************************************************************************
 HandleCustomEditMenuItems (private)

	Returns kTrue if it is one of our items.

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

JBoolean
TestTextEditor::HandleCustomEditMenuItems
	(
	const JIndex index
	)
{
	if (index == itsAutoIndentCmdIndex)
		{
		ShouldAutoIndent( JNegate(WillAutoIndent()) );
		return kTrue;
		}
	else if (index >= itsFirstUndoDepthCmdIndex)
		{
		SetUndoDepth(kUndoDepth[ index - itsFirstUndoDepthCmdIndex ]);
		return kTrue;
		}
	else
		{
		return kFalse;
		}
}
