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

#include <z_win.hpp>
#include <z_border.hpp>
#include <z_max.hpp>
#include <z_min.hpp>
#include <z_sys.hpp>
#include <z_title.hpp>
#include <z_icon1.hpp>
#include <z_string.hpp>

// ----- ZafWindow ----------------------------------------------------------

ZafWindow::ZafWindow(int left, int top, int width, int height) :
	ZafWindowObject(left, top, width, height),
	ZafList(), support(),
	// attributes
	defaultButton(ZAF_NULLP(ZafButton)),
	defaultDefaultButton(ZAF_NULLP(ZafButton)),
	destroyable(true), locked(false), maximized(false), minimized(false),
	modal(false), moveable(true), normalHotKeys(false),
	owner(ZAF_NULLP(ZafWindow)), selectionType(ZAF_SINGLE_SELECTION),
	sizeable(true), temporary(false), sizeToClient(true)
{
	// Initialize environment specific information.
#	if defined(ZAF_MSWINDOWS)
	frameID = 0;
#	elif defined(ZAF_MOTIF) || defined(ZAF_MACINTOSH)
	decorations = 0;
#	endif

	// Initialize the client region.
	clientRegion.coordinateType = ZAF_CELL;
	clientRegion.left = clientRegion.top = 0;
	clientRegion.right = width - 1;
	clientRegion.bottom = height - 1;

	// Pre-initialize default variables.
	restoreRegion.left = restoreRegion.top = 0;
	restoreRegion.right = restoreRegion.bottom = 0;
}

ZafWindow::ZafWindow(const ZafWindow &copy) :
	ZafWindowObject(copy),
	// attributes
	defaultButton(ZAF_NULLP(ZafButton)),
	defaultDefaultButton(ZAF_NULLP(ZafButton)),
	destroyable(copy.destroyable), locked(copy.locked),
	maximized(copy.maximized), minimized(copy.minimized), modal(copy.modal),
	moveable(copy.moveable), normalHotKeys(copy.normalHotKeys),
	owner(ZAF_NULLP(ZafWindow)), selectionType(copy.selectionType),
	sizeable(copy.sizeable), temporary(copy.temporary),
	clientRegion(copy.clientRegion), sizeToClient(true)
{
	// Copy environment specific information.
#	if defined(ZAF_MSWINDOWS)
	frameID = 0;
#	elif defined(ZAF_MOTIF) || defined(ZAF_MACINTOSH)
	decorations = copy.decorations;
#	endif

	// Pre-initialize default variables.
/* START BLOCK COMMENT
**		restoreRegion.left = restoreRegion.top = 0;
**		restoreRegion.right = restoreRegion.bottom = 0;
END BLOCK COMMENT */
	restoreRegion = copy.restoreRegion;

	// Copy the children.
	ZafWindowObject *object = copy.SupportFirst() ? copy.SupportFirst() : copy.First();
	while (object)
	{
		// Duplicate the object.
		Add(object->Duplicate());

		// Get the next object.
		object = (!object->Next() && object->SupportObject()) ? copy.First() : object->Next();
	}

	if (copy.defaultDefaultButton)
		SetDefaultButton(DynamicPtrCast(GetObject(copy.defaultDefaultButton->StringID()), ZafButton));
}

ZafWindow::~ZafWindow(void)
{
}

ZafWindow *ZafWindow::AddGenericObjects(const ZafIChar *title, ZafWindowObject *minObject)
{
	return (AddGenericObjects(new ZafStringData(title), minObject));
}

ZafWindow *ZafWindow::AddGenericObjects(ZafStringData *title, ZafWindowObject *minObject)
{
	// Add default window objects.
	Add(new ZafBorder);
	Add(new ZafMaximizeButton);
	Add(new ZafMinimizeButton);
	Add(new ZafSystemButton(ZAF_NATIVE_SYSTEM_BUTTON));
	Add(new ZafTitle(title));
	if (minObject)
		Add(minObject);

	// Return a pointer to the window.
	return (this);
}

