#pragma once

#include "MPT_Buffer.h"
#include "MobilePhoteTool_IFD.h"
#include "Raw_Processor_Creater.h"
#include "Mathe.h"
#include "MPT_Exception.h"
//#include <vector>
using namespace std;

namespace MobilePhotoTool{
	class TIFF_reader
	{


	private:
		/**
		 * The inputbuffer
		 */
		MPT_Buffer *buffer;

		/**
		 * Read the structur of the inputfile
		 */
		void read_Header(MPT_Exception *exception);

		/**
		 * The IFD in this tiff file
		 */
		IFD **ifd;

		/**
		 * The number of ifds
		 */
		size_t number_ifd;


		/**
		 * This ifd points to the preview
		 */
		IFD *ifd_preview;

		/**
		 * Search for the preview ifd and saves it in this->ifd_preview.
		 * 
		 */
		void set_ifd_preview(MPT_Exception *exception);

		/**
		 * The maximal number of Pixel
		 */
		static const unsigned int MAX_PIXEL = 100000000;

		/**
		 * The class for all raw processing,
		 */
		Raw_Processor *raw_processor;

		/**
		 *
		 */
		void load_Raw_Processor(MPT_Exception *exception);

		/**
		 * The main exception
		 */
		MPT_Exception *exception;


		/**
		 * Add a new ifd to the reader;
		 */
		void set_IFD(MPT_Exception *exception, IFD *ifd);

	public:

		/**
		 * Constructs a TIFF_reader 
		 *
		 * @param path The path to a valid tiff or dng file.
		 */
		TIFF_reader(MPT_Exception *exception, const char *path);

		~TIFF_reader(void);

		/**
		 *	@return The preview image width.
		 */
		unsigned int get_preview_width(MPT_Exception *exception);

		/**
		 *	@return The preview image length.
		 */
		unsigned int get_preview_length(MPT_Exception *exception);


		/**
		 * The data array will filled with the preview image.
		 * Take care, that data is big enough.
		 *
		 * @param data Here the image will be saved.
		 * @param size The maximum size of integer fits in data
		 * @return If the function works it will be 0.
		 */
		unsigned int getPreview_int_RGB(MPT_Exception *exception, unsigned int *data, size_t size);

		/**
		 * Get the current Raw_Processor. If there ara no Raw_Processor it
		 * create one.
		 */
		Raw_Processor *get_Raw_Processor(MPT_Exception *exception);

		/**
		 *
		 */
		MPT_Exception *get_exception();

		static bool test_width_length(MPT_Exception *exception, unsigned int width, unsigned int length);
	};
}
