#include "cdb.h"
#include "symbian_auto_ptr.h"

#ifndef __S60V2__
#include "cdb_v1.h"
#else
#include "cdb_v2.h"
#endif

CCommDbDump::CCommDbDump()
{
}

void CCommDbDump::ConstructL()
{
	iFs.Connect();
	iCC=CCnvCharacterSetConverter::NewL();
	iCC->PrepareToConvertToOrFromL(KCharacterSetIdentifierIso88591, iFs);
	state=CCnvCharacterSetConverter::KStateDefault;
}

CCommDbDump::~CCommDbDump()
{
	iFile.Close();
	iFs.Close();
}

bool CCommDbDump::IsRow(TDbType t)
{
	if (t==TABLE || t==TABLE_SAME_AS_PREV || t==END) return false;
	return true;
}

void CCommDbDump::HandleField(const TDbItem& field)
{
	TInt err;
	TUint32 UintVal; TBool BoolVal;
	HBufC* LongTextVal;
	TPtrC name(field.iName);
	TRAP(err,
	switch(field.iType) {
	case UINT:
		iView->ReadUintL(name, UintVal);
		iValue.Format(_L("%u"), UintVal);
		break;
	case BOOL:
		iView->ReadBoolL(name, BoolVal);
		if (BoolVal) {
			iValue=_L("TRUE");
		} else {
			iValue=_L("FALSE");
		}
		break;
	case DES:
		iView->ReadTextL(name, iValue);
		break;
	case DES8:
		iView->ReadTextL(name, iBuf);
		CC().ConvertToUnicode(iValue, iBuf, state);
		break;
	case LONGDES:
		LongTextVal=iView->ReadLongTextLC(name);
		iValue=LongTextVal->Des().Left(2048);
		CleanupStack::PopAndDestroy();
		break;
	}
	);
	if (err!=KErrNone) {
		if (err==KErrUnknown) {
			iValue=_L("NULL");
		} else {
			iValue.Format(_L("Error reading value %d"), err);
		}
	}
	if (err!=-1) FieldValue(name, iValue);
}

void CCommDbDump::OpenViewLC(const TDesC& name)
{
	iView=db->OpenTableLC(name);
	CleanupStack::Pop();
}

void CCommDbDump::DumpDBtoFileL(const TDesC& FileName)
{
	User::LeaveIfError(iFile.Replace(Fs(), FileName, EFileWrite));
	CleanupClosePushL(iFile);

	db=CCommsDatabase::NewL(EDatabaseTypeIAP);
	CleanupStack::PushL(db);
	db->ShowHiddenRecords();

	TDbItem	item;
	int	i;
	int	previous_i=0;

	TInt err;

	for(i=0; (item=IAP_DB[i]).iType!=END; i++ ) {
		if (item.iType==TABLE) {
			previous_i=i;
		}
		if (item.iType==TABLE || item.iType==TABLE_SAME_AS_PREV) {
			TPtrC name(item.iName);
			BeginTable(name);
			TRAP(err, OpenViewLC(name));
			if (err!=KErrNone) {
				iValue.Format(_L("Error opening table %S: %d"), &(item.iName), err);
				FieldValue(_L("Error"), iValue);
			} else {
				CleanupStack::PushL(iView);
				while( (err=iView->GotoNextRecord()) == KErrNone ) {
					BeginRow();
					TDbItem field;
					int f;
					for (f=0; IsRow( (field=DEFAULT_FIELDS[f]).iType ); f++) {
						HandleField(field);
					}
					for (f=previous_i+1; IsRow( (field=IAP_DB[f]).iType ); f++) {
						HandleField(field);
					}
					EndRow();
				}
				CleanupStack::PopAndDestroy(); // iView
			}
			EndTable();
		}
	}
	CleanupStack::PopAndDestroy(2); // iFile, db
}


void CCommDbDump::BeginTable(const TDesC& name)
{
	iFile.Write(_L8("\nTABLE "));
	CC().ConvertFromUnicode(iBuf, name);
	iFile.Write(iBuf);
	iFile.Write(_L8("\n"));
}

void CCommDbDump::BeginRow()
{
	iFile.Write(_L8("\nROW"));
}

void CCommDbDump::FieldValue(const TDesC& name, const TDesC& value)
{
	iFile.Write(_L8("\n"));
	CC().ConvertFromUnicode(iBuf, name);
	iFile.Write(iBuf);
	iFile.Write(_L8(" = "));
	CC().ConvertFromUnicode(iBuf, value);
	iFile.Write(iBuf);
}

void CCommDbDump::EndRow()
{
	iFile.Write(_L8("\n"));
}

void CCommDbDump::EndTable()
{
	iFile.Write(_L8("\n"));
}

CCommDbDump* CCommDbDump::NewL()
{
	auto_ptr<CCommDbDump> ret(new (ELeave) CCommDbDump);
	ret->ConstructL();
	return ret.release();
}