void ZafWindow::BroadcastEvent(const ZafEventStruct &event, int levels)
{
	// Broadcast the event to all children.
	ZafWindowObject *object = SupportFirst() ? SupportFirst() : First();
	while (object)
	{
		object->Event(event);
		object = (!object->Next() && object->SupportObject()) ? First() : object->Next();
	}

	// Continue the broadcast.
	if (levels == -1 || levels > 0)
	{
		if (levels > 0)
			levels--;
		object = SupportFirst() ? SupportFirst() : First();
		while (object)
		{
			ZafWindow *window = DynamicPtrCast(object, ZafWindow);
			if (window)
				window->BroadcastEvent(event, levels);
			object = (!object->Next() && object->SupportObject()) ? First() : object->Next();
		}
	}
}

bool ZafWindow::Changed(void) const
{
	// Check the immediate flag.
	if (changed)
		return (true);

	// Check the children.
	for (ZafWindowObject *object = First(); object; object = object->Next())
		if (object->Changed())
			return (true);
	return (false);
}

ZafButton *ZafWindow::DefaultButton(bool defaultDefault) const
{
	ZafWindowObject *root = RootObject();
 	if (root != (ZafWindowObject *)this)
		return (DynamicPtrCast(root, ZafWindow)->DefaultButton(defaultDefault));
	else
		return (defaultDefault ? defaultDefaultButton : defaultButton);
}

void ZafWindow::Destroy(void)
{
	// Destroy the window elements (high level).
	OSDestroy();

	// Destroy the list elements (low level).
	ZafList::Destroy();
}

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

ZafWindowObject *ZafWindow::FocusObject(void) const
{
	// Return a pointer to self.
	if (current && Current()->focus)
		return (Current()->FocusObject());
	else if (focus)
		return ((ZafWindowObject *)this);
	return (ZAF_NULLP(ZafWindowObject));
}

#if defined(USE_ZAF_PERSISTENCE)
ZafDataName ZafWindow::GetCompareFunctionName(ZafCompareFunction function, ZafObjectPersistence &persist)
{
	return (persist.GetCompareFunctionName(function));
}
#endif

ZafWindowObject *ZafWindow::GetObject(ZafNumberID matchID)
{
	// Try to match on the current object.
	ZafWindowObject *match = ZafWindowObject::GetObject(matchID);

	// Special support numbers should only go 1 level deep.
	ZafWindowObject *object;
	if (!match && matchID < 0)
	{
		for (object = SupportFirst(); object && !match; object = object->Next())
			match = object->ZafWindowObject::GetObject(matchID);
	}
	// All others are depth first searches.
	else if (!match)
	{
		for (object = SupportFirst(); object && !match; object = object->Next())
			match = object->GetObject(matchID);
		for (object = First(); object && !match; object = object->Next())
			match = object->GetObject(matchID);
	}
	return (match);
}

ZafWindowObject *ZafWindow::GetObject(const ZafIChar *matchID)
{
	// Check for an exact match on the object.
	ZafWindowObject *match = ZafWindowObject::GetObject(matchID);
	if (match)
		return (match);

	// Re-point the arguments to do partial matching.
	ZafIChar parseID[ZAF_MAXNAMELEN];
	ZafIChar *tParseID = parseID;
	for ( ; *matchID && *matchID != ZAF_DIRECTORY_SEPARATOR; matchID++, tParseID++)
		*tParseID = *matchID;
	*tParseID = '\0';
	bool directory = false;
	if (*matchID == ZAF_DIRECTORY_SEPARATOR)
	{
		directory = true;
		matchID++;
	}

	// Try to match with one of the children.
	ZafWindowObject *object = SupportFirst() ? SupportFirst() : First();
	while (object && !match)
	{
		if (!directory)
			match = object->GetObject(parseID);
		else if (!streq(parseID, object->StringID()))
			match = *matchID ? object->GetObject(matchID) : object;
		object = (!object->Next() && object->SupportObject()) ? First() : object->Next();
	}
	return (match);
}

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

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

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

ZafLogicalEvent ZafWindow::LogicalEvent(const ZafEventStruct &event)
{
	ZafLogicalEvent ccode = MapEvent(defaultEventMap, event);
	return ((ccode == L_NONE) ? ZafWindowObject::LogicalEvent(event) : ccode);
}

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

