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

#include <z_lang.hpp>
#include <z_mouse1.hpp>
#include <z_string.hpp> // For strcmp().
#define ZAF_MOUSE_DATA_INFO
#include "gbl_def.cpp"

// ----- ZafMouseStruct -----------------------------------------------------

ZafMouseStruct::ZafMouseStruct(void)
{
	width = height = 0, array = ZAF_NULLP(ZafLogicalColor), staticArray = staticHandle = false;
	hotSpotX = hotSpotY = 0;
	handle = 0;
	mask = 0;
}

ZafMouseStruct::ZafMouseStruct(const ZafImageStruct &data)
{
	width = data.width, height = data.height, array = data.array;
	hotSpotX = hotSpotY = 0;
	staticHandle = false, staticArray = data.staticArray;
	handle = 0;
	mask = 0;
}

ZafMouseStruct::ZafMouseStruct(int tWidth, int tHeight, ZafLogicalColor *tArray, int tHotSpotX, int tHotSpotY, bool tStaticArray)
{
	width = tWidth, height = tHeight, array = tArray;
	hotSpotX = tHotSpotX, hotSpotY = tHotSpotY;
	staticHandle = false, staticArray = tStaticArray;
	handle = 0;
	mask = 0;
}

// ----- ZafMouseData -------------------------------------------------------

ZafMouseData::ZafMouseData(const ZafImageStruct &data) :
	ZafImageData()
{
	// Initialize the image information.
	hotSpotX = hotSpotY = 0;
	array = ZAF_NULLP(ZafLogicalColor);
	SetImage(*this, data);

	staticHandle = false;
	ZafDisplay::InitializeOSMouse(*this);
}

ZafMouseData::ZafMouseData(const ZafMouseStruct &copy) :
	ZafImageData()
{
	// Initialize the information.
	array = ZAF_NULLP(ZafLogicalColor);
	SetImage(*this, copy);

	hotSpotX = copy.hotSpotX;
	hotSpotY = copy.hotSpotY;

	staticHandle = copy.staticHandle;
	ZafDisplay::InitializeOSMouse(*this);
}

ZafMouseData::ZafMouseData(const ZafMouseData &copy) :
	ZafImageData(copy)
{
	// Initialize the mouse information.
	array = ZAF_NULLP(ZafLogicalColor);
	SetHotSpot(copy.hotSpotX, copy.hotSpotY);
	SetMouse(copy);
}

ZafMouseData::~ZafMouseData(void)
{
	// Destroy the mouse information.
	if (zafDisplay)
	{
		if (!StaticHandle())
			zafDisplay->DestroyOSMouse(*this);
		if (!StaticArray())
			zafDisplay->DestroyZafMouse(*this);
	}
	else if (array && !StaticArray())
		delete []array;
}

void ZafMouseData::Clear(void)
{
	// Destroy the color handle and mask.
	PushLevel();
	if (zafDisplay)
	{
		zafDisplay->DestroyOSMouse(*this);
		zafDisplay->DestroyZafMouse(*this);
	}
	SetError(ZAF_ERROR_NONE);
	PopLevel();
}

ZafData *ZafMouseData::Duplicate(void)
{
	return (new ZafMouseData(*this));
}

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

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

ZafError ZafMouseData::SetHotSpot(int tHotSpotX, int tHotSpotY)
{
	// Reset the hot spots.
	hotSpotX = tHotSpotX;
	hotSpotY = tHotSpotY;

	// Return success.
	return (ZAF_ERROR_NONE);
}

ZafError ZafMouseData::SetMouse(int tWidth, int tHeight,
	ZafLogicalColor *tArray)
{
	// Clear the current os handles.
	if (zafDisplay)
		zafDisplay->DestroyOSMouse(*this);

	// Reset the mouse information.
	PushLevel();
	SetImage(*this, tWidth, tHeight, tArray);
	PopLevel();

	// Return success.
	return (ZAF_ERROR_NONE);
}

ZafError ZafMouseData::SetMouse(const ZafMouseStruct &copy)
{
	// Clear the current os handles.
	if (zafDisplay)
		zafDisplay->DestroyOSMouse(*this);

	// Reset the mouse information.
	PushLevel();
	SetImage(*this, copy);

	// Update the os handles.
	staticHandle = copy.staticHandle;
	ZafDisplay::ResetOSMouse(*this, copy);
	PopLevel();

	// Return success.
	return (ZAF_ERROR_NONE);
}

// ----- Persistent functions -----------------------------------------------
#if defined(USE_ZAF_PERSISTENCE)
ZafMouseData::ZafMouseData(const ZafIChar *name, ZafDataPersistence &persist) :
	ZafImageData(name, persist.PushLevel(className, classID, ZAF_PERSIST_ROOT_DIRECTORY))
{
	// Set the default mouse information.
	InitializeImage(*this);

	staticHandle = false;
	ZafDisplay::InitializeOSMouse(*this);

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

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

void ZafMouseData::ReadData(ZafDataPersistence &persist)
{
	// Read the data.
	ZafFile *file = persist.CurrentFile();
	*file >> width >> height >> hotSpotX >> hotSpotY;
	array = new ZafLogicalColor[width * height];
	file->Read(array, sizeof(ZafLogicalColor), width * height);
}

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

void ZafMouseData::Write(ZafDataPersistence &persist)
{
	// Write the object.
	ZafImageData::Write(persist.PushLevel(className, classID, ZAF_PERSIST_ROOT_DIRECTORY));
	if (persist.Error() == ZAF_ERROR_NONE)
		ZafMouseData::WriteData(persist);
	persist.PopLevel();
	if (persist.Error() != ZAF_ERROR_NONE)
		SetError(persist.Error());
}

void ZafMouseData::WriteData(ZafDataPersistence &persist)
{
	// Write the image information.
	ZafFile *file = persist.CurrentFile();
	*file << width << height << hotSpotX << hotSpotY;
	if (array)
		file->Write(array, sizeof(ZafLogicalColor), width * height);
}
#endif
