//	Zinc Application Framework - Z_POPUP1.CPP
//	COPYRIGHT (C) 1990-1999.  All Rights Reserved.
//	Zinc Software Incorporated.  Pleasant Grove, Utah  USA

#include <z_popup.hpp>
#include <z_string.hpp>
#include <z_app.hpp>
#define ZAF_POPUP_INFO
#include "lang_def.cpp"
#include "img_def.cpp"

static ZafStringID _menuName = ZAF_ITEXT("menu");

// ----- ZafPopUpItem -------------------------------------------------------

ZafPopUpItem::ZafPopUpItem(ZafStringData *zStringData, ZafPopUpItemType tItemType) :
	ZafButton(0, 0, (int)(zStringData ? strlen(zStringData->Text()) : 1), 1,
		zStringData, ZAF_NULLP(ZafBitmapData), ZAF_FLAT_BUTTON),
	menu(0, 0), itemType(ZAF_NORMAL_ITEM)
{
	// Initialize the pop-up item information.
	SetAutoSize(false);

	// Check the image information.
	ImageAllocate();

	// Get message strings.
	messages = ZafLanguageManager::Allocate(className, defaultMessages);

	// Initialize the pop-up item information.
	SetItemType(tItemType);
	SetHzJustify(ZAF_HZ_LEFT);
	SetDepth(0);

	menu.parent = this;
	menu.SetStringID(_menuName);
}

ZafPopUpItem::ZafPopUpItem(const ZafIChar *text, ZafPopUpItemType tItemType) :
	ZafButton(0, 0, (int)(text ? strlen(text) : 1), 1, text,
		ZAF_NULLP(ZafBitmapData), ZAF_FLAT_BUTTON),
	menu(0, 0), itemType(ZAF_NORMAL_ITEM)
{
	// Initialize the pop-up item information.
	SetAutoSize(false);

	// Check the image information.
	ImageAllocate();

	// Get message strings.
	messages = ZafLanguageManager::Allocate(className, defaultMessages);

	// Initialize the pop-up item information.
	SetItemType(tItemType);
	SetHzJustify(ZAF_HZ_LEFT);
	SetDepth(0);

	menu.parent = this;
	menu.SetStringID(_menuName);
}

ZafPopUpItem::ZafPopUpItem(const ZafPopUpItem &copy) :
	ZafButton(copy), menu(copy.menu),
	itemType(copy.itemType)
{
	// Check the image information.
	ImageAllocate();

	// Get message strings.
	messages = ZafLanguageManager::Allocate(className, defaultMessages);

	// Initialize the pop-up item information.
	menu.parent = this;
}

ZafPopUpItem::~ZafPopUpItem(void)
{
	// Free the image information.
	ImageFree();

	// Free the language information.
	ZafLanguageManager::Free(messages);
}

ZafWindowObject *ZafPopUpItem::Add(ZafWindowObject *object, ZafWindowObject *position)
{
	if (screenID && !menu.First())
	{
#if defined(ZAF_MSWINDOWS)
		Event(S_DESTROY);
#endif
	 	ZafWindowObject *windowObject = menu.Add(object, position);
		Event(S_CREATE);

		return (windowObject);
	}

	return (menu.Add(object, position));
}

ZafWindowObject *ZafPopUpItem::Duplicate(void)
{
	return (new ZafPopUpItem(*this));
}

ZafWindowObject *ZafPopUpItem::FocusObject(void) const
{
	// Return a pointer to self.
	if (menu.Focus())
		return (menu.Current() ? menu.FocusObject() : (ZafWindowObject *)&menu);
	else if (focus)
		return ((ZafWindowObject *)this);
	return (ZAF_NULLP(ZafWindowObject));
}

ZafWindowObject *ZafPopUpItem::GetObject(ZafNumberID zNumberID)
{
	ZafWindowObject *match = ZafWindowObject::GetObject(zNumberID);
	if (!match)
		match = menu.GetObject(zNumberID);
	return (match);
}

ZafWindowObject *ZafPopUpItem::GetObject(const ZafIChar *zStringID)
{
	ZafWindowObject *match = ZafWindowObject::GetObject(zStringID);
	if (!match)
		match = menu.GetObject(zStringID);
	return (match);
}

#if defined(ZAF_UNICODE)
ZafWindowObject *ZafPopUpItem::GetObject(const char *matchID)
{
	ZafStringData tStringData(matchID);
	return (GetObject(tStringData.Text()));
}
#endif

