//---------------------------------------------------------------------------
#ifndef PrinterH
#define PrinterH
//---------------------------------------------------------------------------
#include "../Printer.h"
#include "../../ComPort.h"
#include <stdTools.h>
#include <string>
//---------------------------------------------------------------------------
#define fcDisplayClear 0x21 //(33)Очистка дисплея
#define fcDispalyLower 0x23 //(35)Вывод текста в нижнюю строку дисплея
#define fcOpenServiceInv 0x26 //(38)Открытие нефискального чека
#define fcCloseServiceInv 0x27 //(39)Закрытие нефискального чека
#define fcSwitchPrg 0x29 //(41)Программирование конфигурационных ключей
#define fcPrintFreeTextInServiceInv 0x2A //(42)Печать свободного текста в нефискальном чеке
#define fcPrintSetup 0x2B //(43)Установка HEADER и FOOTER и опций печати
#define fcFeedPaper 0x2C //(44)Протяжка ленты
#define fcCutPaper 0x2D //(45)Обрезка ленты
#define fcDispalyUpper 0x2F //(47)Вывод текста в верхнюю строку дисплея
#define fcOpenFiscalInv 0x30 //(48)Открытие фискального (клиентского) чека
#define fcRegisterSale 0x31 //(49)Регистрация продажи
#define fcReportOnTaxRates 0x32 //(50)Отчет по налоговым ставкам и положению десятичной точки за период
#define fcSubtotal 0x33 //(51)Подитог
#define fcRegisterSaleDisp 0x34 //(52)Регистрация продажи с выводом на дисплей
#define fcTotal 0x35 //(53)Оплата (итог)
#define fcPrintFreeTextInFiscalInv 0x36 //(54)Печать свободного текста в фискальном чеке
#define fcCloseFiscalInv 0x38 //(56)Закрытие фискального чека
#define fcRegisterArticleSale 0x3A //(58)Регистрация продажи запрограммированного артикула
#define fcCancelFiscalInv 0x3C //(60)Аннуляция (сторно) фискального чека
#define fcSetDateTime 0x3D //(61)Установка даты и времени
#define fcGetDateTime 0x3E //(62)Чтение даты и времени
#define fcDisplayDateTime 0x3F //(63)Вывод даты и времени на дисплей
#define fcLatestFiscalRecord 0x40 //(64)Информация о последней фискальной записи
#define fcAmountOfSavingsPerDay 0x41 //(65)Информация о сумме накоплений за день
#define fcDepartmentReport 0x42 //(66)Отчет по секциям
#define fcFreeFieldsByFiscalMemory 0x44 //(68)Количество свободных полей в фискальной памяти
#define fcDailyFinancialReport 0x45 //(69)Дневной финансовый отчет
#define fcParishOrConsumption 0x46 //(70)Служебный приход или расход
#define fcPrintDiagnostic 0x47 //(71)Печать диагностической информации
#define fcFiscalization 0x48 //(72)Фискализация и пререгистрация
#define fcFullFiscalReportByNumber 0x49 //(73)Полный фискальный отчет за период заданный номерами смен
#define fcGetStatusFP 0x4A //(74)Получение статуса
#define fcFiscalTransactionsStatus  0x4C //(76)Статус фискальной транзакции
#define fcReduceFiscalReportByDate 0x4F //(79)Сокращенный фискальный отчет за период заданный датами
#define fcBeep 0x50 //(80)Звуковой сигнал
#define fcOpenBackInv 0x52 //(82)Открытие чека возврата
#define fcSetTaxRates 0x53 //(83)Установка положения десятичной точки и налоговых ставок
#define fcPrintBarCode 0x54 //(84)Печать штрих-кода
#define fcSetAddTypesOfPayment 0x55 //(85)Установка наименований дополнительных типов оплаты
#define fcDateOfLastEntryByFiscalMemory 0x56 //(86)Дата последней записи в фискальную память
#define fcSetDepartmentName 0x57 //(87)Программирование наименования секции
#define fcGetDepartmentInfo 0x58 //(88)Получение информации по секции
#define fcPrgProductionTestArea 0x59 //(89)Программирование производственной тестовой области
#define fcDiagnosticInfo 0x5A //(90)Диагностическая информация
#define fcGetTimeZReport 0x5D //Получение времени с начала открытия смены.
#define fcSetManufacturersSerialNumber 0x5B //(91)Программирование заводского номера принтера
#define fcFullFiscalReportByDate 0x5E //(94)Полный фискальный отчет за период заданный датами
#define fcReduceFiscalReportByNumber 0x5F //(95)Сокращенный фискальный отчет за период заданный номерами смен
#define fcGetTaxRates 0x61 //(97)Чтение запрограммированных налоговых ставок
#define fcSetRNNAndRNM 0x62 //(98)Установка РНН и РНМ
#define fcGetRNNAndRNM 0x63 //(99)Чтение РНН и РНМ
#define fcDispalyFree 0x64 //(100)Вывод на дисплей свободного текста
#define fcSetOperatorPassword 0x65 //(101)Установка пароля оператора
#define fcSetOperatorName 0x66 //(102)Установка наименования оператора
#define fcInfoByCurrentInv 0x67 //(103)Информация о текущем чеке
#define fcOperatorReport 0x69 //(105)Отчет по операторам
#define fcOpenCashDrawer 0x6A //(106)Открытие денежного ящика
#define fcPrgAndReadArticle 0x6B //(107)Программирование и чтение данных артикула
#define fcPrintDuplicateInv 0x6D //(109)Печать дубликата чека
#define fcDailyReportByTypesOfPayment 0x6E //(110)Дневной отчет по типам оплаты
#define fcReportByArticle 0x6F //(111)Отчет по артикулам
#define fcReportByOperators 0x70 //(112)Отчет по операторам
#define fcGetLastPrintedDocNumber 0x71 //(113)Получение номера последнего напечатанного документа
#define fcGetInfoOfFiscalRecords 0x72 //(114)Получение информации о фискальной записи или записях за период
#define fcPrgGraphicLogo 0x73 //(115)Программирование графического логотипа
#define fcReadFiscalMemoryBlock 0x74 //(116)Чтение блока фискальной памяти
#define fcPrintEJ 0x78 //(119) Печать данных из электронной контрольной лентой
#define fcEJ 0x78 //(120)Работа с электронной контрольной лентой
//#define fcPrintEJ 0x78 //(119) Печать данных из электронной контрольной лентой
#define fcReadROMBlock 0x79 //(121)Чтение блока из ПЗУ
#define fcServiceClearEJ 0x7E //(126)Сервисная очистка контрольной ленты
#define fcServiceClearRAM 0x7F //(127)Сервисное обнуление ОЗУ

