// DWBS ------------------------------------------------------------------ DWBS
//
// PLATFORM		: ALL
// PRODUCT		: BIT_DEMON
// VISIBILITY	: PUBLIC
//
// DWBS ------------------------------------------------------------------ DWBS

#include <bdLobby/bdKeyArchive/bdArchiveValue.h>

#define BD_LOG_LEVEL ("lobby/bdKeyArchive/bdArchiveValue")

bdArchiveValue::bdArchiveValue()
: m_valueType(BD_NONE)
{
}

bdArchiveValue::~bdArchiveValue()
{
}

bdArchiveValue::bdArchiveValue(const bdFloat64 value, bdArchiveUpdateType updateType)
: m_f64Value(value),
  m_valueType(BD_FLOAT64),
  m_updateType(updateType)
{
}

bdArchiveValue::bdArchiveValue(const bdInt32 value, bdArchiveUpdateType updateType)
: m_i32Value(value),
  m_valueType(BD_INT32),
  m_updateType(updateType)
{
}

bdArchiveValue::bdArchiveValue(const bdInt64 value, bdArchiveUpdateType updateType)
: m_i64Value(value),
  m_valueType(BD_INT64),
  m_updateType(updateType)
{
}

void bdArchiveValue::setValue(const bdFloat64 value, bdArchiveUpdateType updateType)
{
	m_f64Value = value;
	m_valueType = BD_FLOAT64;
	m_updateType = updateType;
}
void bdArchiveValue::setValue(const bdInt32 value, bdArchiveUpdateType updateType)
{
	m_i32Value = value;
	m_valueType = BD_INT32;
	m_updateType = updateType;
}
void bdArchiveValue::setValue(const bdInt64 value, bdArchiveUpdateType updateType)
{
	m_i64Value = value;
	m_valueType = BD_INT64;
	m_updateType = updateType;
}

bdBool bdArchiveValue::getValue(bdFloat64 &value)
{
	if(m_valueType == BD_FLOAT64)
	{
		value = m_f64Value;

		return true;
	}

	return false;
}

bdBool bdArchiveValue::getValue(bdInt32 &value)
{
	if(m_valueType == BD_INT32)
	{
		value = m_i32Value;

		return true;
	}

	return false;
}

bdBool bdArchiveValue::getValue(bdInt64 &value)
{
	if(m_valueType == BD_INT64)
	{
		value = m_i64Value;

		return true;
	}

	return false;
}

bdArchiveValue::bdArchiveUpdateType bdArchiveValue::getUpdateType()
{
	return m_updateType;
}

bdArchiveValue::ValueType bdArchiveValue::getValueType()
{
	return m_valueType;
}

bdBool bdArchiveValue::hasValue() const
{
	return m_valueType != BD_NONE;
}

void bdArchiveValue::serialize(bdBitBufferRef buffer) const
{
	switch(m_valueType)
	{
		case BD_NONE:
			BD_WARN(BD_LOG_LEVEL, "No data");
			break;
		case BD_FLOAT64:
			buffer->writeFloat64(m_f64Value);
			break;
		case BD_INT32:
			buffer->writeInt32(m_i32Value);
			break;
		case BD_INT64:
			buffer->writeInt64(m_i64Value);
			break;
	}

	buffer->writeUByte8(static_cast<bdUByte8>(m_updateType));
}

bdBool bdArchiveValue::deserialize(bdBitBufferRef buffer)
{
	bdBool ok = true;
	
	bdBitBufferDataType dataType = buffer->readDataType();

	switch(dataType)
	{
		// FIXME: hack!
		// code duplication here from bitbuffer.
		// these cases read out the data without reading the datatype first
		case BD_BB_FLOAT64_TYPE:
		{
			bdFloat64 nf;
			ok = ok && buffer->readBits(&nf, 64);
			if(ok)
			{
				buffer->endianSwap(nf, m_f64Value);
			}
			m_valueType = BD_FLOAT64;
			//ok = ok && buffer->readFloat64(m_f64Value);
		}
		break;
		case BD_BB_SIGNED_INTEGER32_TYPE:			
		{
			bdInt32 ni;
			ok = ok && buffer->readBits(&ni, 32);
			if(ok)
			{
				buffer->endianSwap(ni, m_i32Value);
			}
			m_valueType = BD_INT32;
			//ok = ok && buffer->readInt32(m_i32Value);
		}
		break;
		case BD_BB_SIGNED_INTEGER64_TYPE:
		{
			bdInt64 ni;
			ok = ok && buffer->readBits(&ni, 64);
			if(ok)
			{
				buffer->endianSwap(ni, m_i64Value);
			}
			m_valueType = BD_INT64;
			//ok = ok && buffer->readInt64(m_i64Value);
		}
		break;
		default:
			ok = false;
	}

	return ok;
}
