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

#include <z_table.hpp>
#include <z_str1.hpp>
#include <z_ctype.hpp>
#include <z_scrdsp.hpp>

#if defined(ZAF_MSWINDOWS)
#include <w_app.hpp>
#endif

// ----- ZafTableRecord -----------------------------------------------------

ZafTableRecord::ZafTableRecord(int width, int height) :
	ZafWindow(0, 0, width, height),
	offset(-1)
{
	SetDestroyable(false);
	SetMoveable(false);
	SetParentDrawFocus(true);
	SetSelectionType(ZAF_MULTIPLE_SELECTION);
	SetSizeable(false);
}

ZafTableRecord::ZafTableRecord(const ZafTableRecord &copy) :
	ZafWindow(copy),
	offset(-1)
{
	SetSelectionType(ZAF_MULTIPLE_SELECTION);
}

ZafTableRecord::~ZafTableRecord(void)
{
}

bool ZafTableRecord::ActivateObject(ZafWindowObject *object)
{
#	if defined(ZAF_INDEPENDENT)
	// Use the correct palettes for a system object.
	object->SetSelected(false);
#	endif

	// Make the specified object a system object.
	return (object->SetSystemObject(true));
}

ZafWindowObject *ZafTableRecord::Add(ZafWindowObject *object, ZafWindowObject *position)
{
	// Check for a support or invalid object.
	if (object->parent)
		return (object);
	else if (object->SupportObject())
		return (ZafWindow::Add(object, position));

	// Add the object to the table record.
	object->SetSystemObject(false);
	object->SetParentDrawFocus(true);
#	if defined(ZAF_MOTIF)
	object->SetParentPalette(true);
#	endif
	return (ZafWindow::Add(object, position));
}

void ZafTableRecord::ConvertRegion(ZafRegionStruct &region, ZafCoordinateType newType)
{
	// Go directly to region convert so preSpace and postSpace are not used.
	region.ConvertCoordinates(newType);
}

bool ZafTableRecord::DeactivateObject(ZafWindowObject *object)
{
	bool saveFocus = object->Focus();
	object->SetSystemObject(false);
	object->SetFocus(saveFocus);

#	if defined(ZAF_INDEPENDENT)
	// Use the correct palettes for a system object.
	if (Selected())
		object->SetSelected(Selected());
#	endif

	return (object->SystemObject());
}