//Свои коды ошибок
#define ERRIO 100001 //ERR_IO

//---------------------------------------------------------------------------
unsigned int MakeCRC(unsigned char* Buf, unsigned int BufStart,unsigned int BufLen);
//---------------------------------------------------------------------------
typedef char int1;
typedef unsigned char uint1;
typedef unsigned int uint4;
#if !defined( _BORLAND )
//	typedef unsigned short Word; // 0..65535
#endif
typedef unsigned char BYTE;
//---------------------------------------------------------------------------
//Сласс статусов для принтера
//Текущее состояние принтера закодировано в поле длиной 6 байт
class StatusFP300KZ
{
	private:
	protected:
	public:
		bool s[6][8];
		StatusFP300KZ();
		void SetStatus(uint1* status);
		std::string getStatus(); //Статусы в виде строки
};
//---------------------------------------------------------------------------
class FP300KZ : public CPrinter
{
	private:
		unsigned char FrameSeqNumber; ///<порядковый номер запроса
		unsigned char CommandName; ///<Номер последней выполненной команды.
		uint1 getNextSeq();
		bool Sw1,Sw2,Sw3,Sw4,Sw5,Sw6,Sw7,Sw8; //Заполняются при вызове DiagnosticInfo
		bool m_SaveLog; ///<Сохранять ли в лог файл
		ComPort* cPort;

