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

#include <bdLobby/bdTitleUtilities/bdTitleUtilities.h>
#include <bdLobby/bdRemoteTaskManager/bdRemoteTaskManager.h>

#define BD_LOG_LEVEL	("lobby/titleUtilities")

bdTitleUtilities::bdTitleUtilities(bdRemoteTaskManager *const remoteTaskManager)
:m_remoteTaskManager(remoteTaskManager),
 m_errorCode(BD_NO_ERROR)
{
}

bdTitleUtilities::~bdTitleUtilities()
{
}

bdRemoteTask* bdTitleUtilities::verifyString(bdNChar8 *str, bdUInt length)
{
	BD_ASSERT(m_remoteTaskManager, "No Taskmanager");
	bdRemoteTask *remoteTask = BD_NULL;

	bdBitBuffer buffer(0,true);

	// write empty controller index, it doesn't matter who has requested verifyString
	buffer.writeUByte8(0); 
	buffer.writeString(str, length);
	m_errorCode = m_remoteTaskManager->startTask(&remoteTask,
												 BD_TITLE_UTILITIES_SERVICE,
                                                 BD_VERIFY_STRING,
                                                 buffer);

	return remoteTask;
}

bdRemoteTask* bdTitleUtilities::recordEvent(const bdNChar8 *eventStr)
{
	bdRemoteTask *remoteTask = BD_NULL;
	bdBitBuffer buffer (0,true);
	buffer.writeUByte8(0);
	buffer.writeString(eventStr, BD_MAX_RECORD_EVENT_STRING_LENGTH);

	m_errorCode = m_remoteTaskManager->startTask(&remoteTask,
		BD_TITLE_UTILITIES_SERVICE,
		BD_RECORD_EVENT,
		buffer);

	return remoteTask;
}

bdRemoteTask* bdTitleUtilities::getTitleStats()
{
	BD_ASSERT(m_remoteTaskManager, "No Taskmanager");
	bdRemoteTask *remoteTask = BD_NULL;
	bdBitBuffer buffer(0,true);

	// write empty controller index, it doesn't matter who has requested getTitleStats
	buffer.writeUByte8(0); 
	m_errorCode = m_remoteTaskManager->startTask(&remoteTask,
												 BD_TITLE_UTILITIES_SERVICE,
                                                 BD_GET_TITLE_STATS,
                                                 buffer);

	return remoteTask;
}

/// Reports the impression of ad units
bdRemoteTask* bdTitleUtilities::trackImpression(bdUWord numUnits,
												bdUnitTracker *units)
{
	BD_ASSERT(m_remoteTaskManager, "No Taskmanager");
	bdRemoteTask *remoteTask = BD_NULL;
	bdBitBuffer buffer(0,true);

	// write empty controller index, it doesn't matter who has called trackImpression
	buffer.writeUByte8(0);

	for (bdUInt i=0;i<numUnits;i++)
	{
		units[i].serialize(buffer);
	}

	m_errorCode = m_remoteTaskManager->startTask(&remoteTask,
												BD_TITLE_UTILITIES_SERVICE,
												BD_TRACK_IMPRESSION,
												buffer);

	return remoteTask;
}

bdRemoteTask* bdTitleUtilities::getAdUnit(bdUnitLayout layout, 
                                          const bdNChar8 *mimeType,
                                          const bdNChar8 *language,
                                          bdScreenType screenType,
                                          bdUISection lobbySection)
{
	BD_ASSERT(m_remoteTaskManager, "No Taskmanager");
	bdRemoteTask *remoteTask = BD_NULL;
	bdBitBuffer buffer(0,true);

	// write empty controller index, it doesn't matter who has requested getTitleStats
	buffer.writeUByte8(0);

	bdInt16 tempLayout = static_cast<bdInt16>(layout);
	bdInt16 tempScreenType = static_cast<bdInt16>(screenType);
	bdInt16 tempLobbySection = static_cast<bdInt16>(lobbySection);

	buffer.writeInt16(tempLayout);
	buffer.writeString(mimeType);
	buffer.writeString(language);
	buffer.writeInt16(tempScreenType);
	buffer.writeInt16(tempLobbySection);
	m_errorCode = m_remoteTaskManager->startTask(&remoteTask,
        										 BD_TITLE_UTILITIES_SERVICE,
                                                 BD_GET_AD_UNIT,
                                                 buffer);
	return remoteTask;
}

bdBool bdTitleUtilities::handleTask(const bdRemoteTask *const remoteTask,
                                    bdQueryResult *const queryResult)
{
	bdBool ok;
	bdBitBufferRef buffer = remoteTask->getResults();
	bdUInt32 taskErrorCode = BD_MAX_ERROR_CODE;
	m_errorCode = BD_HANDLE_TASK_FAILED;
	ok = buffer->readUInt32(taskErrorCode);
	if (ok)
	{
		m_errorCode = static_cast<bdLobbyErrorCode>(taskErrorCode);
		if (m_errorCode == BD_NO_ERROR)
		{
			bdUByte8 operation;
			ok = buffer->readUByte8(operation);
			if(ok)
			{
				switch (operation)
				{
					case BD_VERIFY_STRING:
					case BD_GET_AD_UNIT:
					case BD_GET_TITLE_STATS:
					{
						if (queryResult)
						{
							ok = queryResult->handleResult(1, buffer);
						}
					}
					break;
					default:	
					{
					}
					break;
				}
			}
		}
#if defined BD_DEBUG
		else
		{

			bdUInt64 transactionID;
			bdUInt64 connectionID;

			connectionID = m_remoteTaskManager->getConnectionID();
			transactionID = remoteTask->getTransactionID();

			// here we originally called bdRemoteTaskManager::obtainTransactionID
			BD_WARN(BD_LOG_LEVEL, "Transaction ID " BD_UINT_64_FORMAT ":" BD_UINT_64_FORMAT " failed.",
				connectionID, transactionID);
		}
#endif // BD_DEBUG
	}
	return (m_errorCode == BD_NO_ERROR && ok);
}

bdLobbyErrorCode bdTitleUtilities::getErrorCode() const
{
	return m_errorCode;
}