#if defined(ZAF_DEFAULT_DRAW)
ZafEventType ZafTableRecord::Draw(const ZafEventStruct &event, ZafEventType ccode)
{
	// Compute the actual draw region.
	// Don't use BeginDraw(), since the records would make nested calls to it.
	ZafRegionStruct drawRegion = ConvertToDrawRegion(this, &clientRegion);

#	if defined(ZAF_INDEPENDENT)
	ZafRegionStruct clip = event.region;
#	else
	ZafRegionStruct clip = drawRegion;
	if (ccode == S_REDISPLAY_REGION)
		clip = event.region;
#	endif

#	if defined(ZAF_MOTIF)
	if (ccode == E_MOTIF)
		clip = event.region;
#	endif

#	if defined(ZAF_MSWINDOWS) 
	clip.HzShift(-zafRegion.left);
	clip.VtShift(-zafRegion.top);
#	endif

#	if defined(ZAF_MSWINDOWS)
	// Draw the table fields.
	for (ZafWindowObject *object = First(); object; object = object->Next())
		if (object->zafRegion.Overlap(clip) && !object->SystemObject())
		{
			bool drawSelected = (object->Focus() && !Selected()) || (!object->Focus() && Selected());
			ZafPaletteState state = PaletteState();
			if (drawSelected)
			{
				state &= ~ZAF_PM_NOT_SELECTED;
				state |= ZAF_PM_SELECTED;
			}

			ZafPaletteStruct textPalette = LogicalPalette(ZAF_PM_TEXT, state);
			ZafPaletteStruct backgroundPalette = LogicalPalette(ZAF_PM_BACKGROUND, state);
			if (drawSelected)
			{
				if (textPalette.colorForeground == ZAF_CLR_DEFAULT)
				{
					((ZafScreenDisplay *)display)->colorTable[ZAF_MAXCOLORS - 1] = textPalette.osPalette.colorForeground;
					textPalette.colorForeground = ZAF_MAXCOLORS - 1;
				}
				if (textPalette.colorBackground == ZAF_CLR_DEFAULT)
				{
					((ZafScreenDisplay *)display)->colorTable[ZAF_MAXCOLORS - 2] = textPalette.osPalette.colorBackground;
					textPalette.colorBackground = ZAF_MAXCOLORS - 2;
				}
				if (backgroundPalette.colorForeground == ZAF_CLR_DEFAULT)
				{
					((ZafScreenDisplay *)display)->colorTable[ZAF_MAXCOLORS - 3] = backgroundPalette.osPalette.colorForeground;
					backgroundPalette.colorForeground = ZAF_MAXCOLORS - 3;
				}
				if (backgroundPalette.colorBackground == ZAF_CLR_DEFAULT)
				{
					((ZafScreenDisplay *)display)->colorTable[ZAF_MAXCOLORS - 4] = backgroundPalette.osPalette.colorBackground;
					backgroundPalette.colorBackground = ZAF_MAXCOLORS - 4;
				}
				ZafPaletteMap traverseModePaletteMap[3];
				traverseModePaletteMap[0].type = ZAF_PM_TEXT;
				traverseModePaletteMap[0].state = ZAF_PM_ANY_STATE;
				traverseModePaletteMap[0].palette = textPalette;
				traverseModePaletteMap[1].type = ZAF_PM_BACKGROUND;
				traverseModePaletteMap[1].state = ZAF_PM_ANY_STATE;
				traverseModePaletteMap[1].palette = backgroundPalette;
				traverseModePaletteMap[2].type = ZAF_PM_NONE;
				traverseModePaletteMap[2].state = 0;
				ZafPaletteData traverseModePaletteData(traverseModePaletteMap, true);

				ZafPaletteData *saveUserPaletteData = object->userPaletteData;
				object->userPaletteData = &traverseModePaletteData;
				if (object->Visible())	
					object->Draw(event, ccode);
				else
				{
					BeginDraw();
					ZafRegionStruct eraseRegion = object->Region();
					eraseRegion = ConvertToDrawRegion(object, &eraseRegion);
					DrawBackground(eraseRegion, ccode);
					EndDraw();
				}
				object->userPaletteData = saveUserPaletteData;
			}
			else
			{
				if (object->Visible())
					object->Draw(event, ccode);
				else
				{
					BeginDraw();
					ZafRegionStruct eraseRegion = object->Region();
					eraseRegion = ConvertToDrawRegion(object, &eraseRegion);
					DrawBackground(eraseRegion, ccode);
					EndDraw();
				}
			}
		}
#	elif defined(ZAF_MOTIF)
	// Draw the table fields.
	for (ZafWindowObject *object = First(); object; object = object->Next())
		if (object->zafRegion.Overlap(clip) && !object->SystemObject())
		{
			if (object->Visible())	
			{
				Table()->getChildPalette = true;
				object->Draw(event, ccode);
			}
			else
			{
				BeginDraw();
				ZafRegionStruct eraseRegion = object->Region();
				eraseRegion = ConvertToDrawRegion(object, &eraseRegion);
				DrawBackground(eraseRegion, ccode);
				EndDraw();
			}
		}
#	else
	// Draw the table fields.
	ZafEventStruct childEvent = event;
	for (ZafWindowObject *object = First(); object; object = object->Next())
	{
		ZafRegionStruct compareRegion = object->zafRegion;
		compareRegion.HzShift(drawRegion.left);
		compareRegion.VtShift(drawRegion.top);
		if (compareRegion.Overlap(clip) && !object->SystemObject())
		{
			// The region must be relative to the object.
			childEvent.region = event.region;
			childEvent.region.HzShift(-object->zafRegion.left);
			childEvent.region.VtShift(-object->zafRegion.top);

			if ((object->Focus() && !Selected()) || (!object->Focus() && Selected()))
			{
				ZafPaletteState state = PaletteState();
				state = (ZafPaletteState)(state & ~ZAF_PM_NOT_SELECTED);
				state |= ZAF_PM_SELECTED;

				ZafPaletteMap traverseModePaletteMap[3];
				traverseModePaletteMap[0].type = ZAF_PM_TEXT;
				traverseModePaletteMap[0].state = ZAF_PM_ANY_STATE;
				traverseModePaletteMap[0].palette = LogicalPalette(ZAF_PM_TEXT, state);
				traverseModePaletteMap[1].type = ZAF_PM_BACKGROUND;
				traverseModePaletteMap[1].state = ZAF_PM_ANY_STATE;
				traverseModePaletteMap[1].palette = LogicalPalette(ZAF_PM_BACKGROUND, state);
				traverseModePaletteMap[2].type = ZAF_PM_NONE;
				traverseModePaletteMap[2].state = 0;
				ZafPaletteData traverseModePaletteData(traverseModePaletteMap, true);

				ZafPaletteData *saveUserPaletteData = object->userPaletteData;
				object->userPaletteData = &traverseModePaletteData;
				if (object->Visible())	
					object->Draw(childEvent, ccode);
				else
				{
					BeginDraw();
					ZafRegionStruct eraseRegion = object->Region();
					eraseRegion = ConvertToDrawRegion(object, &eraseRegion);
					DrawBackground(eraseRegion, ccode);
					EndDraw();
				}
				object->userPaletteData = saveUserPaletteData;
			}
			else if (object->Focus() && Selected())
			{
				ZafPaletteState state = PaletteState();
				state = (ZafPaletteState)(state & ~ZAF_PM_SELECTED);
				state |= ZAF_PM_NOT_SELECTED;

				ZafPaletteMap traverseModePaletteMap[3];
				traverseModePaletteMap[0].type = ZAF_PM_TEXT;
				traverseModePaletteMap[0].state = ZAF_PM_ANY_STATE;
				traverseModePaletteMap[0].palette = LogicalPalette(ZAF_PM_TEXT, state);
				traverseModePaletteMap[1].type = ZAF_PM_BACKGROUND;
				traverseModePaletteMap[1].state = ZAF_PM_ANY_STATE;
				traverseModePaletteMap[1].palette = LogicalPalette(ZAF_PM_BACKGROUND, state);
				traverseModePaletteMap[2].type = ZAF_PM_NONE;
				traverseModePaletteMap[2].state = 0;
				ZafPaletteData traverseModePaletteData(traverseModePaletteMap, true);

				ZafPaletteData *saveUserPaletteData = object->userPaletteData;
				object->userPaletteData = &traverseModePaletteData;
				if (object->Visible())	
					object->Draw(childEvent, ccode);
				else
				{
					BeginDraw();
					ZafRegionStruct eraseRegion = object->Region();
					eraseRegion = ConvertToDrawRegion(object, &eraseRegion);
					DrawBackground(eraseRegion, ccode);
					EndDraw();
				}
				object->userPaletteData = saveUserPaletteData;
			}
			else
			{
				if (object->Visible())
					object->Draw(childEvent, ccode);
				else
				{
					BeginDraw();
					ZafRegionStruct eraseRegion = object->Region();
					eraseRegion = ConvertToDrawRegion(object, &eraseRegion);
					DrawBackground(eraseRegion, ccode);
					EndDraw();
				}
			}
		}
	}
#	endif

	// Erase the remaining region.
	drawRegion = BeginDraw();

#	if defined(ZAF_INDEPENDENT)
	display->SetClipRegion(clip);
#	endif

	if (Last())
		drawRegion.left += Last()->zafRegion.right + 1;
# if defined(ZAF_MOTIF)
	if (Selected())
		Table()->getChildPalette = true;
# endif
	DrawBackground(drawRegion, ccode);

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

ZafEventType ZafTableRecord::DrawFocus(ZafRegionStruct &, ZafEventType ccode)
{
	// Table record does not draw its own focus.
	return (ccode);
}
#endif

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

ZafEventType ZafTableRecord::Event(const ZafEventStruct &event)
{
	// Check for zinc events.
	ZafEventType ccode = LogicalEvent(event);
	ZafWindowObject *object = Current();
	switch (ccode)
	{
	case S_INITIALIZE:
		ccode = ZafWindow::Event(event);

#if !defined(ZAF_TEXT_MODE)
		// Adjust child regions to leave space for the grid.
		if (Table() && Table()->Grid())
			for (object = First(); object; object = object->Next())
			{
				ZafRegionStruct region = object->Region();
				region.right--;
				object->SetRegion(region);
			}
#endif
		break;

	case S_DEINITIALIZE:
		ccode = ZafWindow::Event(event);
#if !defined(ZAF_TEXT_MODE)
		// Un-Adjust child regions.
		if (Table() && Table()->Grid())
			for (object = First(); object; object = object->Next())
			{
				ZafRegionStruct region = object->Region();
				region.right++;
				object->SetRegion(region);
			}
#endif
		break;

	case L_BEGIN_SELECT:
		// Try to find an overlapping object.
		for (object = First(); object; object = object->Next())
			if (object->zafRegion.Overlap(event.position))
			{
				// Don't activate the object if it can't become current.
				// If disabled or non current set object to NULL and break 
				// so the record gets made current at the bottom of the case.
				if (object->Disabled())
				{
					object = ZAF_NULLP(ZafWindowObject);
					break;
				}
				else if (object->Noncurrent())
				{
					object->Event(event);
					object = ZAF_NULLP(ZafWindowObject);
					break;
				}
				else 
					// Activate the object.
					ActivateObject(object);

#				if defined(ZAF_MSWINDOWS)
				POINT mousePoint;
				mousePoint.x = LOWORD(event.osEvent.lParam);
				mousePoint.y = HIWORD(event.osEvent.lParam);
				MapWindowPoints(event.osEvent.hwnd, HWND_DESKTOP, &mousePoint, 1);
				HWND hwndMouse = WindowFromPoint(mousePoint);
				if (hwndMouse != screenID)
				{
					MapWindowPoints(HWND_DESKTOP, hwndMouse, &mousePoint, 1);
					SendMessage(hwndMouse, WM_LBUTTONDOWN, event.osEvent.wParam,
						MAKELONG(mousePoint.x, mousePoint.y));
				}
#				elif defined(ZAF_MOTIF)
				XEvent xEvent = event.osEvent;
				xEvent.xbutton.send_event = true;
				xEvent.xbutton.display = XtDisplay(object->screenID);
				xEvent.xbutton.window = XtWindow(object->screenID);
				xEvent.xbutton.x -= object->zafRegion.left + zafRegion.left;
				xEvent.xbutton.y -= object->zafRegion.top + zafRegion.top;
				XSendEvent(xEvent.xbutton.display, xEvent.xbutton.window, false, ButtonPressMask, &xEvent);
#				elif defined(ZAF_MACINTOSH)
				object->SetFocus(true);

				// Use position coordinates of the object.
				ZafEventStruct mEvent = event;
				mEvent.position.line -= object->zafRegion.top;
				mEvent.position.column -= object->zafRegion.left;
				ccode = object->Event(mEvent);
#				else
				object->SetFocus(true);
				ccode = object->Event(event);
#				endif

				break;
			}

		// Make sure the object has the focus.
		if (!object && !Focus())
			SetFocus(true);
		break;

	case L_CONTINUE_SELECT:
	case L_END_SELECT:
		for (object = First(); object; object = object->Next())
			if (object->zafRegion.Overlap(event.position))
			{
				object->Event(event);
			}
		break;

	case N_NON_CURRENT:
		if (Changed())
		{
			ZafTable *table = Table();
			ZafTableHeader *header = Table()->RowTableHeader();
			ZafWindowObject *rowField = header ? header->Get(table->Index(this)) : ZAF_NULLP(ZafWindowObject);
			table->SeekOptimized(Offset());
			table->WriteRecord(*this, rowField);
		}

		ccode = ZafWindow::Event(event);
		break;

	case N_SIZE:
		// Pre-size the children.
		{
		ZafWindowObject *field = Table()->VirtualRecord()->First();
		for (object = First(); object && field; object = object->Next(), field = field->Next())
		{
			object->zafRegion.left = field->zafRegion.left;
			object->zafRegion.top = 0;
			object->zafRegion.right = field->zafRegion.right;
			object->zafRegion.bottom = zafRegion.bottom - zafRegion.top;
#			if defined(ZAF_MOTIF)
			if (!Table()->Grid())
			{
				object->zafRegion.top++;
				object->zafRegion.bottom--;
			}
#			endif
			object->SetRegion(object->zafRegion);
		}

		// Now, defer to the base class.
		ccode = ZafWindow::Event(event);
		}
		break;

	case S_REDISPLAY:
	case S_REDISPLAY_DATA:
	case S_REDISPLAY_REGION:
		ccode = ZafWindowObject::Event(event);
		break;

	case L_LEFT:
	case L_RIGHT:
	case L_BOL:
	case L_EOL:
	case L_UP:
	case L_DOWN:
	case L_FIRST:
	case L_LAST:
	case L_PGDN:
	case L_PGUP:
	case L_NEXT:
	case L_PREVIOUS:
	case L_SELECT:
		ccode = MoveEvent(event);
		break;

	default:
		// Check for key-activation of the current field.
		if (event.InputType() == E_KEY && (event.modifiers & S_KEYDOWN) &&
			!(event.key.shiftState & S_ALT || event.key.shiftState & S_CTRL) &&
			IsPrint(event.key.value) && object && !object->SystemObject())
		{
			ActivateObject(object);
			object->SetFocus(true);
			Table()->ScrollEvent(S_HSCROLL_CHECK);
#if defined(ZAF_MSWINDOWS)
			SendMessage(object->screenID, WM_KEYDOWN, event.osEvent.wParam, event.osEvent.lParam);
#endif
		}

		// Defer to the window.
		ccode = ZafWindow::Event(event);
		break;
	}

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

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

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

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

ZafEventType ZafTableRecord::MoveEvent(const ZafEventStruct &event)
{
	// Determine the new selection.
	ZafWindowObject *object = Current();

	ZafEventType ccode = LogicalEvent(event);
	switch (ccode)
	{
	case L_BOL:
		if (object && object->SystemObject())
			ccode = object->Event(event);
		else
			object = First();
		break;

	case L_EOL:
		if (object && object->SystemObject())
			ccode = object->Event(event);
		else
			object = Last();
		break;

	case L_LEFT:
		if (!object)
			object = Last();
		else if (object->SystemObject())
			ccode = object->Event(event);
		else
		{
			// Move to previous field that can receive focus.
			ZafWindowObject *newObj = object->Previous() ? object->Previous() : Last();
			while (newObj != object &&
			 (newObj->Noncurrent() || newObj->Disabled() || !newObj->Visible()))
				newObj = newObj->Previous() ? newObj->Previous() : Last();
			object = newObj;
		}
		break;

	case L_RIGHT:
		if (!object)
			object = First();
		else if (object->SystemObject())
			ccode = object->Event(event);
		else
		{
			// Move to next field that can receive focus.
			ZafWindowObject *newObj = object->Next() ? object->Next() : First();
			while (newObj != object &&
			 (newObj->Noncurrent() || newObj->Disabled() || !newObj->Visible()))
				newObj = newObj->Next() ? newObj->Next() : First();
			object = newObj;
		}
		break;

	case L_UP:
	case L_DOWN:
		// Only single line objects are permitted for now.
		ccode = S_ERROR;
		break;

	case L_PREVIOUS:
	case L_NEXT:
		if (!object)
		{
			object = (ccode == L_NEXT) ? First() : Last();

			// If object can become current, break. Otherwise, fall through
			// to find the proper object that can become current.
			if (object && !object->Noncurrent() &&
			 !object->Disabled() && object->Visible())
				break;
		}

		// Move to proper object that can become current.
		if (object->SystemObject())
			DeactivateObject(object);
		if (ccode == L_NEXT)
		{
			// Move to next field that can receive focus.
			ZafWindowObject *newObj = object->Next() ? object->Next() : First();
			while (newObj != object &&
			 (newObj->Noncurrent() || newObj->Disabled() || !newObj->Visible()))
				newObj = newObj->Next() ? newObj->Next() : First();
			object = newObj;
		}
		else
		{
			// Move to previous field that can receive focus.
			ZafWindowObject *newObj = object->Previous() ? object->Previous() : Last();
			while (newObj != object &&
			 (newObj->Noncurrent() || newObj->Disabled() || !newObj->Visible()))
				newObj = newObj->Previous() ? newObj->Previous() : Last();
			object = newObj;
		}
		break;

	case L_SELECT:
		if (!object)
			object = First();

		// If there still isn't an object it's because the table
		// record in the Designer doesn't have an object yet.
		if (!object)
			break;

		if (object->SystemObject())
		{
#if defined(ZAF_MOTIF)
			// In Motif the default_callback is responsible for sending an 
			// L_SELECT to the object, but the object is deactivated before 
			// it can be sent so we must pass the event as L_SELECT rather
			// than a system event.
			object->Event(L_SELECT);
#else
			object->Event(event);
#endif
			DeactivateObject(object);
			// Move to next field that can receive focus.
			ZafWindowObject *newObj = object->Next() ? object->Next() : First();
			while (newObj != object && newObj->Noncurrent())
				newObj = newObj->Next() ? newObj->Next() : First();
			object = newObj;
			object->SetFocus(true);
			Table()->ScrollEvent(S_HSCROLL_CHECK);
		}
		else
		{
			ActivateObject(object);
			object->SetFocus(true);
			Table()->ScrollEvent(S_HSCROLL_CHECK);
		}
		break;

	default:
		return (S_ERROR);
	}

	// Check the current object.
	if (!object)
		return (S_ERROR);
	else if (object != current)
	{
		// Reset the object focus.
		object->SetFocus(true);

		// Check the scroll information.
		Table()->ScrollEvent(S_HSCROLL_CHECK);
	}
	return (ccode);
}

ZafWindowObject *ZafTableRecord::NotifyFocus(ZafWindowObject *focusObject, bool setFocus)
{
	ZafWindowObject *object = Current();
	bool transition = (setFocus && focus) ? true : false;

	// Set the correct object to be drawn when the record receives focus.
	if (setFocus && focusObject != this &&
		DynamicPtrCast(parent, ZafWindow)->Current() != this)
		ZafList::SetCurrent(focusObject);

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

	// Update the focus.
	if (!screenID)
		return (invalidObject);

	// Deinitialize the old record focus.
	if (object && (!setFocus || (transition && object != focusObject)))
	{
		DeactivateObject(object);
		object->Redisplay();
	}

	// Redisplay the new record focus.
	if (setFocus && focusObject)
	{
		Table()->focusField = Index(focusObject);

		focusObject->Redisplay();
	}

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

ZafWindowObject *ZafTableRecord::Subtract(ZafWindowObject *object)
{
	// Remove the object from the table record.
	return (ZafWindow::Subtract(object));
}

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

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

bool ZafTableRecord::SetDestroyable(bool )
{
	// destroyable is false for this class.
	destroyable = false;
	return (destroyable);
}

bool ZafTableRecord::SetDisabled(bool )
{
	// disabled is false for this class.
	disabled = false;
	return (disabled);
}

bool ZafTableRecord::SetFocus(bool setFocus)
{
	// Turn on system objects.
//	if (setFocus)
	if (setFocus && current)
	{
//		ZafWindowObject::SetFocus(setFocus);
		if (current)
			Current()->SetFocus(setFocus);
	}
	else
		ZafWindow::SetFocus(setFocus);

	return (focus);
}

bool ZafTableRecord::SetLocked(bool )
{
	// locked is false for this class.
	locked = false;
	return (locked);
}

bool ZafTableRecord::SetMaximized(bool )
{
	// maximized is false for this class.
	maximized = false;
	return (maximized);
}

bool ZafTableRecord::SetMinimized(bool )
{
	// minimized is false for this class.
	minimized = false;
	return (minimized);
}

bool ZafTableRecord::SetModal(bool )
{
	// modal is false for this class.
	modal = false;
	return (modal);
}

bool ZafTableRecord::SetMoveable(bool )
{
	// moveable is false for this class.
	moveable = false;
	return (moveable);
}

bool ZafTableRecord::SetNoncurrent(bool )
{
	// noncurrent is false for this class.
	noncurrent = false;
	return (noncurrent);
}

bool ZafTableRecord::SetNormalHotKeys(bool )
{
	// normalHotKeys is false for this class.
	normalHotKeys = false;
	return (normalHotKeys);
}

ZafOffset ZafTableRecord::SetOffset(ZafOffset tOffset)
{
	// Make sure the offset has changed.
	if (offset != tOffset)
		offset = tOffset;

	// Return the current offset.
	return (offset);
}

ZafWindow *ZafTableRecord::SetOwner(ZafWindow *)
{
	// owner is null for this class.
	owner = ZAF_NULLP(ZafWindow);
	return (owner);
}

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

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

bool ZafTableRecord::SetSelected(bool setSelected)
{
	// Defer to the window level.
	ZafWindowObject::SetSelected(setSelected);

	// Return the current status.
	return (selected);
}

bool ZafTableRecord::SetSizeable(bool )
{
	// sizeable is false for this class.
	sizeable = false;
	return (sizeable);
}

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

bool ZafTableRecord::SetTemporary(bool )
{
	// temporary is false for this class.
	temporary = false;
	return (temporary);
}

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

void ZafTableRecord::OSMapPalette(ZafPaletteStruct &palette, ZafPaletteType type, ZafPaletteState state)
{
	// Defer to the parent table.
	parent->OSMapPalette(palette, type, state);
}

//??? Why is this function needed?
OSWindowID ZafTableRecord::OSScreenID(ZafScreenIDType type) const
{
#if defined(ZAF_MSWINDOWS)
	return (ZafWindow::OSScreenID(type));
#else
	// Defer to the parent table.
	return (parent->OSScreenID(type));
#endif
}

void ZafTableRecord::OSRegisterObject(void)
{
	// Table record is never registered with the OS.
	// The screenID is set by RegisterObject() for a non-SystemObject().
}

// ----- Persistent functions -----------------------------------------------
#if defined(USE_ZAF_PERSISTENCE)
ZafTableRecord::ZafTableRecord(const ZafIChar *name, ZafObjectPersistence &persist) :
	ZafWindow(name, persist.PushLevel(className, classID, ZAF_PERSIST_DIRECTORY)),
	offset(-1)
{
	// Only ZafTable's virtualRecord is persisted.  Other records are created
	// at run-time as needed.
	for (ZafWindowObject *object = First(); object; object = object->Next())
	{
		object->SetSystemObject(false);
		object->SetParentDrawFocus(true);
#	if defined(ZAF_MOTIF)
		object->SetParentPalette(true);
#	endif
	}

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

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

void ZafTableRecord::Write(ZafObjectPersistence &persist)
{
	// Write the object.
	ZafWindow::Write(persist.PushLevel(className, classID, ZAF_PERSIST_DIRECTORY));

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