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

#include <z_string.hpp>
#include <z_data.hpp>
#include <z_stdlib.hpp>
#include <z_lang.hpp>

// ZafData objects must have unique StringID values to avoid storage name conflicts.
ZafIChar *GenerateUniqueStringID(void);

ZafIChar *GenerateUniqueStringID(void)
{
	static ZafIChar ZAF_FARDATA newStringID[ZAF_MAXNAMELEN];
	static ZafInt32 value = 0;
	strcpy(newStringID, ZafData::className);
	itoa(value++, &newStringID[strlen(newStringID)], 10, 0);
	if (value < 0)
		value = 0;
	return (newStringID);
}

// ----- ZafData ------------------------------------------------------------

ZafData::ZafData(void) :
	ZafNotification(), error(ZAF_ERROR_NONE), level(0), destroyable(true)
{
	SetStringID(GenerateUniqueStringID());
}

ZafData::ZafData(const ZafData &copy) :
	ZafElement(copy),
	ZafNotification(), error(ZAF_ERROR_NONE), level(0), destroyable(true)
{
	// Copy constructor does not set any values from the original copy.
	// The notifications must be re-established.
	SetStringID(GenerateUniqueStringID());
}

ZafData::~ZafData(void)
{
}

ZafEventType ZafData::Event(const ZafEventStruct &event)
{
	// Do not process the event.
	return (event.type);
}

ZafData *ZafData::GetObject(ZafNumberID matchID)
{
	return ((matchID == numberID) ? this : ZAF_NULLP(ZafData));
}

ZafData *ZafData::GetObject(const ZafIChar *matchID)
{
	return (!streq(stringID, matchID) ? this : ZAF_NULLP(ZafData));
}

#if defined(ZAF_UNICODE)
#include <z_str.hpp>
ZafData *ZafData::GetObject(const char *matchID)
{
	ZafStringData stringData(matchID);
	return (GetObject(stringData.Text()));
}
#endif

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

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

int ZafData::PopLevel(bool levelNotify)
{
	// Decrement the level count.
	if (--level == 0 && levelNotify)
		UpdateObjects();
	return (level);
}

int ZafData::PushLevel(void)
{
	// Increment the level count.
	return (++level);
}

ZafError ZafData::SetError(ZafError setError)
{
	// Make sure the attribute has changed.
	if (error != setError)
		error = setError;

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

// ----- Persistent functions -----------------------------------------------
#if defined(USE_ZAF_PERSISTENCE)
ZafData::ZafData(const ZafIChar *name, ZafDataPersistence &persist) :
	ZafNotification(), error(ZAF_ERROR_NONE), level(0), destroyable(true)
{
	// Set the string identification.
	SetStringID(name);

	// Prepare the file.
	persist.AllocateFile(stringID, ZAF_FILE_READ);
}

void ZafData::Write(ZafDataPersistence &persist)
{
	// Register the read procedure.
	persist.AddDataConstructor(ClassName(), ClassID(), ReadFunction());

	// Prepare the file.
	persist.AllocateFile(stringID, ZAF_FILE_CREATE | ZAF_FILE_READWRITE);
}
#endif