#if defined(ZAF_TEXT_MODE)
void ZafPopUpItem::ImageAllocate(void) {}
void ZafPopUpItem::ImageFree(bool) {}
#else
void ZafPopUpItem::ImageAllocate(void)
{
	// Initialize the images.
	if (!popupArrowBitmap)
	{
		ZafI18nData::AddStaticModule(ImageFree);
		popupArrowBitmap = new ZafBitmapData(_popupArrow_ZafBitmap);
		popupArrowBitmap->staticHandle = true;
		popupArrowBitmap->SetDestroyable(false);
		popupArrowCurrentBitmap = new ZafBitmapData(_popupArrowCurrent_ZafBitmap);
		popupArrowCurrentBitmap->staticHandle = true;
		popupArrowCurrentBitmap->SetDestroyable(false);
		popupCheckBitmap = new ZafBitmapData(_popupCheck_ZafBitmap);
		popupCheckBitmap->staticHandle = true;
		popupCheckBitmap->SetDestroyable(false);
		popupCheckCurrentBitmap = new ZafBitmapData(_popupCheckCurrent_ZafBitmap);
		popupCheckCurrentBitmap->staticHandle = true;
		popupCheckCurrentBitmap->SetDestroyable(false);
	}
}

void ZafPopUpItem::ImageFree(bool globalRequest)
{
	// Destroy the static images.
	if (globalRequest && popupArrowBitmap)
	{
		popupArrowBitmap->staticHandle = false;
		delete popupArrowBitmap;
		popupArrowBitmap = ZAF_NULLP(ZafBitmapData);
		popupArrowCurrentBitmap->staticHandle = false;
		delete popupArrowCurrentBitmap;
		popupArrowCurrentBitmap = ZAF_NULLP(ZafBitmapData);
		popupCheckBitmap->staticHandle = false;
		delete popupCheckBitmap;
		popupCheckBitmap = ZAF_NULLP(ZafBitmapData);
		popupCheckCurrentBitmap->staticHandle = false;
		delete popupCheckCurrentBitmap;
		popupCheckCurrentBitmap = ZAF_NULLP(ZafBitmapData);
	}
}
#endif

bool ZafPopUpItem::IsA(ZafClassID compareID) const
{
	return ((compareID == classID) ? true : ZafButton::IsA(compareID));
}

bool ZafPopUpItem::IsA(ZafClassName compareName) const
{
	return (!strcmp(compareName, className) ? true : ZafButton::IsA(compareName));
}

const ZafPaletteStruct *ZafPopUpItem::MapClassPalette(ZafPaletteType type, ZafPaletteState state)
{
	const ZafPaletteStruct *palette = MapPalette(defaultPaletteMap, type, state);
	return (palette ? palette : ZafButton::MapClassPalette(type, state));
}

bool ZafPopUpItem::SetAcceptDrop(bool )
{
	// acceptDrop is false for this class.
	acceptDrop = false;
	return (acceptDrop);
}

bool ZafPopUpItem::SetAllowDefault(bool )
{
	// allowDefault is false for this class.
	allowDefault = false;
	return (allowDefault);
}

bool ZafPopUpItem::SetAutoRepeatSelection(bool )
{
	// autoRepeatSelection is false for this class.
	autoRepeatSelection = false;
	return (autoRepeatSelection);
}

bool ZafPopUpItem::SetAutoSize(bool )
{
	// autoSize is true for this class.
	autoSize = false;
	return (autoSize);
}

ZafError ZafPopUpItem::SetBitmapData(ZafBitmapData *)
{
	// bitmapData is null for this class.
	bitmapData = ZAF_NULLP(ZafBitmapData);
	return (ZAF_ERROR_INVALID);
}

bool ZafPopUpItem::SetBordered(bool )
{
	// bordered is false for this class.
	bordered = false;
	return (bordered);
}

ZafButtonType ZafPopUpItem::SetButtonType(ZafButtonType )
{
	// buttonType is ZAF_FLAT_BUTTON for this class.
	buttonType = ZAF_FLAT_BUTTON;
	return (buttonType);
}

bool ZafPopUpItem::SetCopyDraggable(bool )
{
	// copyDraggable is false for this class.
	copyDraggable = false;
	return (copyDraggable);
}

bool ZafPopUpItem::SetDepressed(bool )
{
	// depressed is false for this class.
	depressed = false;
	return (depressed);
}

int ZafPopUpItem::SetDepth(int )
{
	// depth is 0 for this class.
	depth = 0;
	return (depth);
}

ZafHzJustify ZafPopUpItem::SetHzJustify(ZafHzJustify )
{
	// hzJustify is ZAF_HZ_LEFT for this class.
	hzJustify = ZAF_HZ_LEFT;
	return (hzJustify);
}

