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

#include <w_app.hpp>
#include <z_icon1.hpp>
#include <z_string.hpp>

static const int ICON_OFFSET = 4;  // Space between image and text.

// ----- ZafIcon -----------------------------------------------------------

#if defined(ZAF_DEFAULT_DRAW)
ZafEventType ZafIcon::Draw(const ZafEventStruct &, ZafEventType ccode)
{
	// Begin the drawing operation.
	ZafRegionStruct drawRegion = BeginDraw();

	// Compute regions.
	ZafPaletteStruct textPalette = LogicalPalette(ZAF_PM_TEXT, PaletteState());
	display->SetPalette(textPalette);
	ZafRegionStruct textRegion;
	if (stringData)
		textRegion = display->TextSize(*stringData);
	else
	{
		textRegion.coordinateType = ZAF_PIXEL;
		textRegion.left = textRegion.top = 1;
		textRegion.right = textRegion.bottom = 0;
	}

	ZafRegionStruct imageRegion;
	imageRegion.coordinateType = ZAF_PIXEL;
	imageRegion.left = imageRegion.top = 1;
	imageRegion.right = imageRegion.bottom = 0;
	if (iconData)
	{
		imageRegion.right = iconData->width;
		imageRegion.bottom = iconData->height;
	}
	ComputeDrawRegions(drawRegion, imageRegion, textRegion, 4);

	if (ccode == S_REDISPLAY || ccode == S_REDISPLAY_REGION ||
		ccode == S_REDISPLAY_DATA || ccode == L_SELECT)
	{
		// Draw the icon image.
		if (iconData && ccode != L_SELECT)
			display->Icon(imageRegion.left, imageRegion.top, *iconData);

		// Draw the icon text.
		if (stringData)
		{
			DrawBackground(textRegion, ccode == L_SELECT ? S_REDISPLAY : ccode);

			if (Disabled())
			{
				ZafPaletteStruct lightPalette = textPalette;
				lightPalette.colorForeground = lightPalette.colorBackground;
				lightPalette.osPalette.colorForeground = lightPalette.osPalette.colorBackground;
				display->SetPalette(lightPalette);
				display->Text(textRegion.left + 1, textRegion.top + 1, textRegion.right + 1,
					textRegion.bottom + 1, *stringData, -1, ZAF_HZ_CENTER, ZAF_VT_CENTER, hotKeyIndex, false);
			}

			display->SetPalette(textPalette);
			display->Text(textRegion, *stringData, -1, ZAF_HZ_CENTER, ZAF_VT_CENTER, hotKeyIndex, false);
		}
	}

	// Draw the focus rect.
	DrawFocus(textRegion, ccode);

	// End the drawing operation.
	EndDraw();
	return (ccode);
}

ZafEventType ZafIcon::DrawFocus(ZafRegionStruct &region, ZafEventType ccode)
{
	// Draw the focus rectangle.
	return ZafWindowObject::DrawFocus(region, ccode);
}

ZafEventType ZafIcon::DrawShadow(ZafRegionStruct &region, int depth,
	ZafEventType ccode)
{
	return ZafWindowObject::DrawShadow(region, depth, ccode);
}
#endif

