//****************************************************************************
//Copyright (C) 2005-2006 Beijing BlueDJ Technology Co.,Ltd. All rights reserved.

//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program (in the file LICENSE.GPL); if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

//Please visit http://www.bluedj.com for more infomation about us.
//Contact us at ggwizard@gmail.com or darkdong@gmail.com.
//****************************************************************************/

#include "protocol.h"
#include "DJGameTraceManager.h"

DJGameTraceManager::DJGameTraceManager()
{
	c_filename = GetTempSaveFileName();
	c_shCurStep = 0;
}
DJGameTraceManager::DJGameTraceManager(QString & filename,quint16 headlen)
{
	CreateNewFile(filename,headlen);
}

DJGameTraceManager::~DJGameTraceManager()
{
	if(!c_filename.isNull() && !c_filename.isEmpty())
		QFile::remove(c_filename);
}

DJGameTraceManager::DJGameTraceManager(DJGameTraceManager& a)
{
	if(!c_filename.isNull() && !c_filename.isEmpty())
		QFile::remove(c_filename);
	c_filename = GetTempSaveFileName();
	QFile::copy(a.GetFileName(),c_filename);
	c_shCurStep = a.GetCurrentStepNumber();
}

int DJGameTraceManager::operator=(DJGameTraceManager& a)
{
	if(!c_filename.isNull() && !c_filename.isEmpty())
		QFile::remove(c_filename);
	c_filename = GetTempSaveFileName();
	QFile::copy(a.GetFileName(),c_filename);
	c_shCurStep = a.GetCurrentStepNumber();
	return 0;
}

void DJGameTraceManager::CreateNewFile(QString &filename,quint16 headlen)
{
	if(!c_filename.isNull() && !c_filename.isEmpty())
		QFile::remove(c_filename);
	
	c_filename = GetTempSaveFileName();
	QFile file(filename);
	if (file.open(QIODevice::ReadOnly))
	{
		if(file.size()<=headlen)
			return;
		char *buffer = (char *)malloc(file.size());
		if(buffer)
		{
			if(headlen>0)
				file.read(buffer,headlen);
			file.read(buffer,file.size()-headlen);
			QFile newfile(c_filename);
			if (newfile.open(QIODevice::WriteOnly))
			{
				newfile.write(buffer,file.size()-headlen);
				newfile.flush();
				newfile.close();
			}
			free(buffer);
		}
		file.close();
	}
	c_shCurStep = 0;
}

QString DJGameTraceManager::GetTempSaveFileName()
{
	QDir dir = QDir::home();
    if (!dir.exists(QString("DJGameSave")))
	{
		 dir.mkdir("DJGameSave");
	}
	dir.cd("DJGameSave");
	if (!dir.exists(QString("temp")))
	{
		 dir.mkdir("temp");
	}
	dir.cd("temp");
	QString name =dir.path();
	char buffer[32];
	sprintf(buffer,"%04x%02x_%08x.sav",rand()%0x10000,1,rand());
	
	name += QString(buffer);
	return name;
}
bool DJGameTraceManager::Next(char * buffer,quint16 *pshLen)
{
	c_shCurStep ++;
	return GetTrace(c_shCurStep,buffer,pshLen);
}

bool DJGameTraceManager::GetTrace(unsigned short shStep,char * buffer,quint16 *pshLen)
{
	return __GetTrace(c_filename,shStep,buffer,pshLen);
}
bool DJGameTraceManager::__GetTrace(QString &filename,unsigned short shStep,char * buffer,quint16 *pshLen)
{
	if(shStep == 0)
		shStep = 1;
	if(*pshLen <sizeof(GeneralGameTrace2Head))
		return false;
	char temp[260];
	GeneralGameTrace2Head *ptrace =(PGeneralGameTrace2Head)temp;
	QFile file(filename);
	if (file.open(QIODevice::ReadOnly))
	{
		int i=1,iLen=0;
		qint64 pos;
		while(iLen + sizeof(GeneralGameTrace2Head) < file.size())
		{
			pos = file.pos();
			file.read(temp,sizeof(GeneralGameTrace2Head));
			if(iLen + sizeof(GeneralGameTrace2Head) + ptrace->chBufLen > file.size() )
			{
				file.close();
				return false;
			}
			file.seek(pos);
			if(i == shStep)
			{
				if(*pshLen < sizeof(GeneralGameTrace2Head)+ptrace->chBufLen)
				{
					file.close();
					return false;
				}
				
				file.read(buffer,sizeof(GeneralGameTrace2Head) + ptrace->chBufLen);
				file.close();
				return true;
			}else
			{
				file.read(temp,sizeof(GeneralGameTrace2Head) + ptrace->chBufLen);
			}
			i++;
			iLen += sizeof(GeneralGameTrace2Head)+ptrace->chBufLen;
		}
		file.close();
		if(i>1 && shStep == DJGAME_GAMETRACE_LAST)
		{
			memcpy(buffer,temp,sizeof(GeneralGameTrace2Head) + ptrace->chBufLen);
			return true;
		}
		return false;
	}
	return false;
}

bool DJGameTraceManager::AppendTrace(PGeneralGameTrace2Head ptrace)
{
	bool b = __AppendTrace(c_filename,ptrace);
	c_shCurStep = DJGAME_GAMETRACE_LAST;
	return b;
}
bool DJGameTraceManager::__AppendTrace(QString &filename,PGeneralGameTrace2Head ptrace)
{
	QFile file(filename);
	if (file.open(QIODevice::Append))
	{
		file.write((char *)ptrace,sizeof(GeneralGameTrace2Head)+ptrace->chBufLen);
		file.flush();
		file.close();
		return true;
	}
	return false;
}

	
void DJGameTraceManager::SaveGameTrace(char *head,quint16 headlen)
{
}

	
QString DJGameTraceManager::GetFileName()
{
	return c_filename;
}

unsigned short DJGameTraceManager::GetCurrentStepNumber()
{
	return c_shCurStep;
}
unsigned short DJGameTraceManager::GetTotalSteps()
{
	return 0;
}
