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

#include <z_gmgr.hpp>

// ----- ZafDimensionConstraint ---------------------------------------------

ZafDimensionConstraint::ZafDimensionConstraint(ZafWindowObject *zObject,
	ZafDimensionConstraintType zType) :
	ZafConstraint(zObject),
	minimum(0), maximum(0), type(zType)
{
}

ZafDimensionConstraint::ZafDimensionConstraint(const ZafDimensionConstraint &copy) :
	ZafConstraint(copy),
	minimum(copy.minimum), maximum(copy.maximum), type(copy.type)
{
}

ZafDimensionConstraint::~ZafDimensionConstraint(void)
{
}

ZafConstraint *ZafDimensionConstraint::Duplicate(void)
{
	// Initialize ZafConstraint stuff.
	ZafConstraint::Duplicate();
	return (new ZafDimensionConstraint(*this));
}

ZafEventType ZafDimensionConstraint::Event(const ZafEventStruct &event)
{
	// Check for zinc events.
	ZafEventType ccode = event.type;
	if (ccode == S_INITIALIZE)
	{
		ZafConstraint::Event(event);
		return (ccode);
	}
	else if (ccode != S_COMPUTE_SIZE || !object || !object->display)
		return (S_ERROR);

	// Compute the object's constraint.
	int newMinimum, newMaximum;
	if (type == ZAF_DNCF_WIDTH)
	{
		if (object->CoordinateType() == ZAF_CELL)
		{
			newMinimum = minimum * object->display->cellWidth;
			newMaximum = maximum * object->display->cellWidth;
		}
		else if (object->CoordinateType() == ZAF_MINICELL)
		{
			newMinimum = (int)((unsigned long)minimum * object->display->cellWidth * object->display->miniNumeratorX / object->display->miniDenominatorX);
			newMaximum = (int)((unsigned long)maximum * object->display->cellWidth * object->display->miniNumeratorX / object->display->miniDenominatorX);
		}
		else
		{
			newMinimum = minimum;
			newMaximum = maximum;
		}

		ZafRegionStruct region = object->Region();
		if (minimum && region.Width() < newMinimum)
			region.right = region.left + newMinimum - 1;
		if (maximum && region.Width() > newMaximum)
			region.right = region.left + newMaximum - 1;
		object->SetRegion(region);
	}

	if (type == ZAF_DNCF_HEIGHT)
	{
		if (object->CoordinateType() == ZAF_CELL)
		{
			newMinimum = minimum * object->display->cellHeight;
			newMaximum = maximum * object->display->cellHeight;
		}
		else if (object->CoordinateType() == ZAF_MINICELL)
		{
			newMinimum = (int)((unsigned long)minimum * object->display->cellHeight * object->display->miniNumeratorY / object->display->miniDenominatorY);
			newMaximum = (int)((unsigned long)maximum * object->display->cellHeight * object->display->miniNumeratorY / object->display->miniDenominatorY);
		}
		else
		{
			newMinimum = minimum;
			newMaximum = maximum;
		}

		ZafRegionStruct region = object->Region();
		if (minimum && region.Height() < newMinimum)
			region.bottom = region.top + newMinimum - 1;
		if (maximum && region.Height() > newMaximum)
			region.bottom = region.top + newMaximum - 1;
		object->SetRegion(region);
	}

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

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

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

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

int ZafDimensionConstraint::SetMaximum(int tMaximum)
{
	maximum = tMaximum;
	return (maximum);
}

int ZafDimensionConstraint::SetMinimum(int tMinimum)
{
	minimum = tMinimum;
	return (minimum);
}

ZafDimensionConstraintType ZafDimensionConstraint::SetType(ZafDimensionConstraintType tType)
{
	type = tType;
	return (type);
}
	
// ----- Persistent functions -----------------------------------------------
#if defined(USE_ZAF_PERSISTENCE)
ZafDimensionConstraint::ZafDimensionConstraint(const ZafIChar *name, ZafObjectPersistence &persist) :
	ZafConstraint(name, persist.PushLevel(className, classID, ZAF_PERSIST_FILE))
{
	// Read the data.
	if (persist.Error() == ZAF_ERROR_NONE)
		ZafDimensionConstraint::ReadData(persist);
	persist.PopLevel();
}

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

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

	// Read the data.
	ZafUInt16 flag1;
	*file >> maximum >> minimum >> flag1;
	type = (ZafDimensionConstraintType)(((int)flag1 & 0xF000) >> 12);
}

void ZafDimensionConstraint::Write(ZafObjectPersistence &persist)
{
	// Write the constraint.
	ZafConstraint::Write(persist.PushLevel(className, classID, ZAF_PERSIST_FILE));
	if (persist.Error() == ZAF_ERROR_NONE)
		ZafDimensionConstraint::WriteData(persist);
	persist.PopLevel();
}

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

	// Read the data.
	ZafUInt16 flag1 = 0;
	flag1 |= (ZafUInt16)((type & 0x000F) << 12);
	*file << maximum << minimum << flag1;
}
#endif