		void SleepMs(int ms); //Задержка в миллисекундах
	protected:
		std::string m_ErrCode; ///<Функция фискализации
	public:
		std::string PrinterName; ///<Название принтера
		std::string PrinterVersion; ///<Версия программного обеспечения
		std::string PrinterNumber; ///<Заводской номер (серийник)
//		int PrinterDecimal; ///<Количество знаков после запятой (Заполняется после вызова GetTaxRates) смотри m_Dots
		//int iResultCode; ///<Код ошибки


		int CheckCount; ///<Сколько распечатали чеков
		std::string Password; ///<Пароль оператора временное хранилище
		
		StatusFP300KZ* Status;
		FP300KZ();
		virtual ~FP300KZ();

		MyError PrinterInit(); //Инициализация принтера взятие инфы о версии и разделителе дробной части.

		std::string getErrorDesc(int rc);
		std::string getLastErrorDest();
		int ResultCode(); //Код последней ошибки

		bool SendPMessage(uint8_t* msg, uint32_t msize, std::string& answer);
		bool CloseCOMPort();
		//bool OpenCOMPort(std::string ComNumber,int BaudRate); ///<Соедениться по COM порту
		bool OpenSerial(std::string ComNumber, int BaudRate); ///<Соедениться по COM порту
		bool Print(); ///<Тестовая печать
		void LoadSetup(); ///<Load COM port and speed
		void SaveSetup(); ///<Save COM port and speed
		//void Init(); ///<Очистить буфера

		int getComSpeed(); ///<Получить скорость порта из конфига
		bool setComSpeed(int Speed); ///<Сохранить скорость порта

		MyError CutPaper(); ///<Отрезать бумагу
		MyError GetStatusFP(); ///<Получение статуса принтера команда: 4A
		void NewLine(); ///<Курсор на новую строку
		//void Push(); ///<Прокрутить ???
		MyError FeedPaper(int cnt); ///<Протяжка ленты
		MyError OpenCashDrawer(int mSec = 0); ///<Открытие денежного ящика
		MyError SetDepartmentName(int dept,std::wstring line1,std::wstring line2); ///<Задать наименование департамента (Секции)
		MyError GetDepartmentInfo(int dept,int &RecSales,float &RecSum,int &TotSales,float &TotSum,std::wstring &Line1,std::wstring &Line2); ///<Получить информацию по секциям

		MyError DiagnosticInfo(); ///<Диагностическая информация
		MyError GetTimeZReport(int & time); ///<Получение времени с начала открытия смены.
		MyError SetManufacturersSerialNumber(std::string Serial);
		MyError GetLastPrintedDocNumber(int& num); ///<Получение номера последнего напечатанного документа

		//Чеки
		MyError CancelFiscalInv(); ///<Аннуляция (сторно) фискального чека
		MyError PrintDuplicateInv(); ///<Печать дубликата чека
		MyError OpenServiceInv(); ///<Открытие нефискального чека
		MyError CloseServiceInv(int& count); ///<Закрытие нефискального чека
		MyError OpenFiscalInv(int OpCode,std::string OpPwd,int TillNmb); ///<Открытие фискального (клиентского) чека
		MyError CloseFiscalInv(); ///<Закрытие фискального чека
		MyError OpenBackInv(int OpCode,std::string OpPwd,int TillNmb); ///<Открытие чека возврата

		MyError RegisterSale(std::wstring L1,std::wstring L2,int dep,std::string TaxCd,double Price,double Qwan, bool Abs, double Perc); ///<Регистрация продажи

		MyError RegisterSaleDisp(std::string L1,int dep,std::string TaxCd,std::string Price); ///<Регистрация продажи с выводом на дисплей
		MyError FiscalTransactionsStatus(bool& Open,int& Items,double& Amount,double& Tender); ///<Статус фискальной транзакции

		MyError PrintBarCode(int Type,std::string Data); ///<Печать штрих-кода

