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

#include <time.h>
#include <z_sys.hpp>
#include <z_min.hpp>
#include <z_max.hpp>
#include <z_title.hpp>

#define ZAF_SYSTEM_BUTTON_INFO
#include "img_def.cpp"

// ----- ZafSystemButton --------------------------------------------------

ZafWindowObject *ZafSystemButton::Add(ZafWindowObject *object, ZafWindowObject *position)
{
	// Add the item to the menu.
	return (menu.Add(object, position));
}

#if defined(ZAF_DEFAULT_DRAW)
ZafEventType ZafSystemButton::Draw(const ZafEventStruct &event, ZafEventType ccode)
{
	// Compute the actual draw region.
	ZafPaletteState state = PaletteState();
	ZafRegionStruct drawRegion = BeginDraw();

	display->SetClipRegion(event.region);

	ZafPaletteStruct palette;
	ZafWindow *parentWindow = DynamicPtrCast(parent, ZafWindow);
	ZafWindowObject *title = parentWindow->Title();
	if (title)
		palette = title->LogicalPalette(ZAF_PM_TEXT, state);
	else
		palette = LogicalPalette(ZAF_PM_TEXT, state);

	display->SetPalette(palette);

	int bitmapWidth = bitmapData->Width();
	int bitmapHeight = bitmapData->Height();
	int fieldHeight = zafRegion.Height();
	int left = (zafRegion.Width() - bitmapWidth) / 2;
	int top = (fieldHeight - bitmapHeight) / 2;

	display->Rectangle(drawRegion, 0, true);
	display->Bitmap(left, top, *bitmapData);

	EndDraw();

	return (ccode);
}
#endif

ZafEventType ZafSystemButton::Event(const ZafEventStruct &event)
{
	static bool close;
	static ZafWindowObject *lastSelected = ZAF_NULLP(ZafWindowObject);

	ZafWindow *parentWindow = DynamicPtrCast(parent, ZafWindow);

	ZafEventType ccode = LogicalEvent(event);

	// Check for zinc events.
	switch (ccode)
	{
	// ----- Create messages -----
	case S_INITIALIZE:
		SetBitmapData(sysBitmap);

		// Initialize the generic system button.
		if (SystemButtonType() == ZAF_NATIVE_SYSTEM_BUTTON && !menu.First())
		{
			// Set to empty so SetSystemButtonType() will populate the menu when
			// reset to ZAF_NATIVE_SYSTEM_BUTTON.
			SetSystemButtonType(ZAF_EMPTY_SYSTEM_BUTTON);

			// Populate the system menu.
			SetSystemButtonType(ZAF_NATIVE_SYSTEM_BUTTON);
		}
		ZafButton::Event(event);
		break;

	case S_COMPUTE_SIZE:
		ZafWindowObject::Event(event);
#if defined(ZAF_GRAPHICS_MODE)
		zafRegion.bottom = zafRegion.top + (display->cellHeight - display->preSpace - display->postSpace - 3);
		zafRegion.right = zafRegion.left + (display->cellHeight - display->preSpace - display->postSpace);
#else
        zafRegion.bottom = zafRegion.top;
        zafRegion.right = zafRegion.left + 2;
#endif
		break;

	// ----- Actions -----
	case L_CONTINUE_SELECT:
		break;

	case L_BEGIN_SELECT:
		{
			close = false;

			// Close the menu if it is already open.
			if (menu.First() && windowManager->Index(&menu) != -1)
			{
				windowManager->Event(S_CLOSE_TEMPORARY);
		  		break;
			}
			lastSelected = this;
		}

		// Continue to L_SELECT.
	case L_SELECT:
		if (menu.First() && !close)
		{
			if (windowManager->Index(&menu) != -1)
				break;
			menu.parent = this;
	 		menu.zafRegion.coordinateType = ZAF_PIXEL;
			ZafPositionStruct origin;
/* START BLOCK COMMENT
**				if (parentWindow->Minimized())
**				{
**					origin.column = 0;
**					origin.line = 0;
**					origin.coordinateType = parent->zafRegion.coordinateType;
**					origin = parent->ConvertToOSPosition(parent, &origin);
**				}
**				else
END BLOCK COMMENT */
			{
				origin.column = zafRegion.left;
				origin.line = zafRegion.bottom;
				origin.coordinateType = zafRegion.coordinateType;
				origin = parent->ConvertToOSPosition(this, &origin);
			}
			menu.zafRegion.left = origin.column;
			menu.zafRegion.top = origin.line;

#if defined(ZAF_TEXT_MODE)
			menu.zafRegion.top++;
#endif
			if (menu.Current())
			{
				menu.Current()->SetFocus(false);
				menu.SetCurrent(ZAF_NULLP(ZafElement));
			}
			for (ZafPopUpItem *object = DynamicPtrCast(menu.First(), ZafPopUpItem);
				object; object = DynamicPtrCast(object->Next(), ZafPopUpItem))
			{
				switch (object->ItemType())
				{
					case ZAF_RESTORE_OPTION:
						if (parentWindow->Maximized() || parentWindow->Minimized())
							object->SetDisabled(false);
						else
							object->SetDisabled(true);
						break;

					case ZAF_MOVE_OPTION:
						if (!parentWindow->Moveable() || parentWindow->Maximized())
							object->SetDisabled(true);
						else
							object->SetDisabled(false);
						break;

					case ZAF_SIZE_OPTION:
						if (!parentWindow->Sizeable() || parentWindow->Maximized() ||
							parentWindow->Minimized())
							object->SetDisabled(true);
						else
							object->SetDisabled(false);
						break;

					case ZAF_MINIMIZE_OPTION:
					case ZAF_MAXIMIZE_OPTION:
						{
							if ((parentWindow->Minimized() && object->ItemType() == ZAF_MINIMIZE_OPTION) ||
								(parentWindow->Maximized() && object->ItemType() == ZAF_MAXIMIZE_OPTION))
							{
								object->SetDisabled(true);
								break;
							}
							ZafWindowObject *pObject;
							if (object->ItemType() == ZAF_MINIMIZE_OPTION)
								pObject = parentWindow->MinimizeButton();
							else
								pObject = parentWindow->MaximizeButton();
							if (!pObject)
								object->SetDisabled(true);
							else
								object->SetDisabled(false);
						}
						break;

					case ZAF_CLOSE_OPTION:
						if (parentWindow->Locked())
							object->SetDisabled(true);
						else
							object->SetDisabled(false);
						break;

					case ZAF_ABOUT_OPTION:
					case ZAF_COPY_OPTION:
					case ZAF_CUT_OPTION:
					case ZAF_EXIT_OPTION:
					case ZAF_NORMAL_ITEM:
					case ZAF_PASTE_OPTION:
					case ZAF_SEPARATOR:
					case ZAF_SWITCH_OPTION:
						// Do nothing.
						break;
				}

				if (!menu.Current() && !object->Disabled())
				{
					object->SetFocus(true);
					menu.SetCurrent(object);
				}
			}
			windowManager->Add(&menu);
		}
/* START BLOCK COMMENT
**			else
**				ZafButton::Event(event);
END BLOCK COMMENT */
		break;

	case L_DOUBLE_CLICK:
		close = true;
		break;

	case L_END_SELECT:
		if (close)
		{
			bool canClose = false;

			for (ZafPopUpItem *object = DynamicPtrCast(menu.First(), ZafPopUpItem);
				object; object = DynamicPtrCast(object->Next(), ZafPopUpItem))
				if (object->ItemType() == ZAF_CLOSE_OPTION)
					canClose = true;

			if (parent->parent && canClose)
			{
//				windowManager->Event(S_CLOSE_TEMPORARY);
				eventManager->Put(S_MDI_CLOSE);
			}
			else if (!parentWindow->Locked() && canClose)
			{
//				windowManager->Event(S_CLOSE_TEMPORARY);
  				eventManager->Put(S_CLOSE);
			}

		}
		break;

	// ----- Miscellaneous messages -----
	case S_ADD_OBJECT:
	case S_SUBTRACT_OBJECT:
		menu.Event(event);
		break;


	case N_NON_CURRENT:
//	case S_NON_CURRENT:
/* START BLOCK COMMENT
**			if (windowManager->windowFocusObject &&
**				windowManager->windowFocusObject->RootObject() == RootObject())
END BLOCK COMMENT */
		if (windowManager->windowFocusObject)
		{
			ZafWindowObject *tFocusObject = windowManager->windowFocusObject;
			windowManager->windowFocusObject = ZAF_NULLP(ZafWindowObject);
			tFocusObject->NotifyFocus(tFocusObject, true);
			ccode = 0;
			break;
		}

	// ----- Unknown or error messages -----
	default:
		ccode = ZafButton::Event(event);
		break;
	}

	// Return the control code.
	return (ccode);
}

