//---------------------------------------------------------------------------
#ifndef PrinterOPOSH
#define PrinterOPOSH
//---------------------------------------------------------------------------
//#include "OposFiscalPrinter_1_7_Lib_OCX.h"
#include "OposFiscalPrinter_CCO_TLB.h"
#include "FP300KZ.h"
//---------------------------------------------------------------------------
const LONG FPTR_RT_CASH_IN = 1;
const LONG FPTR_RT_CASH_OUT = 2;
const LONG FPTR_RT_GENERIC = 3;
const LONG FPTR_RT_SALES = 4;
const LONG FPTR_RT_SERVICE = 5;
const LONG FPTR_RT_SIMPLE_INVOICE = 6;
//---------------------------------------------------------------------------
//Продаваемый товар
class Goods
{
	private:
	public:
		WideString name1; //Название товара 1 строка
		WideString name2; //Название товара 2 строка
		double price; //Цена за еденицу
		long count; //Количество
		long VatInfo; //Номер налоговой ставки из справочника
		Goods(WideString name1, WideString name2, double price, long count,long VatInfo)
		{	//if(name1==NULL)
			//	this->name1=L"";
			//else
				this->name1=name1;
			//if(name2==NULL)
			//	this->name2=L"";
			//else
				this->name2=name2;
			this->price=price;
			this->count=count;
			this->VatInfo=VatInfo;
		};
};
//---------------------------------------------------------------------------
class FiscalPrinter
{
	protected:
		bool Crashed;
		long FState;
		TList* FListGoods;
		long CheckId; //Сколько распечатали чеков на данном терминале
	public:
		AnsiString HeadLine; //Первая строка в чеке "Оплата за услуги водоснабжения"
		WideString GoodsName; //Название товара
		WideString CasireName; //Имя кассира
		bool TestMode;
		bool AutoOpenShift; //Авто открытие смены

		FiscalPrinter(){ FListGoods= new TList(); CheckId=0; LoadSetup(); };
		virtual AnsiString getPrinterName()=0;
		virtual bool Start()=0;
		virtual bool isOk()=0;
		virtual long getCheckId(){ return CheckId; }; //Номер последнего отпечатоного документа
		void ClearGoods()
		{
			try
			{
				while(FListGoods->Count>0)
				{
					Goods* g=(Goods*)FListGoods->Items[0];
					delete g;
					FListGoods->Delete(0);
				}
				FListGoods->Clear();
			}catch(...)
			{
				Crashed=true;
			}
		};
		int getGoodsPrice();
		virtual bool PrintLine(WideString line)=0;
		void addGoods(Goods* goods)
		{
			FListGoods->Add(goods);
		};
		virtual bool getNextCheckId(int &id);

		bool SaveCheck(int CheckId);
		virtual bool PrintCheck(bool sales, int check, WideString headLine ) { return false; };
		bool deleteCheck(int CheckId);
		virtual AnsiString getLastError(){ return ""; };
		virtual bool DayOpened(){ return false; };
		virtual void setHeader(TStrings* Text){};
		virtual void getHeader(TStrings* Text){};
		virtual void setTrailer(TStrings* Text){};
		virtual void getTrailer(TStrings* Text){};
                virtual bool OpenShift(){ return true; }; //Открытие смены

                int getCOMPort();
                int getBaudRate();
                void setBaudRate(int val);
                void setCOMPort(int n);
                virtual bool PrintZReport()=0;
                virtual void PrintXReport()=0;

                void LoadSetup();
		void SaveSetup();
                virtual bool setTrainingMode(bool val){ return false; };
                virtual bool Cut(){ return false; }; //Отрезать бумагу
                virtual bool setNalog(long n,float stavka){ return false; }; //Заполнение массива с суммами по налоговым ставкам
                virtual int getAllSum(){ return 0; };
};
//---------------------------------------------------------------------------
//Обвёртка для OPOS фискального принтера
class PrinterOPOS : public FiscalPrinter
{
	private:
		TOPOSFiscalPrinter *fp;
	public:


		bool setTrainingMode(bool val);
		bool getTrainingMode();

		PrinterOPOS(TComponent* AOwner);
		virtual ~PrinterOPOS();
		AnsiString getPrinterName(){ return "Moebius";};
		bool Start(); //Соедениться по COM порту и проинициализировать принтер
		bool PrintCheck(bool sales, int check, WideString headLine ); //Печать чека

		bool SaveCheck(int CheckId); //Сохранение чека для последующей распечатки
		bool deleteCheck(int CheckId); //Удаление чека из базы

		bool Cut(); //Отрезать бумагу
		//int GetState(); //0 - Нет ошибок готов к печати чека
		bool isOk(); //Проверка работоспособности принтера
		AnsiString GetStatusDescription(long StatusCode); //Описание статуса
		AnsiString getLastError(long* err); //Получить код последней ошибки
		AnsiString getLastError(); //Получить код последней ошибки
		TDateTime getDateOpenShift(); //Получить дату открытия смены

		void setHeader(TStrings* Text);
		void getHeader(TStrings* Text);
		void setTrailer(TStrings* Text);
		void getTrailer(TStrings* Text);
		int getCOMPort();
		void setCOMPort(int n);
		int getDaySum(); //Сумма в касса с прошлого Z отчёта
		int getAllSum(); //Общий итог продаж


		bool PrintLine(WideString line);
		bool PrintZReport(); //Печать отчёта и закрытие смены
		void PrintXReport(); //Печать суточного отчёта без закрытия смены
		bool OpenShift(); //Открытие смены
		bool DayOpened(); //Отрыта ли смена

		bool setNalog(long n,float stavka); //Заполнение массива с суммами по налоговым ставкам

		void Push(){}; //В OPOS драйвере нет такой функции
};
//---------------------------------------------------------------------------
class FiscalPrinterPort : public FiscalPrinter
{
	private:
		FP300KZ* fp;
	public:
		FiscalPrinterPort():FiscalPrinter()
		{ fp = new FP300KZ();
		};
		virtual ~FiscalPrinterPort(){ delete fp; };
		AnsiString getPrinterName(){ return "Port";};
		bool getNextCheckId(int &res)
		{
			int num;
			bool b=fp->GetLastPrintedDocNumber(num);
			res=num+1;
			if(!b)throw Exception(getLastError());
			return b;
		};

		bool Start()
		{
			fp->OpenCOMPort(getCOMPort(),getBaudRate());
			return fp->PrinterInit();
		};
		long getCheckId(){ int num; fp->GetLastPrintedDocNumber(num); return num; }; //Номер последнего отпечатоного документа

		bool PrintCheck(bool sales, int check, WideString headLine ); //Печать чека

		bool isOk();
		bool PrintLine(WideString line)
		{
			//if(line!=NULL)
				return fp->PrintLine(line.c_bstr());
			//else
			//	return fp->PrintLine(L"");
		};
		AnsiString getLastError()
		{
			return fp->getLastErrorDest().c_str();
		};
		bool DayOpened(){ return true; };
		bool PrintZReport();
		void PrintXReport() { fp->PrintXReport(); };
		bool Cut(){ return fp->CutPaper(); };
};
//---------------------------------------------------------------------------
extern FiscalPrinter* g_printer;
//---------------------------------------------------------------------------
#endif