		//Опциии печати
//		std::string PrintSetup(std::string Item, std::string Text); ///<Установка HEADER и FOOTER и опций печати
		MyError PrintSetup(std::string Item, std::string Text, std::string& Answer); ///<Установка HEADER и FOOTER и опций печати
		MyError getPrintLogo(bool& Enable,int& Height); ///<Печатается ли графический логотип
		MyError setPrintLogo(bool Enable,int Height); ///<Печатается ли графический логотип

		MyError PrintFreeTextInServiceInv(std::string Text); ///<Печать свободного текста в нефискальном чеке 48 символов
		MyError PrintFreeTextInFiscalInv(std::string Text); ///<Печать свободного текста в фискальном чеке
		MyError Subtotal(std::string Print, std::string Display, bool Abs, double Perc,double& Sum); ///<Подитог
		MyError Total(std::string Line1,std::string Line2,std::string PaidMode,double Amount,double& Change); ///<Оплата (итог)
		MyError ParishOrConsumption(std::string Oper,std::string Password,double Amount,std::wstring strH,std::wstring strF,std::string& ExitCode,double& CashSum,double& ServIn,double& ServOut); ///<Служебный приход или расход
		MyError SetAddTypesOfPayment(char Option, std::wstring& Text); ///<Установка наименований дополнительных типов оплаты

		//Отчёты
		MyError DepartmentReport();
		MyError AmountOfSavingsPerDay(double& TaxA,double& TaxB,double& TaxC,double& TaxD,double& TaxE); ///<Информация о сумме накоплений за день
		MyError FullFiscalReportByDate(std::string Password,std::string Receipts,std::string Start,std::string End); ///<Полный фискальный отчет за период заданный датами
		MyError ReduceFiscalReportByDate(std::string Password,std::string Receipts,std::string Start,std::string End); ///<Сокращёный фискальный отчет за период заданный датами
		MyError FullFiscalReportByNumber(std::string Password,std::string Receipts,int Start,int End); ///<Полный фискальный отчет за период заданный номерами смен
		MyError ReduceFiscalReportByNumber(std::string Password,std::string Receipts,int Start,int End); ///<сокражённый фискальный отчет за период заданный номерами смен

		MyError DailyFinancialReport(uint1 Option); ///<Дневной финансовый отчет
		MyError OperatorReport(); ///<Отчет по операторам
		MyError PrintDiagnostic(); ///<Печать диагностической информации
		MyError DailyReportByTypesOfPayment(std::string& Cash,std::string& Credit,std::string& Debit,std::string& Cheque,std::string& Pay1,std::string& Pay2,std::string& Pay3,std::string& Pay4,std::string& Closure,std::string& Receipt); ///<Дневной отчет по типам оплаты
		MyError ReportByArticle(std::string Option); ///<Отчет по артикулам
		MyError ReportOnTaxRates(std::string Start,std::string End); ///<Отчет по налоговым ставкам и положению десятичной точки за период

		MyError GetRNNAndRNM(std::string &RNN,std::string &RNM); ///<Чтение РНН и РНМ
		MyError SetRNNAndRNM(std::string RNN,std::string RNM); ///<Установка РНН и РНМ
		MyError SetOperatorPassword(std::string OpCode,std::string OldPwd,std::string NewPwd); ///<Установка пароля оператора
		MyError SetOperatorName(std::string OpCode,std::string Pwd,std::string OpName); ///<Установка наименования оператора
		MyError SetDateTime(std::string date,std::string time); ///<Установка даты и времени
		MyError GetDateTime(unsigned short& De,unsigned short& Me,unsigned short& Ye,unsigned short& Ho,unsigned short& Mi,unsigned short& Se); ///<Поолучение даты и времени

