#include "HexRecord.h"
#include <QByteArray>
#include <QDataStream>
CHexRecord::CHexRecord(void)
{
	mRecordData = NULL;
}

CHexRecord::~CHexRecord(void)
{
	mStartAddress = 0;
    mRecordSize = 0;
	mRecordType = 0;
	mExtendedAddress = 0;
//	delete[] mRecordData;
}

int CHexRecord::DecodeRawRecord(QString *RawRecordData, unsigned int HighAddress)
{
    bool OK;
//	CString RecordString;
    QString RecordString;
	bool IsAllFF = true;
    int StartIndex = RawRecordData->indexOf(QChar(':'));

	if(StartIndex == -1)
		return -1;

    RecordString = RawRecordData->right(RawRecordData->length()-1);	//Remove all that is left of ':'

    QString RecordSizeString;
    RecordSizeString = RecordString.mid(0,2);
    //sscanf_s(RecordSizeString.GetBuffer(),"%x",&mRecordSize);
    mRecordSize = RecordSizeString.toUInt(&OK,16);

    QString RecordAddress;
    RecordAddress = RecordString.mid(2,4);
    //sscanf_s(RecordAddress.GetBuffer(),"%x",&mStartAddress);
    mStartAddress = RecordAddress.toUInt(&OK,16);
	mStartAddress |= (HighAddress & 0xFFFF0000);

	if(mStartAddress == 0x1d0097F0)
	{
		mStartAddress = mStartAddress;
	}

    QString RecordTypeString;
    RecordTypeString = RecordString.mid(6,2);
    //sscanf_s(RecordTypeString.GetBuffer(),"%x",&mRecordType);
    mRecordType = RecordTypeString.toUInt(&OK,16);

    RecordString = RecordString.right(RecordString.length()- 8);
	
	if(mRecordType >= MAX_RECORD_TYPE)
		return RET_UNKNOWN_RECORD_TYPE;

	if(mRecordSize %2 != 0)
	{
		mRecordSize++;//Pad the last word if we do not have an even number of bytes in the record.
	}
	

	switch(mRecordType)
	{
		case DATA_RECORD_TYPE:		//0x00
		{
			char *DataPtr;
            QString DataString;
           // mRecordData = new char[mRecordSize/*+10*/];	//I have no clue why I have to allocate more space but if I don't delete[] crashes.  I think it's a scanf bug...
//            DataPtr = mRecordData.data();
			
			for(unsigned int i = 0; i < mRecordSize; i++)
			{
                DataString = RecordString.mid(2*i,2);
                char DataByte = (char)DataString.toUShort(&OK,16);
                //sscanf_s(DataString.GetBuffer(),"%x",&mRecordData[i],sizeof(char)/*DataPtr*/);
                //mRecordData[i] = (char)DataString.toUShort(&OK,16);
                mRecordData.append(DataByte);
                if((unsigned char)DataByte != 0xFF)
					IsAllFF = false;
                //DataPtr++;
			}
            if(mRecordSize %2 != 0)     //Is this really needed?
			{
                //*DataPtr++ = 0xFF;	//Pad the last word if we do not have an even number of bytes in the record.
                mRecordData.append(0xFF);
			}

			mRecordSize /= 4;	//Transfom the size in WORD size...

//#ifdef IGNORE_ALL_FF_RECORDS
			if(IsAllFF)
			{

				return RET_IGNORED_ALL_FF_RECORD;
			}
			else
				return RET_DATA_RECORD;
//#else
	//			return RET_DATA_RECORD;
//#endif

			break;
		}
		case EOF_RECORD_TYPE:			//0x01
		{
			return RET_EOF_RECORD;
			break;
		}
		case EXTENDED_ADDRESS_TYPE:		//0x02
		{
			return RET_UNMANAGED_RECORD_TYPE;

			break;
		}			
		case START_SEGMENT_ADDRESS_TYPE:		//0x03
		{
			return RET_UNMANAGED_RECORD_TYPE;
			break;
		}		
		case EXTENDED_LINEAR_ADDRESS_TYPE:		//0x04
		{
            QString ExtendedAddressString;
            ExtendedAddressString = RecordString.mid(0,4);
            //sscanf_s(ExtendedAddressString.GetBuffer(),"%x",&mExtendedAddress);
            mExtendedAddress = ExtendedAddressString.toUInt(&OK,16);
			mExtendedAddress <<= 16;
			return RET_EXTENDED_LINEAR_ADDRESS;
			break;
		}	
		case START_LINEAR_ADDRESS_TYPE:			//0x05
		{
			return RET_UNMANAGED_RECORD_TYPE;
			break;
		}
		default:
		{
			return RET_UNKNOWN_RECORD_TYPE;
		}
	}
}

unsigned int CHexRecord::AppendRecord(CHexRecord *NewRecord)
{
	unsigned int NewSize;

    NewSize = GetRecordSizeInBytes() + NewRecord->GetRecordSizeInBytes();

  //  char *NewBuff = new char[NewSize];
  //  memcpy(NewBuff,mRecordData,GetRecordSizeInBytes());
  //  memcpy(&NewBuff[GetRecordSizeInBytes()],NewRecord->GetDataBuffer(),NewRecord->GetRecordSizeInBytes());

    //delete[] mRecordData;
    //mRecordData = NewBuff;

    mRecordData.append(NewRecord->GetData());
	mRecordSize = NewSize/4;

	return 1;
}

CHexRecord& CHexRecord::operator = (const CHexRecord &rhs)
{
	if(this == &rhs)
		return *this;

	mExtendedAddress = rhs.mExtendedAddress;
	mRecordSize = rhs.mRecordSize;
	mStartAddress = rhs.mStartAddress;
	mRecordType = rhs.mRecordType;
    mRecordData = rhs.mRecordData;

//	mRecordData = new char[mRecordSize*4];
//	memcpy(mRecordData,rhs.mRecordData,mRecordSize*4);

	return *this;
}

QByteArray CHexRecord::GetRecord()
{
    QByteArray Record;
    Record.clear();
    QDataStream Strm(&Record,QIODevice::WriteOnly);



    //Header
            Strm << HEX_RECORD_HEADER;
    //Size
            Strm << GetRecordSizeInBytes();
    //Address
            Strm << GetStartAddress();
    //Data
            Record.append(mRecordData);


    return Record;
}
