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

#include <z_bmap1.hpp>
#define ZAF_BITMAP_INFO
#include "gbl_def.cpp"

// ----- ZafBitmap ----------------------------------------------------------

ZafBitmap::ZafBitmap(int left, int top, int width, int height,
	ZafBitmapData *zBitmapData) :
	ZafWindowObject(left, top, width, height),
	bitmapData(ZAF_NULLP(ZafBitmapData)), autoSize(true)
{
	// Initialize the bitmap information.
	SetFont(ZAF_FNT_NULL);
	SetNoncurrent(true);
	SetOSDraw(false);

	// Initialize the bitmap data.
	if (zBitmapData)
		SetBitmapData(zBitmapData);
}

ZafBitmap::ZafBitmap(const ZafBitmap &copy) :
	ZafWindowObject(copy),
	bitmapData(ZAF_NULLP(ZafBitmapData)), autoSize(copy.autoSize)
{
	// Initialize the bitmap information.
	if (copy.BitmapData())
	{
		if (copy.BitmapData()->Destroyable())
			SetBitmapData(new ZafBitmapData(*copy.BitmapData()));
		else
			SetBitmapData(copy.BitmapData());
		bitmapData->SetStringID(copy.BitmapData()->StringID());
	}
}

ZafBitmap::~ZafBitmap(void)
{
	// Remove the data notification.
	if (bitmapData)
		bitmapData->SubtractNotification(this, (ZafUpdateFunction)Update);

	// Restore the bitmap information.
	if (bitmapData && bitmapData->Destroyable() && bitmapData->NotifyCount() == 0)
		delete bitmapData;
}

#if defined(ZAF_DEFAULT_DRAW)
#if defined(ZAF_INDEPENDENT)
ZafEventType ZafBitmap::Draw(const ZafEventStruct &event, ZafEventType ccode)
#else
ZafEventType ZafBitmap::Draw(const ZafEventStruct &, ZafEventType ccode)
#endif
{
	ZafRegionStruct drawRegion = BeginDraw();

#if defined(ZAF_INDEPENDENT)
	display->SetClipRegion(event.region);
#endif

	if (Bordered())
		DrawBorder(drawRegion, ccode);

	DrawBackground(drawRegion, ccode);

	if (bitmapData)
	{
		display->SetClipRegion(drawRegion);
		display->Bitmap(drawRegion.left, drawRegion.top, *bitmapData);
	}

	EndDraw();
	return (ccode);
}
#endif

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

