// apl_image.h
#pragma once

#ifdef APL_IMAGE_IMPL
#define APL_CLASS_EXPORT	_declspec(dllexport)
#else
#define APL_CLASS_EXPORT	_declspec(dllimport)

#ifdef _DEBUG
#ifdef UNICODE
#pragma comment (lib,"apl_image_ud.lib")
#else
#pragma comment (lib,"apl_imageD.lib")
#endif
#else
#ifdef UNICODE
#pragma comment (lib,"apl_image_u.lib")
#else
#pragma comment (lib,"apl_image.lib")
#endif
#endif

#endif


class CxImage;

#define APL_DI_FIT_TO_RECT			1 //вписать в прямоугольник
#define APL_DI_FIT_TO_RECT_WSCALE	2 //сохранить пропорции

#ifndef PIMAGE 
#define PIMAGE void
#endif


enum ENUM_APLIMAGE_FORMATS{
	APLIMAGE_FORMAT_UNKNOWN = 0,
	APLIMAGE_FORMAT_BMP = 1,
	APLIMAGE_FORMAT_GIF = 2,
	APLIMAGE_FORMAT_JPG = 3,
	APLIMAGE_FORMAT_PNG = 4,
	APLIMAGE_FORMAT_ICO = 5,
	APLIMAGE_FORMAT_TIF = 6,
	APLIMAGE_FORMAT_TGA = 7,
	APLIMAGE_FORMAT_PCX = 8,
	APLIMAGE_FORMAT_WBMP = 9,
	APLIMAGE_FORMAT_WMF = 10,
	APLIMAGE_FORMAT_JP2 = 11,
	APLIMAGE_FORMAT_JPC = 12,
};

class APL_CLASS_EXPORT CaplImage  
{
public:	

	CaplImage();
	CaplImage(const TCHAR * filename, DWORD imagetype);

	virtual ~CaplImage();
	void Clear();

	bool HasImage();

	bool SetImage(CxImage* pImage);
	bool SetImage(CaplImage* pImage);
	bool CreateFromBitmap(HBITMAP hBm);

	bool LoadFromBuf(BYTE *pBuf, DWORD size, DWORD type);
	bool LoadImage(LPCTSTR lpszFileName);
	bool Decode(BYTE *pBuf, DWORD size, DWORD type);

	void Copy(const CaplImage &src, bool copypixels = true, bool copyselection = true, bool copyalpha = true);

	HBITMAP MakeBitmap(HDC hdc = NULL); // Потом надо вызвать DeleteObject().  BITMAP будес с параметрами цветности как в исходном файле

	bool SaveAs(LPCTSTR lpszFileName);
	bool Save(const TCHAR* filename, DWORD imagetype);

	bool Encode(BYTE * &buffer, long &size, DWORD imagetype);

	DWORD GetType();
	bool GetFormat(CString &sFormat);
	bool GetImageDimensions(CSize &sizes);
	bool GetImageDimensions(int &cx, int &cy);
	DWORD GetHeight();
	DWORD GetWidth();
	bool GetDPI(long &xDPI, long &yDPI);
	bool GetColorInfo(CString &color_scheme, CString &img_coding);
	int	GetNumColors();
	int	GetBpp();
	bool IsColor(); 

	void Draw(CRect &rect, CDC *pDC, UINT flags = APL_DI_FIT_TO_RECT_WSCALE); // Функция Даровских (не изменять)
	long Stretch(HDC hdc, long xoffset, long yoffset, long xsize, long ysize, DWORD dwRop = SRCCOPY);
	long Stretch(HDC hdc, const RECT& rect, DWORD dwRop = SRCCOPY);
	long Blt(HDC pDC, long x=0, long y=0);
	long Draw2(HDC hdc, long x=0, long y=0, long cx = -1, long cy = -1);
	long Draw(HDC hdc, long x=0, long y=0, long cx = -1, long cy = -1, RECT* pClipRect = 0, bool bSmooth = false);

	bool ayStrechBigImg(CDC *dc, int out_cx, int out_cy, bool bHalftone); // Для отрисовки больших тифов созвездия

	// frame operations (Для многостраничных TIFF)
	long GetNumFrames();
	long GetFrame();
	bool SetFrame(long nFrame); // Переключает (перечитывает) страницу

	// Функции Даровских перенесенные AsIs в этот класс

	// Сохранять тиф-ы в градациях серого как монохромный (1 bit/pixel)
	// Возвращает предыдущее значение
	static bool SaveTifGrayfAsMonochrome(bool b);

	// Сохнанение HBITMAP в файл. Формат файла определяется по расширению файла
	static bool SaveBitmapAs(HBITMAP hBM, LPCTSTR FileName, int DPI = -1, BOOL bColor = TRUE, DWORD CompressionMode=0);
	
	// объединяет файлы из strs в один многостраничный sFileName. файлы из strs удаляет
	static bool UnificationTIFF(CStringArray *strs, CString sFileName);

	const char*	GetLastError();

	// Для копирования в другой CaplImage
	void GetBuf(BYTE *&pBuf, int &iBufSize){pBuf=m_file_buf; iBufSize=m_file_buf_size; };

protected:
	CxImage	*m_pImage;

	BYTE *m_file_buf;  // буффер для запоминания многостраничных документов
	int  m_file_buf_size;

	static bool st_bSaveGrayTiffAsMonochrome; // Сохранять тиф-ы в градациях серого как монохромный (1 bit/pixel)
};

//  Сжатие или распаковка данных во внутренний буффер
class APL_CLASS_EXPORT CaplZip
{
public:	
	CaplZip();
	virtual ~CaplZip(){Clear();};

	static bool IsBufferAplZip(BYTE *buf, UINT buf_len); // Лежит ли в буффере архив

	bool Compress(BYTE *buf, UINT buf_len, int level=9); // level: 0- без сжатия, 9 - максимальное сжатие
	bool Decompress(BYTE *buf, UINT buf_len);

	bool CompressFile(LPCTSTR fname, int level=9); // Сжать файл сам в себя
	bool DecompressFile(LPCTSTR fname); // Распаковать файл сам в себя. Если файл не zip, то он не изменится

	BYTE *GetData();
	UINT GetDataLen(){return m_data_len;};

	void Clear();

	LPCTSTR GetLastError();

protected:
	BYTE *m_buf;
	UINT m_buf_len; // размер буфера
	UINT m_data_len; // размер данных в буфереж

	UINT m_last_error;
};

