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

#include <z_idata.hpp>
#include <z_lang.hpp>
#include <z_string.hpp>
#define ZAF_LANGUAGE_INFO
#define ZAF_LANGUAGE_MANAGER_INFO
#include "gbl_def.cpp"
#include "lang_def.cpp"

// --------------------------------------------------------------------------
// ----- ZafLanguageManager -------------------------------------------------
// --------------------------------------------------------------------------

ZafLanguageManager::ZafLanguageManager(void) :
	ZafDataRecord()
{
	language = strdup(defaultLanguageName);
}

ZafLanguageManager::~ZafLanguageManager(void)
{
	delete []language;
}

ZafLanguageData *ZafLanguageManager::Allocate(const ZafIChar *stringID,
	ZafMessageStruct *defaultData)
{
	ZafLanguageData *messageGroup = zafLanguageManager ?
		(ZafLanguageData *)zafLanguageManager->GetObject(stringID) : ZAF_NULLP(ZafLanguageData);
	if (!messageGroup)
	{
#if defined(USE_ZAF_PERSISTENCE)
		if (zafDataPersistence)
		{
			messageGroup = new ZafLanguageData(stringID, *zafDataPersistence);

			if (messageGroup && messageGroup->Error() != ZAF_ERROR_NONE)
			{
				delete messageGroup;
				messageGroup = ZAF_NULLP(ZafLanguageData);
			}
		}
#endif

		if (!messageGroup && defaultData)
		{
			messageGroup = new ZafLanguageData(defaultData, true);
			messageGroup->SetStringID(stringID);
		}

		if (zafLanguageManager)
			zafLanguageManager->Add(messageGroup);
	}

	if (messageGroup)
		messageGroup->Lock();

	return (messageGroup);
}

void ZafLanguageManager::Free(ZafLanguageData *messageGroup)
{
	if (messageGroup)
	{
		messageGroup->UnLock();
		if (!messageGroup->Locked())
		{
			if (zafLanguageManager)
				zafLanguageManager->Subtract(messageGroup);
			if (messageGroup->Destroyable() && messageGroup->NotifyCount() == 0)
	   			delete messageGroup;
		}
	}
}

const ZafIChar *ZafLanguageManager::Language(void)
{
 	return (language);
}

ZafError ZafLanguageManager::SetLanguage(const ZafIChar *languageName)
{
	delete []language;
	language = strdup(languageName);
	SetStringID(language);

#if defined(USE_ZAF_PERSISTENCE)
	if (zafDataManager && zafDataPersistence)
	{
		zafDataPersistence->PushLanguage(zafLanguageManager->Language());
		for (ZafLanguageData *messageGroup = First(); messageGroup;
			messageGroup = (ZafLanguageData *)messageGroup->Next())
		{
			ZafLanguageData *newMessageGroup = new ZafLanguageData(messageGroup->StringID(), *zafDataPersistence);
			messageGroup->SetMessages(*newMessageGroup);
			delete newMessageGroup;
		}
		zafDataPersistence->PopLanguage();
	}
#endif

	return (ZAF_ERROR_NONE);
}

const ZafIChar *ZafLanguageManager::LanguageName(void)
{
	if (zafLanguageManager)
		return (zafLanguageManager->Language());
	else
		return (ZAF_NULLP(ZafIChar));
}

ZafError ZafLanguageManager::SetLanguageName(const ZafIChar *languageName)
{
	LanguageAllocate(languageName);

	if (zafLanguageManager)
		return (zafLanguageManager->SetLanguage(languageName));
	else
		return (ZAF_ERROR_INVALID);
}

void ZafLanguageManager::LanguageAllocate(const ZafIChar *name)
{
	// Check for initialization.
	if (zafLanguageManager)
		return;
	ZafI18nData::AddStaticModule(LanguageFree);

	// Try the zafDataManager.
	ZafError localError = ZAF_ERROR_NONE;
	if (!zafLanguageManager && zafDataManager)
	{
		// Read the language from the data manager.
		if (name && *name)
		{
//			zafLanguageManager = DynamicPtrCast(zafDataManager->AllocateData(name, ZafLanguageData::className, ZafLanguageData::classID), ZafLanguageData);
			zafLanguageManager = new ZafLanguageManager();
			zafLanguageManager->SetStringID(name);
		}

		// Make sure zafLanguageManager's destructor isn't called multiple times.
#if defined(USE_ZAF_PERSISTENCE)
		if (zafDataPersistence)
		{
			localError = zafDataPersistence->Error();
			zafDataPersistence->SetError(ZAF_ERROR_NONE);
		}
#endif
	}

	// Reset the language name.
	if (!zafLanguageManager)
	{
		zafLanguageManager = new ZafLanguageManager();
		zafLanguageManager->SetStringID(defaultLanguageName);
	}

	// Set/clear the zafLanguageManager error.
	zafLanguageManager->SetError(localError);
}

void ZafLanguageManager::LanguageFree(bool globalRequest)
{
	// Destroy the static language.
	if (globalRequest && zafLanguageManager && zafLanguageManager->Destroyable() &&
		zafLanguageManager->NotifyCount() == 0)
	{
		delete zafLanguageManager;
		zafLanguageManager = ZAF_NULLP(ZafLanguageManager);
	}
}

ZafData *ZafLanguageManager::Add(ZafData *object, ZafData *position)
{
	if (!object)
		return (ZAF_NULLP(ZafData));

	return (ZafDataRecord::Add(object, position));
}

ZafData *ZafLanguageManager::Subtract(ZafData *object)
{
	if (!object)
		return (ZAF_NULLP(ZafData));

	return (ZafDataRecord::Subtract(object));
}

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

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