#pragma once

#ifdef APL_PDF_IMPL
#define CLASS_DECL_APL_PDF  _declspec(dllexport)
#else
#define CLASS_DECL_APL_PDF  _declspec(dllimport)
#ifdef _DEBUG
#ifdef UNICODE
#pragma comment (lib,"aplPdf_ud.lib")
#else
#pragma comment (lib,"aplPdfD.lib")
#endif
#else
#ifdef UNICODE
#pragma comment (lib,"aplPdf_u.lib")
#else
#pragma comment (lib,"aplPdf.lib")
#endif
#endif
#endif

class CaplPdfPage;

typedef void* p_fz_context;
typedef void* p_fz_document;
typedef void* p_fz_page;
//typedef void* p_fz_pixmap;


class CLASS_DECL_APL_PDF CaplPdf
{
public:
	CaplPdf();
	virtual ~CaplPdf();

	bool OpenFile(LPCTSTR fname); // Открыть файл
	// Открыть файл из памяти 
	// !!! память не освобожать до тех пор, пока используется CaplPdf
	// file_ext - расширение файла ("pdf", "tiff" и т.д.)
	// Если bCreateCopyMemory==true - Создается своя копия данных в памяти (после вызова память можно освобождать)
    // иначе - память нужно беречь все время , пока используется CaplPdf, а потом освободить
	bool OpenFileFromMemory(unsigned char *mem, ULONG memsize, LPCTSTR file_ext, bool bCreateCopyMemory=true); 
	bool CloseFile();
	
	CaplPdfPage  *LoadPage(int num_page, bool bTemp=false);  // загрузить в память страницу  bTemp = не запоминать (временная для печати)

	int GetPageCount(){return m_PagesCount;};
	int GetCurPage(){return m_CurPage;};

	CaplPdfPage *GetActualPage(){return m_page;};

	p_fz_context GetCtx();
	p_fz_document GetFzDoc();

protected:
	p_fz_context m_ctx;
	p_fz_document m_fz_doc;

	int m_PagesCount;
	int m_CurPage;
	CaplPdfPage  *m_page;

	unsigned char *m_file_buf; 
};

 class CLASS_DECL_APL_PDF CaplPdfPage
{
public:
	//CaplPdfPage(); 
	CaplPdfPage(CaplPdf *doc, p_fz_page page, int pagenum);
	virtual ~CaplPdfPage(void);
	
	int GetPageNum(){return m_PageNum;};
	bool GetOriginalSize(float &cx, float &cy); // Возвращает размер страницы в уе (72dpi)
	bool GetOriginalSizeIn_mm(float &cx, float &cy); // Возвращает размер страницы в мм

	// Готовит в памяти битовую матрицу шириной сх пикселей ; 
	// dc - совместимый с тем, в который будет отрисовываться
	// rotate - угол в градусах на который повернуть по час. срелке
	// при больших сх (зависит от pdf, примерно сх>4743) не рисует через BitBlt. 
	// (Из Pixmap рисует.) Возможно, это ограничение mfc или экрана. (4743 на 30 см - это 395 dpi)
	// sSignsInField - строка выводимая в правлм нижнем углу
	// sInfoInField - строка выводимая в левом верхнем углу углу
	bool Make2Cx(CDC *dc, int cx, int rotation=0, LPCTSTR sSignsInField=0, LPCTSTR sInfoInField=0, LPCTSTR sBarCodeInFied=0, LPCTSTR sOrderNum=0 ); 

	// Рисует текст в прямоугольнике (вызывается внутри Make2Cx) ; 
	// x0,x1 - в мм, если >0, то от левого края, если <0. то от правого	
	// y0,y1 - в мм, если >0, то от верхнего края, если <0. то от нижнего	
	// bDrawAsBarCode - если true, то рисует не буквы, а штрихкод
	bool DrawTextInRect(CDC &dc, float x0, float y0, float x1, float y1, int rotation, LPCTSTR sText, bool bDrawAsBarCode=false); 


	// Отрисовка
	//x0,y0 - угол изображения, x1, y1 - угол в окне
	// dc4draw - если не 0, то рисует не свое, а это. Используется для отрисовки результатов сравнения
	bool Draw(CDC *dc, int x0, int y0, int cx, int cy, int x1, int y1, CDC *dc4draw=0); 

	bool GetCurImageSize(int &cx, int &cy); // Возвращает размер свформированного в память ихображения (сх - последний вызов Make2Cx)

	bool ConvertPointFromOrigUnit(float  x0, float y0, int &x1, int &y1);  // преобразует коодинаты из 72dpi в пикселы
	bool ConvertPointToOrigUnit(int  x0, int y0, float &x1, float &y1);  // преобразует коодинаты из пикселов в 72dpi

	void FreeBitmap(); // Освобождает bitmap из памяти

	bool GetFormat(CString &format); // Возвращает название формата

	// Возвращает информацию о текущей картинке. 
	// Пока работает только для tiff
	bool GetImageInfo(int &cx, int &cy, int &xres, int &yres, CString &color_scheme, CString &img_coding);

	CBitmap *GetCurBitmap(){return &m_bitmap;} // Для служебных целей

protected:
	CaplPdf *m_doc;
	int m_PageNum;
	BITMAPINFO m_dibinf;
	CDC m_comp_dc;
	CBitmap m_bitmap;

	int m_img_compression;  // Параметры ихображенияя. Заполняются только для TIFF
	int m_img_bitspersample;
	int m_img_samplesperpixel;

	p_fz_context m_ctx; // берется из CaplPdf
	p_fz_document m_fz_doc; // берется из CaplPdf
	p_fz_page m_fz_page;
	//p_fz_pixmap m_pix; Переделано на хранание в CDC
	
	float m_original_cx; // Оригинальная ширина в 72 dpi
	float m_original_cy; // Оригинальная высота в 72 dpi

	int m_cx; // Размер подготовленной матрицы в пикселах (как думают снаружи. на самом деле ширина bmp m_cx/m_strech_k
	int m_cy; // Размер подготовленной матрицы в пикселах

	int m_cur_angle; // текущий угол поворота в градусах

	int m_strech_k; // Во сколько раз матрица в памяти меньше выводимой (если bitmap не влазит в память)
};

// Рисует штрих-код  
// dc - куда рисовать
// rect - Прямоугольник для отрисовки
// rotation - Угол в градусах (кратно 90) по часосой стрелке
// sText - Текст для отображения
// Возвращает true, если отрисовать удалось, и false, если не удалось

bool CLASS_DECL_APL_PDF DrawBarCode(CDC &dc, RECT &rect, int rotation, LPCTSTR sText);
