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

#include <z_stdlib.hpp>
#include "m_group.hpp"

// -- undocumented group variables --
int zafGroupNavigation = XmTAB_GROUP;
int zafGroupTitleVtAlignment = XmALIGNMENT_CENTER;
int zafGroupTitleHzAlignment = XmALIGNMENT_BEGINNING;

// ----- ZafGroup -----------------------------------------------------------

ZafPositionStruct ZafGroup::ConvertToOSPosition(const ZafWindowObject *object,
	const ZafPositionStruct *position) const
{
	ZafPositionStruct newPosition = ZafWindowObject::ConvertToOSPosition(object, position);
	newPosition.column += ZAF_SHADOW_SIZE;
	newPosition.line += ZAF_SHADOW_SIZE;
	return (newPosition);
}

ZafPositionStruct ZafGroup::ConvertToZafPosition(const ZafWindowObject *object,
	const ZafPositionStruct *position) const
{
	ZafPositionStruct newPosition = ZafWindowObject::ConvertToZafPosition(object, position);
	newPosition.column -= ZAF_SHADOW_SIZE;
	newPosition.line -= ZAF_SHADOW_SIZE;
	return (newPosition);
}

#if defined(ZAF_DEFAULT_DRAW)
ZafEventType ZafGroup::Draw(const ZafEventStruct &, ZafEventType ccode)
{
	// Return the control code.
	return (ccode);
}

ZafEventType ZafGroup::DrawBorder(ZafRegionStruct &, ZafEventType ccode)
{
	return (ccode);
}
#endif