ZafPopUpItemType ZafPopUpItem::SetItemType(ZafPopUpItemType newItemType)
{
	// Make sure the request is valid.
	if (itemType != newItemType && !screenID)
	{
		itemType = newItemType;

		// Check for special conditions.
		ZafIChar *message = ZAF_NULLP(ZafIChar);
		ZafIChar newHotKeyChar = 0;
		int newHotKeyIndex = -1;
		switch (itemType)
		{
		case ZAF_SEPARATOR:
			SetDisabled(true);
			SetNoncurrent(true);
			break;

		case ZAF_CLOSE_OPTION:
			memberUserFunction = (MemberUserFunction)&ZafButton::SendMessage;
			SetValue(S_CLOSE);
			message = messages->GetMessage(ZAF_CLOSE_OPTION, false,
				&newHotKeyChar, &newHotKeyIndex);
			break;

		case ZAF_MAXIMIZE_OPTION:
			memberUserFunction = (MemberUserFunction)&ZafButton::SendMessage;
			SetValue(S_MAXIMIZE);
			message = messages->GetMessage(ZAF_MAXIMIZE_OPTION, false,
				&newHotKeyChar, &newHotKeyIndex);
			break;

		case ZAF_MINIMIZE_OPTION:
			memberUserFunction = (MemberUserFunction)&ZafButton::SendMessage;
			SetValue(S_MINIMIZE);
			message = messages->GetMessage(ZAF_MINIMIZE_OPTION, false,
				&newHotKeyChar, &newHotKeyIndex);
			break;

		case ZAF_MOVE_OPTION:
			memberUserFunction = (MemberUserFunction)&ZafButton::SendMessage;
			SetValue(S_MOVE_MODE);
			message = messages->GetMessage(ZAF_MOVE_OPTION, false,
				&newHotKeyChar, &newHotKeyIndex);
			break;

		case ZAF_RESTORE_OPTION:
			memberUserFunction = (MemberUserFunction)&ZafButton::SendMessage;
			SetValue(S_RESTORE);
			message = messages->GetMessage(ZAF_RESTORE_OPTION, false,
				&newHotKeyChar, &newHotKeyIndex);
			break;

		case ZAF_SIZE_OPTION:
			memberUserFunction = (MemberUserFunction)&ZafButton::SendMessage;
			SetValue(S_SIZE_MODE);
			message = messages->GetMessage(ZAF_SIZE_OPTION, false,
				&newHotKeyChar, &newHotKeyIndex);
			break;

		case ZAF_COPY_OPTION:
			memberUserFunction = (MemberUserFunction)&ZafButton::SendMessage;
			SetValue(S_COPY);
			message = messages->GetMessage(ZAF_COPY_OPTION, false,
				&newHotKeyChar, &newHotKeyIndex);
			break;

		case ZAF_CUT_OPTION:
			memberUserFunction = (MemberUserFunction)&ZafButton::SendMessage;
			SetValue(S_CUT);
			message = messages->GetMessage(ZAF_CUT_OPTION, false,
				&newHotKeyChar, &newHotKeyIndex);
			break;

		case ZAF_PASTE_OPTION:
			memberUserFunction = (MemberUserFunction)&ZafButton::SendMessage;
			SetValue(S_PASTE);
			message = messages->GetMessage(ZAF_PASTE_OPTION, false,
				&newHotKeyChar, &newHotKeyIndex);
			break;

		case ZAF_EXIT_OPTION:
			memberUserFunction = (MemberUserFunction)&ZafButton::SendMessage;
			SetValue(S_EXIT);
			message = messages->GetMessage(ZAF_EXIT_OPTION, false,
				&newHotKeyChar, &newHotKeyIndex);
			break;

		case ZAF_SWITCH_OPTION:
		case ZAF_ABOUT_OPTION:
		case ZAF_NORMAL_ITEM:
		default:
			break;
		}

		// Set the pop-up item information.
		if (message && stringData)
		{
			// Do not notify the data manager.
			ZafUpdateType updateType = stringData->Update(this);
			stringData->SetUpdate(this, ZAF_UPDATE_NONE);
			stringData->SetText(message);
			SetHotKey(newHotKeyChar, newHotKeyIndex);
			stringData->SetUpdate(this, updateType);
		}
	}
	return (itemType);
}

bool ZafPopUpItem::SetLinkDraggable(bool )
{
	// linkDraggable is false for this class.
	linkDraggable = false;
	return (linkDraggable);
}

bool ZafPopUpItem::SetMoveDraggable(bool )
{
	// moveDraggable is false for this class.
	moveDraggable = false;
	return (moveDraggable);
}

bool ZafPopUpItem::SetParentDrawBorder(bool )
{
	// parentDrawBorder is false for this class.
	parentDrawBorder = false;
	return (parentDrawBorder);
}

bool ZafPopUpItem::SetParentDrawFocus(bool )
{
	// parentDrawFocus is false for this class.
	parentDrawFocus = false;
	return (parentDrawFocus);
}

