#include "MPT_Buffer.h"

namespace MobilePhotoTool{

	MPT_Buffer::MPT_Buffer(MPT_Exception *exception, const char *path)
	{
		file =  fopen(path, "rb");
		if(file == NULL){
			MPT_EXCEPTION("Unable to open the file") ;
		}
		fseek(file, 0, SEEK_END),
		size = ftell(file);
		fseek(file, 0, SEEK_SET);

		order = BigEndian;
	}


	MPT_Buffer::~MPT_Buffer(void)
	{
		fclose(file);
	}

	size_t MPT_Buffer::position(MPT_Exception *exception)
	{
		long position = 0;
		if(!ferror(file)){
			position = ftell(file);
		}else{
			MPT_EXCEPTION("Unable to read the file.") 0;
		}
		return position;
	}

	void MPT_Buffer::position(MPT_Exception *exception, const size_t position)
	{
		if(position < size){
			if(!ferror(file)){
				fseek(file, (long)position, SEEK_SET);
			}else{
				MPT_EXCEPTION("Unable to read the file.");
			}
		}else{
			MPT_EXCEPTION("The position is out of range.");
		}
	}

	void MPT_Buffer::set_order(MPT_Exception *, Endian endian)
	{
		order = endian;
	}

	unsigned short MPT_Buffer::get_ushort(MPT_Exception *exception)
	{
		unsigned short value = 0;
		unsigned char input[2];
		//long pos = ftell(file);
		if(!fread((char *)input, 2, 1, file)){
			MPT_EXCEPTION("Can not read the file eof") 0;
		}
		if(order == BigEndian){
			value = input[0] << 8;
			value |= input[1];
		}else{
			value = input[1] << 8;
			value |= input[0];
		}

		return value;
	}

	unsigned int MPT_Buffer::get_uint(MPT_Exception *exception)
	{
		unsigned int value = 0;
		unsigned char input[4];
		if(!fread((char *)input, 4, 1, file)){
			MPT_EXCEPTION("Can not read the file") 0;
		}
		if(order == BigEndian){
			value = input[0] << 24;
			value |= input[1] << 16;
			value |= input[2] << 8;
			value |= input[3];
		}else{
			value = input[3] << 24;
			value |= input[2] << 16;
			value |= input[1] << 8;
			value |= input[0];
		}

		return value;
	}

	int MPT_Buffer::get_int(MPT_Exception *exception)
	{
		int value = 0;
		unsigned char input[4];
		if(!fread((char *)input, 4, 1, file)){
			MPT_EXCEPTION("Can not read the file") 0;
		}
		if(order == BigEndian){
			value = input[0] << 24;
			value |= input[1] << 16;
			value |= input[2] << 8;
			value |= input[3];
		}else{
			value = input[3] << 24;
			value |= input[2] << 16;
			value |= input[1] << 8;
			value |= input[0];
		}

		return value;
	}

	unsigned char MPT_Buffer::get_ubyte(MPT_Exception *exception)
	{
		unsigned char value = 0;
		//unsigned char input[1];
		if(!fread((char*)&(value), 1, 1, file)){
			MPT_EXCEPTION("Can not read the file") 0;
		}
		
		return value;
	}

	size_t MPT_Buffer::get_size(MPT_Exception *)
	{
		return size;
	}

	size_t MPT_Buffer::get_ubytes(MPT_Exception *exception, unsigned char *data, size_t count)
	{
		size_t number = 0;
		number = fread((char *)data, 1, count, file);
		if(number != count){
			MPT_EXCEPTION("Can not read the file") 0;
		}
		return number;
	}
}
