//---------------------------------------------------------------------------
#ifndef PrinterOPOSH
#define PrinterOPOSH
//---------------------------------------------------------------------------
//#include <vcl.h>
//#include "OposFiscalPrinter_1_7_Lib_OCX.h"
#import "file:O:\MyDocuments\projects\Workspace_C++Builder\PayTerminal_XE\dist\OPOSFiscalPrinter.ocx"
#include "../FP300KZ/FP300KZ.h"
#include "structs.h"
#include <list>
//---------------------------------------------------------------------------
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:
		std::wstring name1; //Название товара 1 строка
		std::wstring name2; //Название товара 2 строка
		double price; //Цена за еденицу
		long count; //Количество
		long VatInfo; //Номер налоговой ставки из справочника
		Goods(std::wstring name1, std::wstring 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;
		TSimpleList<Goods*>* FListGoods;
		long CheckId; //Сколько распечатали чеков на данном терминале
	public:
		std::wstring HeadLine; //Первая строка в чеке "Оплата за услуги водоснабжения"
		std::wstring GoodsName; //Название товара
		std::wstring CasireName; //Имя кассира
		bool TestMode;
		bool AutoOpenShift; //Авто открытие смены
		std::string m_LogFilePath;

		FiscalPrinter(){ FListGoods= new TSimpleList<Goods*>(); CheckId=0; LoadSetup(); };
		virtual std::string getPrinterName()=0;
		virtual bool Start()=0;
		virtual bool isOk()=0;
		virtual long getCheckId(){ return CheckId; }; //Номер последнего отпечатоного документа
		void ClearGoods()
		{
			try
			{
				while(FListGoods->count()>0)
				{
					Goods* g=FListGoods->get(0);
					delete g;
					FListGoods->del((unsigned int)0);
				}
				FListGoods->clear();
			}catch(...)
			{
				Crashed=true;
			}
		};
		int getGoodsPrice();
		virtual bool PrintLine(std::wstring 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, std::wstring headLine ) { return false; };
		bool deleteCheck(int CheckId);
		virtual std::wstring getLastError(){ return L""; };
		virtual bool DayOpened(){ return false; };
		virtual void setHeader(TSimpleList2<std::wstring>* Text){};
		virtual void getHeader(TSimpleList2<std::wstring>* Text){};
		virtual void setTrailer(TSimpleList2<std::wstring>* Text){};
		virtual void getTrailer(TSimpleList2<std::wstring>* Text){};
		virtual bool OpenShift(){ return true; }; //Открытие смены

		int getCOMPort();
		int getBaudRate();
		virtual bool setBaudRate(std::wstring data) = 0;
		virtual bool setCOMPort(std::wstring data) = 0;
		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; };
		virtual int PrintDiagnostic() = 0; //Печать диагностической информации
		virtual int FeedPaper(int cnt) = 0;
		virtual int Beep() = 0;
};
//---------------------------------------------------------------------------
//Обвёртка для OPOS фискального принтера
class PrinterOPOS : public FiscalPrinter
{
	private:
		//TOPOSFiscalPrinter *fp;
		OposFiscalPrinter_1_7_Lib::IOPOSFiscalPrinterPtr fp;
	public:
		std::string m_LogFilePath; ///<Куда сохранять лог файл
		std::wstring m_LogFileWPath; ///<Куда сохранять лог файл

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

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

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

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

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


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

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

		void Push(){}; //В OPOS драйвере нет такой функции
		int PrintDiagnostic() { return 0; };
		int FeedPaper(int cnt)
		{
			return 0;
		};
		int Beep()
		{
			return 0;
		};
};
//---------------------------------------------------------------------------
class FiscalPrinterPort : public FiscalPrinter
{
	private:
		FP300KZ* fp;
	public:
		FiscalPrinterPort():FiscalPrinter()
		{	fp = new FP300KZ();
		};
		virtual ~FiscalPrinterPort(){ delete fp; };
		std::string getPrinterName(){ return "Port";};
		bool getNextCheckId(int &res)
		{
			int num;
			bool b=fp->GetLastPrintedDocNumber(num).ErrorCode==0;
			res=num+1;
			if (!b)
			{
				std::wstring estr = getLastError();
				throw std::runtime_error(Utility::WStringToString(estr, std::locale("")));
			}
			return b;
		};

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

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

		bool isOk();
		bool PrintLine(std::wstring line)
		{
			//if(line!=NULL)
				return fp->PrintLine(line).ErrorCode==0;
			//else
			//	return fp->PrintLine(L"");
		};
		std::wstring getLastError()
		{
			std::string str = fp->getLastErrorDest();
			std::wstring result = Utility::StringToWString(str, std::locale(""));
			return result;
		};
		bool DayOpened(){ return true; };
		bool PrintZReport();
		void PrintXReport() { fp->PrintXReport(); };
		bool Cut(){ return fp->CutPaper().ErrorCode==0; };
		int PrintDiagnostic() { return fp->PrintDiagnostic().ErrorCode==0; };
		bool setBaudRate(std::wstring data)
		{
			//fp->cPort->BaudRate = StdWStrToInt(data);
			return false;
		};
		bool setCOMPort(std::wstring data)
		{
			//fp->cPort->ComNumber = StdWStrToInt(data);
			return false;
		};
		int FeedPaper(int cnt)
		{
			return fp->FeedPaper(cnt).ErrorCode==0;
		};
		int Beep()
		{
			MyError err = fp->Beep();
			return err.ErrorCode;
		};

};
//---------------------------------------------------------------------------
//extern FiscalPrinter* g_printer;
//---------------------------------------------------------------------------
#endif