ZafEventType ZafGroup::Event(const ZafEventStruct &event)
{
	ZafWindowObject *object;

	// Check for zinc events.
	ZafEventType ccode = event.type;
	switch (ccode)
	{
	case S_REGISTER_OBJECT:
		ccode = ZafWindow::Event(event);

	 	// Reset the object navigation to be arrow keys.
		for (object = First(); object; object = object->Next())
			XtVaSetValues(object->screenID, XmNnavigationType, zafGroupNavigation, 0);
		break;

	case S_HOT_KEY:
		if (!Disabled() && event.key.value == hotKeyChar)
		{
			// See if the object has focus.
			if (!Focus())
				SetFocus(true);
		}
		else
			ccode = ZafWindow::Event(event);
		break;

	case N_SIZE:
	{
		Dimension clientWidth;
		Dimension clientHeight;
		XtVaGetValues(screenID, XmNwidth, &clientWidth, XmNheight, &clientHeight, 0);
		clientRegion.right = clientWidth - 2 * ZAF_SHADOW_SIZE;
		clientRegion.bottom = clientHeight - 2 * ZAF_SHADOW_SIZE;
		ccode = ZafWindow::Event(event);
	}
		break;

	case L_UP:
	case L_DOWN:
	case L_LEFT:
	case L_RIGHT:
		{
		ZafWindowObject *curObj = Current();
		ccode = ZafWindow::Event(event);
		if (AutoSelect() && curObj != Current() && Current())
		{
			curObj = Current();
			(curObj->*(curObj->memberUserFunction))(event, L_SELECT);
		}
		}
		break;
 
	// ----- Default operation -----
	default:
		ccode = ZafWindow::Event(event);
		break;
	}

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

ZafRegionStruct ZafGroup::MaxRegion(ZafWindowObject *object,
	ZafVtJustify vWeight, ZafHzJustify hWeight)
{
	if (object == this)
		return(clientRegion);
  	return (ZafWindow::MaxRegion(object, vWeight, hWeight));
}

ZafWindowObject *ZafGroup::NotifyFocus(ZafWindowObject *focusObject, bool setFocus)
{
	// Defer to the base class.
	ZafWindowObject *invalidObject = ZafWindow::NotifyFocus(focusObject, setFocus);
	focusObject = Current();

	// Check for automatic selection.
	if (AutoSelect() && !focusObject->Selected())
	{
		// Set the selected status.
		focusObject->SetSelected(true);

		// Call the associated user function.
		(focusObject->*(focusObject->memberUserFunction))(L_SELECT, L_SELECT);
	}

	// Return the object focus.
	return (invalidObject);
}

bool ZafGroup::SetDisabled(bool setDisabled)
{
	// Make sure the attribute has changed.
	if (disabled != setDisabled)
	{
		// Defer to the base class.
		ZafWindow::SetDisabled(setDisabled);

		// Update the title area.
		if (screenID)
		{
			Widget title = ((XmFrameRec *)XtParent(screenID))->frame.title_area;
			XtVaSetValues(title, XmNsensitive, Disabled(false) ? false : true, 0);
		}
	}

	// Return the current attribute.
	return (disabled);
}

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

ZafEventType ZafGroup::OSEvent(const ZafEventStruct &)
{
	return (S_ERROR);
}

ZafError ZafGroup::OSSetText(void)
{
	// Check for a valid widget.
	if (!screenID)
		return (ZAF_ERROR_INVALID);

	// Set the group label.
	Widget title = ((XmFrameRec *)XtParent(screenID))->frame.title_area;
	if (title && stringData)
	{
		// Update the title.
		char *osText = stringData->DynamicOSText();
		XmString label = XmStringCreate(osText, XmFONTLIST_DEFAULT_TAG);
		XtVaSetValues(title, XmNlabelString, label, 0);
		if (stringData->Length())
  			XtVaSetValues(title, XmNchildVerticalAlignment, XmALIGNMENT_CENTER, 0);
		else
			XtVaSetValues(title, XmNchildVerticalAlignment, XmALIGNMENT_WIDGET_TOP, 0);
		XmStringFree(label);
		delete []osText;

		// Determine the hot key.
		if (hotKeyIndex >= 0)
			XtVaSetValues(title, XmNmnemonic, ZafKeySym(stringData->Char(hotKeyIndex)), 0);
	}

	return (ZAF_ERROR_NONE);
}

OSWindowID ZafGroup::OSScreenID(ZafScreenIDType type) const
{
	// Return the client widget.
	if (type == ZAF_FRAMEID && screenID)
		return (XtParent(screenID));
	return (ZafWindowObject::OSScreenID(type));
}

void ZafGroup::OSRegisterObject(void)
{
	// Create the motif widget.
	char *name = zafCodeSet->ConvertToOSString(stringID, 0, false);
	screenID = XtVaCreateWidget(name,
		xmFrameWidgetClass, parent->OSScreenID(ZAF_CLIENTID),
		// user information
		XmNuserData, this,
		// miscellaneous
		XmNshadowThickness, Bordered() ? ZAF_SHADOW_SIZE : 0,
		XmNshadowType, XmSHADOW_ETCHED_OUT,
		XmNmarginWidth, 0,
		XmNmarginHeight, 0,
		0);

	// Create the client area.
	screenID = XtVaCreateManagedWidget(name,
		(WidgetClass)&MtfWindowClient::classRecord, screenID,
		// user information
		XmNuserData, this,
		// miscellaneous
		XmNresizePolicy, XmRESIZE_NONE,
		XmNtraversalOn, Noncurrent() ? false : true,
		XmNmarginWidth, 0, 
		XmNmarginHeight, 0,
		XmNchildType, XmFRAME_WORKAREA_CHILD,
		0);

	// Override translations.
	MtfWindowClient *mtfClient = MtfWindowClient::GetMotifWidget(screenID);
	mtfClient->OverrideTranslations();

	// Create the title.
	XtVaCreateManagedWidget(name,                            
		xmLabelWidgetClass, XtParent(screenID),
		// user information
		XmNuserData, this,
		// miscellaneous
		XmNlabelString, 0,
		XmNchildType, XmFRAME_TITLE_CHILD,
		XmNchildVerticalAlignment, zafGroupTitleVtAlignment,
		XmNalignment, zafGroupTitleHzAlignment,
		XmNsensitive, Disabled(false) ? false : true,
		0);
	OSSetText();

	// Add edit mode overrides.
	ZafEditModeRegister(this);

	// Add drag/drop capabilities.
	ZafDropSiteRegister(this);
}

ZafError ZafGroup::OSUpdatePalettes(ZafPaletteType zafTypes, ZafPaletteType osTypes)
{
	// Make sure the widget can be updated.
	if (!screenID || !AutomaticUpdate() || !SystemObject())
		return (ZAF_ERROR_INVALID);

	// Adjust the group.
	ZafWindow::OSUpdatePalettes(zafTypes, osTypes);

	// Adjust the group title's information.
	Pixel mtfForeground;
	XmFontList mtfFont = 0;
	Widget widget = ((XmFrameRec *)XtParent(screenID))->frame.title_area;
	XtVaGetValues(widget,
		XmNfontList, &mtfFont,
		XmNforeground, &mtfForeground,
		0);

	// Check the foreground.
	ZafPaletteStruct foreground = LogicalPalette(ZAF_PM_TEXT, ZAF_PM_NOT_SELECTED | ZAF_PM_ENABLED);
	if (foreground.colorForeground < ZAF_MAXCOLORS &&
		((ZafScreenDisplay *)display)->colorTable[foreground.colorForeground].pixel != mtfForeground)
		XtVaSetValues(widget, XmNforeground, ((ZafScreenDisplay *)display)->colorTable[foreground.colorForeground].pixel, 0);
	else if (foreground.colorForeground == ZAF_CLR_DEFAULT)
	{
		Pixel foreground;
		static XtResource resource = { "foreground", "Foreground", "Pixel", sizeof(Pixel), 0, "CallProc", _XmForegroundColorDefault };
		XtGetApplicationResources(widget, &foreground, &resource, 1, 0, 0);
		if (foreground != mtfForeground)
			XtVaSetValues(widget, XmNforeground, foreground, 0);
	}

	// Check the font.
	ZafPaletteStruct palette = LogicalPalette(ZAF_PM_TEXT, ZAF_PM_ACTIVE | ZAF_PM_ENABLED);
	if (palette.font >= 0 && mtfFont && ((ZafScreenDisplay *)display)->fontTable[palette.font] != mtfFont)
		XtVaSetValues(widget, XmNfontList, ((ZafScreenDisplay *)display)->fontTable[palette.font], 0);
	else if (palette.font == ZAF_FNT_DEFAULT)
	{
		XmFontList font = 0;
		static XtResource resource = { "fontList", "FontList", "FontList", sizeof(XmFontList), 0, "Immediate", (XtPointer)0 };
		XtGetApplicationResources(widget, &font, &resource, 1, 0, 0);
		if (font != mtfFont)
			XtVaSetValues(widget, XmNfontList, font, 0);
	}

	return (ZAF_ERROR_NONE);
}