		MyError SwitchPrg(bool update); ///<Программирование конфигурационных ключей
		bool getSmallEJ(bool& val); ///<Для сохранение сокращённой информации в ЭКЛ
		MyError setSmallEJ(bool val); ///<Для сохранение сокращённой информации в ЭКЛ
		bool getDisplayTransparent(bool& val); ///<Режим прозрачного дисплея
		MyError setDisplayTransparent(bool val); ///<Режим прозрачного дисплея
		bool getDisplayWin1251(bool& val); ///<Работа дисплея с кодовой таблицей Windows 1251
		MyError setDisplayWin1251(bool val); ///<Работа дисплея с кодовой таблицей Windows 1251

/*		bool getAutoCut(); ///<Автоматическая обрезка ленты
		bool setAutoCut(bool val); ///<Автоматическая обрезка ленты
*/
		MyError Beep(int Hz = 0, int mSec = 0); ///<Звуковой сигнал
		//Дисплей
		MyError DisplayClear(); ///<Очистка дисплея
		MyError DispalyLower(std::string Text); ///<Вывод текста в нижнюю строку дисплея
		MyError DispalyUpper(std::string Text); ///<Вывод текста в верхнюю строку дисплея
		MyError DispalyFree(std::string Text); ///<Вывод на дисплей свободного текста
		//Работа с электронной контрольной лентой
		MyError EJ(std::string Cmd); ///<Работа с электронной контрольной лентой
		MyError PrintEJ();

		MyError ServiceClearEJ(); ///< Сервисная очистка контрольной ленты
		MyError ServiceClearRAM(); ///< Сервисное обнуление ОЗУ

		MyError GetTaxRates(std::string &Decimals,std::string &Rounding,bool& bA,bool& bB,bool& bC,bool& bD, std::string &TaxA, std::string &TaxB, std::string &TaxC, std::string &TaxD); ///<Чтение запрограммированных налоговых ставок
		MyError SetTaxRates(int Decimal, std::string Rounding, std::string TaxA, std::string TaxB, std::string TaxC, std::string TaxD); ///<Установка положения десятичной точки и налоговых ставок

		//int GetState();
		std::string GetStatusDescription(BYTE StatusCode); ///<Описание статуса

		//Логотип
		MyError PrgGraphicLogo(int RowNum, std::string Data); ///<Программирование графического логотипа
		MyError getGraphicLogo(int RowNum, std::string &Data); ///<Программирование графического логотипа

		MyError Fiscalization(std::string Password,std::string Serial,std::string& ErrCode); ///<фискализация
		MyError reFiscalization(std::string OldPwd,std::string Password,std::string RNN,std::string RNM,std::string& ErrCode); ///<перерегистрация

		MyError LatestFiscalRecord(std::string& Clos,int& Rec, float& Total,float& VAT,std::string& Date); ///<Информация о последней фискальной записи
		MyError FreeFieldsByFiscalMemory(long& Logical); //<Количество логических мест для фискальных записей

		//**************************************************************
		//Методы для совместимости с CPrinter для  создания универсального драйвера
		bool isOk(){ 
			bool result = cPort->isOpen();
			return result; };
		bool CashInOut(bool test, double sum) //Приход + или расход -
		{
			float Amount=(float)sum; //10 цифр
			std::string ExitCode;
			double CashSum;
			double ServIn;
			double ServOut;
			return ParishOrConsumption("1",Password,Amount,L"",L"",ExitCode,CashSum,ServIn,ServOut).ErrorCode==0;
		};
		virtual bool GetCashSum(double& sum) //<Получить сумму наличности в кассе.
		{
			std::string ExitCode;
			double CashSum=0,ServIn=0,ServOut=0;
			bool b=ParishOrConsumption("1",Password,0.0,L"",L"",ExitCode,CashSum,ServIn,ServOut).ErrorCode==0;

			sum=CashSum;
			return b;
		};
		MyError PrintZReport(); ///<Печатать дневной отчёт с гашением
		MyError PrintXReport(); ///<Печатать дневной отчёт без гашения
		MyError PrintLine(std::wstring line); //Печатает строку текста (на служебном и на фискальном)
		int GetLineLength() {
			return 46; 
		}; //Получить ширину строки чека в символах.
};
//---------------------------------------------------------------------------
#endif