ZafWindowObject *ZafSystemButton::Subtract(ZafWindowObject *object)
{
	return (menu.Subtract(object));
}

// ----- Attributes ---------------------------------------------------------

ZafSystemButtonType ZafSystemButton::SetSystemButtonType(ZafSystemButtonType setSystemButtonType)
{
	// Make sure the request is valid.
	if (systemButtonType == setSystemButtonType || screenID)
		return (systemButtonType);

	ZafSystemButton::systemButtonType = setSystemButtonType;

	// Destroy old system menu options.
	menu.Destroy();

	// Populate with generic items.
	if (systemButtonType == ZAF_NATIVE_SYSTEM_BUTTON)
	{
		ZafNumberID type[] = {ZAF_RESTORE_OPTION, ZAF_MOVE_OPTION,
			ZAF_SIZE_OPTION, ZAF_MINIMIZE_OPTION, ZAF_MAXIMIZE_OPTION,
			ZAF_SEPARATOR, ZAF_CLOSE_OPTION};

		// Add the pop-up menu items.
		ZafMessageData *messageData;
		ZafPopUpItem *popItem;
		for (int i = 0; i < 7; i++)
		{
			messageData = messages->GetMessageData(type[i]);
			popItem = new ZafPopUpItem(ZAF_NULLP(ZafIChar));
			if (messageData)
			{
				popItem->SetItemType((ZafPopUpItemType)type[i]);
				popItem->SetStringData(messageData);
				popItem->SetHotKey(messageData->HotKeyChar(),
					messageData->HotKeyIndex());
			}
			else
			{
				popItem->SetItemType((ZafPopUpItemType)type[i]);
				popItem->SetText(messages->GetMessage(type[i]));
			}
			if (type[i] != ZAF_SEPARATOR)
				popItem->SetSendMessageWhenSelected(true);
			menu.Add(popItem);
		}
	}

	return (systemButtonType);
}

// ----- OS Specific Functions ----------------------------------------------

void ZafSystemButton::OSRegisterObject(void)
{
	ZafButton::OSRegisterObject();
}

void ZafSystemButton::OSSize(void)
{
	ZafWindowObject::OSSize();
}

ZafError ZafSystemButton::OSUpdatePalettes(ZafPaletteType zafTypes, ZafPaletteType osTypes)
{
	// Skip the button level.
	return (ZafWindowObject::OSUpdatePalettes(zafTypes, osTypes));
}