ZafEventType ZafIcon::Event(const ZafEventStruct &event)
{
	ZafEventType ccode = event.type;

	if (ccode == E_OSEVENT)
		return ZafIcon::OSEvent(event);

	// Process Zinc events.
	switch (ccode)
	{
	case S_REGISTER_OBJECT:
		if (iconData && iconData->handle && !iconData->array)
			display->ConvertToZafIcon(*iconData);
		else if (iconData && iconData->array && !iconData->handle)
			display->ConvertToOSIcon(*iconData);

		if (iconType == ZAF_MINIMIZE_ICON)
		{
			systemObject = false;
			screenID = parent->OSScreenID(ZAF_FRAMEID);
#if defined(ZAF_WIN32)
			::SendMessage(screenID, WM_SETICON, (WPARAM)TRUE, (LPARAM)iconData->handle);
//??? For task manager?
			::SendMessage(screenID, WM_SETICON, (WPARAM)FALSE, (LPARAM)iconData->handle);
#endif
		}
		else
			ccode = ZafWindowObject::Event(event);
		break;

	case S_COMPUTE_SIZE:
		{
		// Get the text size.
		display->SetDisplayContext(GetDC(screenID));
		display->SetFont(LogicalPalette(ZAF_PM_TEXT, 0).font);
		ZafRegionStruct textSize;
		if (stringData)
			textSize = display->TextSize(*stringData);
		else
		{
			textSize.coordinateType = ZAF_PIXEL;
			textSize.left = textSize.top = 1;
			textSize.right = textSize.bottom = 0;
		}
		ReleaseDC(screenID, display->RestoreDisplayContext());

		// Get the image size.
		ZafRegionStruct imageSize;
		imageSize.coordinateType = ZAF_PIXEL;
		imageSize.left = imageSize.top = 1;
		imageSize.right = imageSize.bottom = 0;
		if (iconData)
		{
			imageSize.right = iconData->width;
			imageSize.bottom = iconData->height;
		}

		// Zero out zafRegion so that it will be computed.
		zafRegion.right = zafRegion.left - 1;
		zafRegion.bottom = zafRegion.top - 1;
		ComputeDrawRegions(zafRegion, imageSize, textSize, 4);
		}
		break;

	case S_CURRENT:
	case S_NON_CURRENT:
		ccode = ZafWindowObject::Event(event);
		if (systemObject)
			Draw(event, ccode);
		break;

	case S_REDISPLAY:
	case S_REDISPLAY_REGION:
		if (screenID && AutomaticUpdate())
		{
			ZafEventStruct redisplayEvent(S_REDISPLAY_REGION);
			redisplayEvent.region = parent->ConvertToOSRegion(this,
				(ccode == S_REDISPLAY_REGION) ?
				&event.region : ZAF_NULLP(ZafRegionStruct));
			ccode = parent->Event(redisplayEvent);
		}
		break;

	default:
		ccode = ZafWindowObject::Event(event);
		break;
	}

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

bool ZafIcon::SetDisabled(bool setDisabled)
{
	ZafWindowObject::SetDisabled(setDisabled);
	RedisplayData();
	return disabled;
}

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

ZafEventType ZafIcon::OSEvent(const ZafEventStruct &event)
{
	if (editMode && event.InputType() == E_MOUSE)
		return (ZafWindowObject::Event(event));

	ZafEventType ccode = event.osEvent.message;

	switch (ccode)
	{
	case WM_LBUTTONDOWN:
		ccode = ZafWindowObject::OSEvent(event);
		if (!Disabled() && !Noncurrent())
			SetFocus(true);
		if (SelectOnDownClick())
			(this->*memberUserFunction)(event, L_SELECT);
		break;

	case WM_LBUTTONUP:
		if (!SelectOnDownClick() && !windowManager->dragObject)
			(this->*memberUserFunction)(event, L_SELECT);
		ccode = ZafWindowObject::OSEvent(event);
		break;

	case WM_LBUTTONDBLCLK:
		ccode = ZafWindowObject::OSEvent(event);
		if (SelectOnDoubleClick())
			(this->*memberUserFunction)(event, L_DOUBLE_CLICK);
		else if (SelectOnDownClick())
			(this->*memberUserFunction)(event, L_SELECT);
		break;

	default:
		ccode = ZafWindowObject::OSEvent(event);
	}

	return (ccode);
}

void ZafIcon::OSRegisterObject(void)
{
	DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS;
	DWORD dwExStyle = WS_EX_TRANSPARENT;
	if (visible)
		dwStyle |= WS_VISIBLE;
	screenID = ZafMSWindowsApp::CreateSubclassedWindow(this, NULL, dwStyle, ZAF_NULLP(ZafIChar), NULL, dwExStyle);
}

ZafError ZafIcon::OSSetImage(void)
{
	if (screenID && !SupportObject())
		Redisplay();

	return (ZAF_ERROR_NONE);
}

bool ZafIcon::SetSelected(bool tSelected)
{
	return ZafWindowObject::SetSelected(tSelected);
}

ZafError ZafIcon::OSSetText(void)
{
	if (screenID && parent->IsA(ID_ZAF_LIST) && parent->OSDraw())
		return (ZafWindowObject::OSSetText());

	if (screenID && !SupportObject())
	{
		Event(ZafEventStruct(S_COMPUTE_SIZE));
		OSSize();
		Redisplay();
	}
	return (ZAF_ERROR_NONE);
}

bool ZafIcon::SetVisible(bool tVisible)
{
	return ZafWindowObject::SetVisible(tVisible);
}

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

ZafError ZafIcon::OSUpdatePalettes(ZafPaletteType , ZafPaletteType )
{
	if (screenID)
	{
		Event(ZafEventStruct(S_COMPUTE_SIZE));
		OSSize();
		Redisplay();
	}

	return (ZAF_ERROR_NONE);
}