ZafWindowObject *ZafWindow::NotifyFocus(ZafWindowObject *focusObject, bool setFocus)
{
	// Check for self notification.
	if (focusObject == this)
		return (ZafWindowObject::NotifyFocus(focusObject, setFocus));

#if defined(ZAF_INDEPENDENT)
	// Keep pointer to old current in case pull-down menu is becoming current.
	ZafWindowObject *oldCurrent = Current();
#endif
	// Check for algorithm direction.
	ZafWindowObject *invalidObject = ZAF_NULLP(ZafWindowObject);
	if (!setFocus) // down
	{
		if (screenID || Temporary())
		{
			// Remove focus from the current branch.
			if (Current())
				invalidObject = Current()->NotifyFocus(focusObject, false);

			// Remove focus from the "this"
			if (!invalidObject)
				invalidObject = ZafWindowObject::NotifyFocus(focusObject, false);
		}
	}
	else if (!focus) // up
	{
		// Recurse the entire focus path.  Give this object focus.
		invalidObject = ZafWindowObject::NotifyFocus(focusObject, true);

		if (screenID && !invalidObject && Current() && Current()->Event(S_VALID_CHECK) == S_ERROR)
		{
			invalidObject = this;
			Event(S_SET_FOCUS);
		}

		// Set focus if validation succeeded.
		if (!invalidObject)
			ZafList::SetCurrent(focusObject);
	}
	else // transition
	{
	 	// This window is the root of the focus path.  Transition focus
		// if focusObject doesn't already have it.
		if (Current() && Current() != focusObject)
			invalidObject = Current()->NotifyFocus(this, false);

		// Set focus if validation succeeded.
		if (!invalidObject)
			ZafList::SetCurrent(focusObject);
	}

	// Check for a default button, or pull-down menu.
	if (setFocus)
	{
		ZafButton *newDefaultButton = DefaultButton(true);
		if (newDefaultButton)
		{
			ZafButton *focusButton = DynamicPtrCast(focusObject, ZafButton);
			if (focusButton && focusButton->AllowDefault())
			{
				ZafButton *oldDefault = defaultButton;
				DynamicPtrCast(RootObject(), ZafWindow)->defaultButton = focusButton;
				if (screenID && oldDefault == newDefaultButton && oldDefault != focusButton)
					oldDefault->Event(S_REDISPLAY_DEFAULT);
			}
			else
				SetDefaultButton(newDefaultButton, false);
		}

#if defined(ZAF_INDEPENDENT)
		if (focusObject && !windowManager->windowFocusObject &&
			(focusObject->IsA(ID_ZAF_PULL_DOWN_MENU) ||
			focusObject->IsA(ID_ZAF_SYSTEM_BUTTON)))
			windowManager->windowFocusObject = oldCurrent;
#endif
	}

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

ZafWindowObject *ZafWindow::NotifySelection(ZafWindowObject *selectedObject, bool setSelected)
{
	// Check for a valid object.
	if (!selectedObject || selectedObject->SupportObject())
		return (selectedObject);

	// Update the old selected objects. If a window allows multiple 
	// selections, selecting and object doesn't affect other objects 
	// in the window.
	if (setSelected && SelectionType() == ZAF_SINGLE_SELECTION)
	{
		// Deselect all objects except "selectedObject."
		for (ZafWindowObject *object = First(); object; object = object->Next())
			if (object->Selected() && object != selectedObject)
				object->SetSelected(false);
	}
	else if (SelectionType() == ZAF_SINGLE_SELECTION)
	{
		// Check for a valid change of selection.
		ZafWindowObject *object = First();
		while (object)
			if (object->Selected() && object != selectedObject)
				break;
			else
				object = object->Next();

		// De-selection is not allowed, except within a combo box list.
		if (!object && !temporary)
			selectedObject->selected = true;
	}

	// Return the object selection.
	return (selectedObject);
}

bool ZafWindow::SetChanged(bool setChanged)
{
	// Check the immediate flag.
	ZafWindowObject::SetChanged(setChanged);

	// Only reset the children if the value is false.
	if (!changed)
	{
		for (ZafWindowObject *object = First(); object; object = object->Next())
			object->SetChanged(false);
	}

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

ZafCoordinateType ZafWindow::SetCoordinateType(ZafCoordinateType newCoordinateType)
{
	// Make sure the attribute has changed.
	if (coordinateType != newCoordinateType && !screenID)
		coordinateType = zafRegion.coordinateType = clientRegion.coordinateType = newCoordinateType;

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

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

ZafButton *ZafWindow::SetDefaultButton(ZafButton *newDefaultButton, bool defaultDefault)
{
	// Make sure the button is attached to the window.
	ZafWindowObject *root = RootObject();
 	if (root != this)
		return DynamicPtrCast(root, ZafWindow)->SetDefaultButton(newDefaultButton, defaultDefault);

	// Set the default button.
	if (defaultDefault)
	{
		if (newDefaultButton != defaultDefaultButton)
		{
			if (!defaultButton || (defaultButton == defaultDefaultButton &&
				!defaultButton->Focus()))
			{
				ZafButton *oldDefault = defaultButton;
				defaultButton = newDefaultButton;
				if (oldDefault)
					oldDefault->Event(S_REDISPLAY_DEFAULT);
				if (defaultButton)
					defaultButton->Event(S_REDISPLAY_DEFAULT);
			}

			defaultDefaultButton = newDefaultButton;
		}

		return (defaultDefaultButton);
	}

	// Update the button image.
	if (newDefaultButton != defaultButton)
	{
		ZafButton *oldDefault = defaultButton;
		defaultButton = newDefaultButton;
		if (oldDefault && oldDefault == defaultDefaultButton)
			oldDefault->Event(S_REDISPLAY_DEFAULT);
		if (defaultButton && defaultButton == defaultDefaultButton)
			defaultButton->Event(S_REDISPLAY_DEFAULT);
	}

	// Return a pointer to the default button.
	return (defaultButton);
}

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

bool ZafWindow::SetLocked(bool setLocked)
{
	// Make sure the attribute has changed.
	if (locked != setLocked)
		locked = setLocked;

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

bool ZafWindow::SetModal(bool setModal)
{
	// Make sure the attribute has changed.
	if (modal != setModal && !screenID)
		modal = setModal;

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

bool ZafWindow::SetMoveable(bool setMoveable)
{
	// Make sure the attribute has changed.
	if (moveable != setMoveable && !screenID)
		moveable = setMoveable;

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

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

bool ZafWindow::SetNormalHotKeys(bool setNormalHotKeys) 
{ 
	normalHotKeys = setNormalHotKeys; 
	return (normalHotKeys); 
}

ZafWindow *ZafWindow::SetOwner(ZafWindow *setOwner)
{
	if (!screenID && !parent)
		owner = setOwner;

	return (owner);
}

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

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

bool ZafWindow::SetSelected(bool )
{
	// selected is false for this class.
	selected = false;
	return (selected);
}

bool ZafWindow::SetSizeable(bool setSizeable)
{
	// Make sure the attribute has changed.
	if (sizeable != setSizeable && !screenID)
		sizeable = setSizeable;

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

bool ZafWindow::SetTemporary(bool setTemporary)
{
	// Make sure the attribute has changed.
	if (temporary != setTemporary && !screenID)
		temporary = setTemporary;

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

ZafError ZafWindow::SetText(const ZafIChar *text)
{
	ZafWindowObject *title = Title();
	return (title ? title->SetText(text) : ZAF_ERROR_INVALID);
}

#if defined(ZAF_UNICODE)
ZafError ZafWindow::SetText(const char *text)
{
	ZafStringData stringData(text);
	return (SetText(stringData.Text()));
}
#endif

int ZafWindow::CompareAscending(ZafWindowObject *object1, ZafWindowObject *object2)
{
	const ZafIChar *string1 = object1->Text();
	if (!string1)
		return (-1);
	const ZafIChar *string2 = object2->Text();
	if (!string2)
		return (1);
#if defined(__SC__) && !defined(ZAF_MACINTOSH)
	return (strcmp(string1, string2));
#else
	return (strcoll(string1, string2));
#endif
}

int ZafWindow::CompareDescending(ZafWindowObject *object1, ZafWindowObject *object2)
{
	const ZafIChar *string1 = object1->Text();
	if (!string1)
		return (1);
	const ZafIChar *string2 = object2->Text();
	if (!string2)
		return (-1);
#if defined(__SC__) && !defined(ZAF_MACINTOSH)
	return (strcmp(string2, string1));
#else
	return (strcoll(string2, string1));
#endif
}

const ZafIChar *ZafWindow::Text(void)
{
	ZafTitle *title = Title();
	return (title ? title->Text() : ZAF_NULLP(ZafIChar));
}

// ----- Persistent functions -----------------------------------------------
#if defined(USE_ZAF_PERSISTENCE)
ZafWindow::ZafWindow(const ZafIChar *name, ZafObjectPersistence &persist) :
	ZafWindowObject(name, persist.PushLevel(className, classID, ZAF_PERSIST_ROOT_DIRECTORY)),
	ZafList(), support(),
	// attributes
	defaultButton(ZAF_NULLP(ZafButton)),
	defaultDefaultButton(ZAF_NULLP(ZafButton)), owner(ZAF_NULLP(ZafWindow)),
	sizeToClient(true)
{
	// Initialize environment specific information.
#	if defined(ZAF_MSWINDOWS)
	frameID = 0;
#	elif defined(ZAF_MOTIF) || defined(ZAF_MACINTOSH)
	decorations = 0;
#	endif

	// Initialize the window information.
	restoreRegion.left = restoreRegion.top = 0;
	restoreRegion.right = restoreRegion.bottom = 0;

	// Read the data.
	if (persist.Error() == ZAF_ERROR_NONE)
	{
		ZafWindow::ReadData(persist);

		// Read the default button id.
		ZafFile *file = persist.CurrentFile();
		ZafIChar defaultButtonID[ZAF_MAXNAMELEN], compareNameBuf[ZAF_MAXNAMELEN];
		*file >> defaultButtonID >> compareNameBuf;

		ReadChildren(persist);

		if (*defaultButtonID)
		{
			// Set the default button.
			ZafButton *defButton = DynamicPtrCast(GetObject(defaultButtonID), ZafButton);
			if (defButton)
				SetDefaultButton(defButton, true);
		}
	}

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

void ZafWindow::ReadChildren(ZafObjectPersistence &persist)
{
	// Read the sub-object information.
	ZafFileSystem *fileSystem = persist.CurrentFileSystem();
	ZafFileInfoStruct fileInfo;
	int finished = fileSystem->FindFirst(fileInfo, ZAF_ITEXT("*"));
	while (!finished)
	{
		// Try to find a matching object constructor.
		if (fileInfo.stringID)
		{
			ZafObjectConstructor constructor = persist.GetObjectConstructor((ZafClassID)0, fileInfo.stringID);
			if (constructor)
			{
				persist.PushLevel(fileInfo.stringID, fileInfo.numberID, ZAF_PERSIST_DIRECTORY);
				Add((ZafWindowObject *)(constructor)(fileInfo.name, persist));
				persist.PopLevel();
			}
		}

		// Get the next entry.
		finished = fileSystem->FindNext(fileInfo, ZAF_ITEXT("*"));
	}
}

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

void ZafWindow::ReadData(ZafObjectPersistence &persist)
{
	ZafFile *file = persist.CurrentFile();

	// Read the client size.
	int clientWidth, clientHeight;
	*file >> clientWidth >> clientHeight;
	clientRegion.coordinateType = coordinateType;
	clientRegion.left = clientRegion.top = 0;
	clientRegion.right = clientRegion.left + clientWidth - 1;
	clientRegion.bottom = clientRegion.top + clientHeight - 1;

	// Read the window data.
	ZafIChar compareName[ZAF_MAXNAMELEN];
	ZafUInt16 flag1, flag2;
	*file >> flag1 >> flag2;
	destroyable = (flag1 & 0x0001) ? true : false;
	locked = (flag1 & 0x0002) ? true : false;
	maximized = (flag1 & 0x0004) ? true : false;
	minimized = (flag1 & 0x0008) ? true : false;
	moveable = (flag1 & 0x0010) ? true : false;
	sizeable = (flag1 & 0x0020) ? true : false;
	temporary = (flag1 & 0x0040) ? true : false;
	modal = (flag1 & 0x0080) ? true : false;
	normalHotKeys = (flag1 & 0x0100) ? true : false;
	// flag2
	selectionType = (ZafSelectionType)((int)flag2 & 0x000F);

	ZafFileSystem *fileSystem = persist.CurrentFileSystem();
	ZafFile *compareFile = fileSystem->Open(ZAF_ITEXT("compareFunction"), ZAF_FILE_READ);
	if (compareFile)
	{
		*compareFile >> compareName;
		fileSystem->Close(compareFile);

		if (*compareName)
			compareFunction = persist.GetCompareFunction(compareName);
	}
}

void ZafWindow::Write(ZafObjectPersistence &persist)
{
	// Write the window data.
	ZafWindowObject::Write(persist.PushLevel(className, classID, ZAF_PERSIST_ROOT_DIRECTORY));
	if (persist.Error() == ZAF_ERROR_NONE)
		ZafWindow::WriteData(persist);
	if (persist.Error() == ZAF_ERROR_NONE)
		WriteSupportChildren(persist);
	if (persist.Error() == ZAF_ERROR_NONE)
		WriteChildren(persist);

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

void ZafWindow::WriteChildren(ZafObjectPersistence &persist)
{
	// Write the sub-object information.
	for (ZafWindowObject *object = First(); object; object = object->Next())
	{
		// Write the object.
		object->Write(persist.PushLevel(object->ClassName(), object->ClassID(), ZAF_PERSIST_DIRECTORY));
		persist.PopLevel();
	}
}

void ZafWindow::WriteData(ZafObjectPersistence &persist)
{
	ZafFile *file = persist.CurrentFile();

	// Write the client size.
	ZafRegionStruct region = clientRegion;
	ConvertRegion(region, coordinateType);
	*file << region.Width() << region.Height();

	// Write the window data.
	ZafUInt16 flag1 = 0, flag2 = 0;
	flag1 |= (ZafUInt16)(destroyable ? 0x0001 : 0);
	flag1 |= (ZafUInt16)(locked ? 0x0002 : 0);
	flag1 |= (ZafUInt16)(maximized ? 0x0004 : 0);
	flag1 |= (ZafUInt16)(minimized ? 0x0008 : 0);
	flag1 |= (ZafUInt16)(moveable ? 0x0010 : 0);
	flag1 |= (ZafUInt16)(sizeable ? 0x0020 : 0);
	flag1 |= (ZafUInt16)(temporary ? 0x0040 : 0);
	flag1 |= (ZafUInt16)(modal ? 0x0080 : 0);
	flag1 |= (ZafUInt16)(normalHotKeys ? 0x0100 : 0);
	// flag2
	flag2 |= (ZafUInt16)(selectionType & 0x000F);
	*file << flag1 << flag2;

	// Write the default button string id.
	const ZafIChar *defaultButtonID = defaultDefaultButton ? defaultDefaultButton->StringID() : ZAF_NULLP(ZafIChar);
	ZafDataName compareName = GetCompareFunctionName(compareFunction, persist);
	*file << defaultButtonID << compareName;

	if (compareName)
	{
		ZafFileSystem *fileSystem = persist.CurrentFileSystem();
		ZafFile *file = fileSystem->Open(ZAF_ITEXT("compareFunction"),
			ZAF_FILE_CREATE | ZAF_FILE_READWRITE, compareName, ID_ZAF_COMPARE_FUNCTION);
		*file << compareName;
		fileSystem->Close(file);
	}
}

void ZafWindow::WriteSupportChildren(ZafObjectPersistence &persist)
{
	// Write the sub-object information.
	for (ZafWindowObject *object = SupportFirst(); object; object = object->Next())
	{
		// Write the object.
		object->Write(persist.PushLevel(object->ClassName(), object->ClassID(), ZAF_PERSIST_DIRECTORY));
		persist.PopLevel();
	}
}
#endif