bool ZafPopUpItem::SetParentPalette(bool )
{
	// parentPalette is false for this class.
	parentPalette = false;
	return (parentPalette);
}

ZafRegionType ZafPopUpItem::SetRegionType(ZafRegionType )
{
	// regionType is ZAF_INSIDE_REGION for this class.
	regionType = ZAF_INSIDE_REGION;
	return (regionType);
}

bool ZafPopUpItem::SetSelectOnDoubleClick(bool )
{
	// selectOnDoubleClick is false for this class.
	selectOnDoubleClick = false;
	return (selectOnDoubleClick);
}

bool ZafPopUpItem::SetSelectOnDownClick(bool )
{
	// selectOnDownClick is false for this class.
	selectOnDownClick = false;
	return (selectOnDownClick);
}

bool ZafPopUpItem::SetSupportObject(bool )
{
	// supportObject is false for this class.
	supportObject = false;
	return (supportObject);
}

ZafVtJustify ZafPopUpItem::SetVtJustify(ZafVtJustify )
{
	// vtJustify is ZAF_VT_CENTER for this class.
	vtJustify = ZAF_VT_CENTER;
	return (vtJustify);
}

ZafWindowObject *ZafPopUpItem::Subtract(ZafWindowObject *object)
{
 	ZafWindowObject *windowObject = menu.Subtract(object);
	if (screenID && !menu.First())
	{
		Event(S_DESTROY);
		Event(S_CREATE);
	}

	return (windowObject);
}

// ----- Persistent functions -----------------------------------------------
#if defined(USE_ZAF_PERSISTENCE)
ZafPopUpItem::ZafPopUpItem(const ZafIChar *name, ZafObjectPersistence &persist) :
	ZafButton(name, persist.PushLevel(className, classID, ZAF_PERSIST_DIRECTORY)),
	menu(0, 0), itemType(ZAF_NORMAL_ITEM)
{
	// Check the image information.
	ImageAllocate();

	// Get message strings.
	messages = ZafLanguageManager::Allocate(className, defaultMessages);
	if (persist.Error() == ZAF_ERROR_NONE)
		ZafPopUpItem::ReadData(persist);

	// Read the menu data.
	ZafIChar menuName[ZAF_MAXNAMELEN];
	ZafFile *file = persist.CurrentFile();
	*file >> menuName;
	if (*menuName)
	{
		menu.SetStringID(menuName);
		persist.PushLevel(menu.ClassName(), menu.ClassID(), ZAF_PERSIST_DIRECTORY);
		persist.AllocateFile(menu.StringID(), ZAF_FILE_READ);
		if (persist.Error() == ZAF_ERROR_NONE)
			menu.ZafWindowObject::ReadData(persist);
		if (persist.Error() == ZAF_ERROR_NONE)
			menu.ZafWindow::ReadData(persist);
		if (persist.Error() == ZAF_ERROR_NONE)
			menu.ZafWindow::ReadChildren(persist);
		persist.PopLevel();
	}
	menu.parent = this;

	persist.PopLevel();
	if (persist.Error() != ZAF_ERROR_NONE)
		SetError(persist.Error());
}

ZafElement *ZafPopUpItem::Read(const ZafIChar *name, ZafObjectPersistence &persist)
{
	return (new ZafPopUpItem(name, persist));
}

void ZafPopUpItem::ReadData(ZafObjectPersistence &persist)
{
	// Read the data.
	ZafUInt16 flag1;
	ZafFile *file = persist.CurrentFile();
	*file >> flag1;
	SetItemType((ZafPopUpItemType)flag1);
}

void ZafPopUpItem::Write(ZafObjectPersistence &persist)
{
	// Write the object.
	ZafButton::Write(persist.PushLevel(className, classID, ZAF_PERSIST_DIRECTORY));
	if (persist.Error() == ZAF_ERROR_NONE)
		ZafPopUpItem::WriteData(persist);

	if (menu.First() && !menu.StringID())
		menu.SetStringID(_menuName);

	// Write the menu data.
	const ZafIChar *menuName = menu.First() ? menu.StringID() : ZAF_NULLP(ZafIChar);
	ZafFile *file = persist.CurrentFile();
	*file << menuName;
	if (menu.First())
	{
		menu.Write(persist.PushLevel(menu.ClassName(), menu.ClassID(), ZAF_PERSIST_DIRECTORY));
		persist.PopLevel();
	}

	persist.PopLevel();
	if (persist.Error() != ZAF_ERROR_NONE)
		SetError(persist.Error());
}

void ZafPopUpItem::WriteData(ZafObjectPersistence &persist)
{
	// Write the data.
	ZafUInt16 flag1 = (ZafUInt16)itemType;
	ZafFile *file = persist.CurrentFile();
	*file << flag1;
}
#endif