ZafEventType ZafBitmap::Event(const ZafEventStruct &event)
{
	ZafEventType ccode = LogicalEvent(event);

	// Check for zinc events.
	switch (ccode)
	{
	case S_COMPUTE_SIZE:
		if (AutoSize() && bitmapData)
		{
			zafRegion.bottom = zafRegion.top + bitmapData->Height() +
				(Bordered() ? (2 * ZAF_BORDER_SIZE) : 0) - 1;
			zafRegion.right = zafRegion.left + bitmapData->Width() +
				(Bordered() ? (2 * ZAF_BORDER_SIZE) : 0) - 1;
		}
		ccode = ZafWindowObject::Event(event);
		break;

	case S_REDISPLAY_DATA:
		OSSetImage();
		break;

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

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

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

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

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

bool ZafBitmap::SetAutoSize(bool setAutoSize)
{
	// Make sure the request is valid.
	if (autoSize != setAutoSize && !screenID)
		autoSize = setAutoSize;

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

ZafError ZafBitmap::SetBitmapData(ZafBitmapData *tBitmapData)
{
	// Remove the data notification.
	if (bitmapData)
		bitmapData->SubtractNotification(this, (ZafUpdateFunction)Update);

	// Reset the bitmap data.
	if (bitmapData && bitmapData != tBitmapData &&
		bitmapData->Destroyable() && bitmapData->NotifyCount() == 0)
		delete bitmapData;
	bitmapData = tBitmapData;

	// Add the data notification.
	if (bitmapData)
		bitmapData->AddNotification(this, (ZafUpdateFunction)Update);
	return (ZAF_ERROR_NONE);
}

bool ZafBitmap::SetChanged(bool )
{
	// changed is false for this class.
	changed = false;
	return (changed);
}

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

bool ZafBitmap::SetFocus(bool )
{
	// focus is false for this class.
	focus = false;
	return (focus);
}

ZafLogicalFont ZafBitmap::SetFont(ZafLogicalFont )
{
	// This class does not permit font changes.
	return (ZAF_FNT_NULL);
}

const ZafIChar *ZafBitmap::SetHelpContext(const ZafIChar *)
{
	// helpContext is empty for this class.
	return (ZAF_NULLP(ZafIChar));
}

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

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

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

bool ZafBitmap::SetOSDraw(bool )
{
	// osDraw is false for this class.
	osDraw = false;
	return (osDraw);
}

ZafLogicalColor ZafBitmap::SetTextColor(ZafLogicalColor , ZafLogicalColor )
{
	// This class does not permit text color changes.
	return (ZAF_CLR_NULL);
}

ZafUserFunction ZafBitmap::SetUserFunction(ZafUserFunction )
{
	// userFunction is null for this class.
	userFunction = ZAF_NULLF(ZafUserFunction);
	return (userFunction);
}

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

ZafError ZafBitmap::OSSetImage(void)
{
	if (screenID)
	{
		Event(S_COMPUTE_SIZE);
		OSSize();
		Redisplay();
	}

	return (ZAF_ERROR_NONE);
}

ZafError ZafBitmap::Update(ZafBitmap *bitmap, ZafUpdateType type)
{
	ZafError retVal = ZAF_ERROR_INVALID;
	if (type & ZAF_UPDATE_OBJECT)
		retVal = bitmap->OSSetImage();
	if (type & ZAF_UPDATE_DATA)
		retVal = (ZAF_ERROR_NONE);
	return (retVal);
}

// ----- Persistent functions -----------------------------------------------
#if defined(USE_ZAF_PERSISTENCE)
ZafBitmap::ZafBitmap(const ZafIChar *name, ZafObjectPersistence &persist) :
	ZafWindowObject(name, persist.PushLevel(className, classID, ZAF_PERSIST_DIRECTORY)),
	bitmapData(ZAF_NULLP(ZafBitmapData))
{
	// Read the data.
	if (persist.Error() == ZAF_ERROR_NONE)
		ZafBitmap::ReadData(persist);
	persist.PopLevel();
	if (persist.Error() != ZAF_ERROR_NONE)
		SetError(persist.Error());
}

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

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

	// Read the data.
	ZafIChar bitmapName[ZAF_MAXNAMELEN];
	ZafUInt16 flag1;
	*file >> bitmapName >> flag1;
	autoSize = (flag1 & 0x0001) ? true : false;

	// Read the bitmap data.
	if (*bitmapName)
		SetBitmapData(new ZafBitmapData(bitmapName, persist));
}

void ZafBitmap::Write(ZafObjectPersistence &persist)
{
	// Write the object.
	ZafWindowObject::Write(persist.PushLevel(className, classID, ZAF_PERSIST_DIRECTORY));
	if (persist.Error() == ZAF_ERROR_NONE)
		ZafBitmap::WriteData(persist);
	persist.PopLevel();
	if (persist.Error() != ZAF_ERROR_NONE)
		SetError(persist.Error());
}

void ZafBitmap::WriteData(ZafObjectPersistence &persist)
{
	// Write the data.
	ZafUInt16 flag1 = 0;
	flag1 |= (ZafUInt16)(autoSize ? 0x0001 : 0);

	const ZafIChar *bitmapName = bitmapData ? bitmapData->StringID() : ZAF_NULLP(ZafIChar);
	ZafFile *file = persist.CurrentFile();
	*file << bitmapName << flag1;

	// Write the bitmap data.
	if (bitmapData)
		bitmapData->Write(persist);
}
#endif
