/*
 * DP25.h
 *
 *  Created on: 11 сент. 2015 г.
 *      Author: Igor
 */

#ifndef DP25_H_
#define DP25_H_

#include "Printers/Printer.h"
#include "ComPort.h"
#include "SocketPort.h"

#define fcDisplayClear 0x21 //(33)Очистка дисплея
#define fcDisplayLower 0x23 //(35)Вывод текста в нижнюю строку дисплея
#define fcOpenServiceInv 0x26 //(38)Открытие нефискального чека
#define fcCloseServiceInv 0x27 //(39)Закрытие нефискального чека
#define fcPrintFreeTextInServiceInv 0x2A //(42)Печать свободного текста в нефискальном чеке
#define fcFeedPaper 0x2C //44 Протяжка ленты
#define fcCheckConnection 0x2D //Проверяет режим соединения с ПК  а раньше было: Обрезка ленты
#define fcCutPaper 0x2E //(46)Обрезка ленты
#define fcDisplayUpper 0x2F //(47)Вывод текста в верхнюю строку дисплея
#define fcOpenFiscalInv 0x30 //(48)Открытие фискального (клиентского) чека
#define fcRegisterSale 0x31 //(49)Регистрация продажи
#define fcReportOnTaxRates 0x32 //(50)Возвращает активные ставки НДС
#define fcSubtotal 0x33 //(51)Подитог
#define fcTotal 0x35 //(53)Оплата (итог)

#define fcPrintFreeTextInFiscalInv 0x36 //(54)Печать свободного текста в фискальном чеке

#define fcCloseFiscalInv 0x38 //(56)Закрытие фискального чека
#define fcSetFiscalInvParam 0x39 //(57) Write client GSM/E-mail for current fiscal receipt ИИН INN

#define fcRegisterArticleSale 0x3A //(58)Регистрация продажи запрограммированного артикула
#define fcCancelFiscalInv 0x3C //(60)Аннуляция (сторно) фискального чека
#define fcSetDateTime 0x3D //(61)Установка даты и времени
#define fcGetDateTime 0x3E //(62)Чтение даты и времени
#define fcShowDateTime 0x3F //(63) Show current date and time
#define fcLatestFiscalRecord 0x40 //(64)Информация о последней фискальной записи
#define fcAmountOfSavingsPerDay 0x41 //(65)Информация о сумме накоплений за день

#define fcTurnoversOfSavingsPerDay 0x42 //(66)Информация о сумме накоплений за день

#define fcFreeFieldsByFiscalMemory 0x44 //(68)Количество Z-отчетов оставшихся до заполнения ФП
#define fcDailyFinancialReport 0x45 //69 (45h) X и Z отчёты
#define fcParishOrConsumption 0x46 //(70)Служебный приход или расход
#define fcPrintDiagnostic 0x47 //(71)Печать диагностической информации

#define fcFiscalization 0x48 //(72)Фискализация и пререгистрация
#define fcGetStatusFP 0x4A //(74)Получение статуса
#define fcFiscalTransactionsStatus  0x4C //(76)Статус фискальной транзакции
#define fcBeep 0x50 //(80)Звуковой сигнал
#define fcSetTaxRates 0x53 //Программирование ставок НДС
#define fcPrintBarCode 0x54 //(84)Печать штрих-кода
#define fcDateOfLastEntryByFiscalMemory 0x56 //Дата последней фискальной записи
#define fcGetTradingGroupInfo 0x57 //Получение информации по группам товаров
#define fcGetDepInfoInCheck 0x58 //Получение информации по отделу в текущем чеке
#define fcTestOfFiscalMemory 0x59 //Test of Fiscal Memory
	
#define fcDiagnosticInfo 0x5A //(90)Диагностическая информация
#define fcSetManufacturersSerialNumber 0x5B //(91)Программирование заводского номера принтера
#define fcPrintDivideLine 0x5C //(92) Печать разделительной линии
#define fcFiscalReportByDate 0x5E //(94)Полный фискальный отчет за период заданный датами
#define fcFiscalReportByNumber 0x5F //Фискальный отчет по номерам Z-отчетов
	
#define fcSetSoftwarePassword 0x60 //Set Software Password
#define fcReadingError 0x64 //(100) Reading an error 
#define fcSetOperatorPassword 0x65 //(101)Установка пароля оператора
#define fcInfoByCurrentInv 0x67 //(103)Информация о текущем чеке
#define fcOperatorReport 0x69 //(105)Отчет по операторам
#define fcOpenCashDrawer 0x6A //(106)Открытие денежного ящика
#define fcPrgAndReadArticle 0x6B //(107)Программирование и считывание параметров товаров
#define fcGetPLUTurnoversByZReport 0x6C //(108) Get PLU turnovers by Z - report

#define fcDailyReportByTypesOfPayment 0x6E //(110)Дневной отчет по типам оплаты
#define fcReportByArticle 0x6F //(111)Отчет по артикулам
#define fcReportByOperators 0x70 //(112)Отчет по операторам
#define fcReadFiscalMemoryBlock 0x74 //(116)Чтение блока фискальной памяти

#define fcReadDeviceInfo 0x7B //(123) Информация об устройстве
#define fcGetDocInEJByDate 0x7C //(124) Поиск документа в ЭЖ по дате
#define fcGetInfoFromEJ 0x7D //(125) Информация из ЭЖ
#define fcPrintStamp 0x7F //(127) Stamp operations 

#define fnCheckUpdate 0xC8 //(200) проверить обновление TODO удалить при обновлении основной версии
#define fnUploadImage 0xCA //(202) Загрузить изображение
#define fnUploadStamp 0xCB //(203) Загрузить изображение для штампа

#define fnSetServiceParam 0xFD //(253) Установка сервисных параметров
#define fnProgramming 0xFF //(255) Программирование

//Свои коды ошибок
#define ERRIO 100001 //ERR_IO
#define ERRActivation 100050 //Ошибка изза не активации программы
#define ERRDiscounts 100051 //Ошибка если прентер не поддерживает скидки


class StatusDP25
{
	private:
	protected:
	public:
		bool stat[6][8];
		StatusDP25();
		void SetStatus(unsigned char* status);
		std::string getStatus(); //Статусы в виде строки
};

class DP25: public CPrinter
{
private:
	//unsigned char ReadAr[255]; ///<буфер для чтения ответа
	unsigned char FrameSeqNumber; ///<порядковый номер запроса
	unsigned char CommandName; ///<Номер последней выполненной команды.
	unsigned char getNextSeq();
	bool Sw1,Sw2,Sw3,Sw4,Sw5,Sw6,Sw7,Sw8; //Заполняются при вызове DiagnosticInfo
public:
	int m_activated1; //Устанавливается время от времени (2147443647 если то - активированно)
	//int m_activated2; //Устанавливается случайным образом по таймеру (2147443647 если то - активированно)

	std::string PrinterName; ///<Название принтера FPG-1000 или DP-25
	std::string PrinterVersion; ///<Версия программного обеспечения
	std::string PrinterNumber; ///<Заводской номер (серийник)
	std::string PrintColumns; //Сколько строк печатает принтер
	bool m_SaveLog; ///<Сохранять ли в лог файл
	std::string m_LogFilePath; ///<Куда сохранять лог файл
	int m_OpCode;
	std::string m_OpPwd;
	int m_TillNmb;
	//std::string ComNumber;
	//int BaudRate;
	int TimeOut;
	int CuttingPluName; //Как обрезать строки

	//ComPort* csPort;
	Port* csPort; //TCP or Serial
	StatusDP25* Status;

	DP25();
	virtual ~DP25();
	//MyError SendPMessage(unsigned char* msg,int size,std::string &answer);
	int SendPMessage(unsigned int cmd, unsigned char* msg, int size, std::string &answer);


	bool isOk(){ return true; };
	bool OpenSerial(std::string ComNumber, int BaudRate);
	//bool OpenCOMPort(std::string ComNumber,int BaudRate);
	bool CloseCOMPort();

	bool OpenSocket(std::string host, int port); //Отркыть соединение по сокету
	bool CloseSocket();

	MyError PrinterInit();
	bool CashInOut(bool test, double sum){ return true; };
	bool GetCashSum(double& sum){ return true; };

	MyError PrintZReport();
	MyError PrintXReport();
	MyError PrintLine(std::wstring line) { MyError err; err.ErrorCode = 0; return err; };
	int GetLineLength(); //Получить ширину строки чека в символах.

	MyError DisplayClear();

	MyError DisplayLower(std::string Text); ///<Вывод текста в нижнюю строку дисплея
	MyError OpenServiceInv(int& ShiftNumber, int& DocNumber); ///<Открытие нефискального чека
	MyError CloseServiceInv(int& ShiftNumber, int& DocNumber); ///<Закрытие нефискального чека
	MyError SetFiscalInvParam(int Type, std::string Data); ///<Write client GSM/E-mail for current fiscal receipt
	MyError PrintFreeTextInServiceInv(std::string Text,char Bold,char Italic,char Height,char Underline,char Alignment); ///<Печать свободного текста в нефискальном чеке 48 символов
	MyError FeedPaper(int count); ///<Протяжка ленты
	MyError CheckConnection(); ///<Проверяет режим соединения с ПК
	MyError CutPaper(); ///<Отрезать бумагу
	MyError DisplayUpper(std::string Text); ///<Вывод текста в верхнюю строку дисплея
	MyError OpenFiscalInv(int OpCode, std::string OpPwd, int TillNmb, char ReceiptType, int& ShiftNumber, int& SlipNumber, int& DocNumber); ///<Открытие фискального (клиентского) чека
	MyError RegisterSale(std::string PluName, char TaxCode,double Price,double Quantity,char DiscountType,double DiscountValue,int Department, std::string MarkStamp,double RoundPrice,int UnitCode, std::string ProductID, std::string BarCode, int& SlipNumber, int& DocNumber);
	MyError ReportOnTaxRates(int& NZreport,double& TaxA,double& TaxB,double& TaxC,std::string& EntryDate); ///<Отчет по налоговым ставкам и положению десятичной точки за период
	int ReadingError(int Code, int& ECode, std::string& ErrorMessage);
	MyError Subtotal(char Print,char Display,char DiscountType,double DiscountValue,int& SlipNumber,double& Subtotal,double& TaxA,double& TaxB,double& TaxC); ///<Подитог

	MyError PrintFreeTextInFiscalInv(std::string Text,char Bold,char Italic,char Height,char Underline,char Alignment);

	MyError Total(int PaidMode,double Amount,int& MyErrorStatus,double& NewAmount,int& SlipNumber); ///<Оплата (итог)
	MyError CloseFiscalInv(int& FiscalSignType, std::string& FiscalSign, int& ShiftNumber, int& SlipNumber, int& DocNumber); ///<Закрытие фискального чека
	MyError RegisterArticleSale(int PluCode, double Quantity, double Price, char DiscountType, double DiscountValue, std::string MarkStamp, int& SlipNumber, int& DocNumber); ///<Регистрация продажи запрограммированного товара
	MyError CancelFiscalInv(int& ShiftNumber, int& DocNumber); ///<Аннуляция (сторно) фискального чека
	MyError SetDateTime(std::string DateTime); ///<Установка даты и времени
	MyError GetDateTime(std::string &DateTime); ///<Поолучение даты и времени
	MyError ShowDateTime(std::string &DateTime); ///<Show current date and time
	MyError LatestFiscalRecord(char Type, int& nRep, double& SumA,double& SumB,double& SumC,std::string& Date); ///<Информация о последней фискальной записи
	MyError AmountOfSavingsPerDay(char Type, int& NRep, double& SumA,double& SumB,double& SumC); ///<Информация о налогах за текущий день
	MyError TurnoversOfSavingsPerDay(int& nRep, double& DailySales, double& DailyRetOfSales, double& DailyPurchases, double& DailyRetOfPurchases, double& NonNullSales, double& NonNullRetOfSales, double& NonNullPurchases, double&  NonNullRetOfPurchases);
	MyError FreeFieldsByFiscalMemory(int& ReportsLeft); //<Количество логических мест для фискальных записей
	MyError PrintReport(char Type, int& nRep, double& TotA, double& TotB, double& TotC, double& TotNegA, double& TotNegB, double& TotNegC, double& TotPuA, double& TotPuB, double& TotPuC, double& TotPuNegA, double& TotPuNegB, double& TotPuNegC); ////Печатать отчёт
	MyError ParishOrConsumption(char Type,double Amount,double& CashSum,double& CashIn,double& CashOut); ///<Служебный приход или расход
	MyError PrintDiagnostic(char InfoType); ///<Печать диагностической информации
	MyError PrintDiagnostic(); ///<Печать диагностической информации
	MyError EnablePrinting(bool val); ///< 0 - disable printout

	MyError Fiscalization(std::string SerialNumber,std::string TAXnumber1,std::string TAXnumber2,std::string InspPssword); ///Фискализация и пререгистрация
	MyError GetStatusFP(std::string& StatusBytes);
	MyError FiscalTransactionsStatus(char& IsOpen,int& Items,double& Amount,double& Payed,int& SlipNumber,int &SlipNumberFiscal); ///<Статус фискального чека
	MyError Beep(int Hz = 0, int mSec = 0); ///<Звуковой сигнал
	MyError SetTaxRates(double TaxA,double TaxB,double TaxC,int& RemainingChanges); ///<Программирование ставок НДС

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

	MyError DateOfLastEntryByFiscalMemory(std::string& DateTime); ///<Дата последней фискальной записи
	MyError GetTradingGroupInfo(int ItemGroup,int& TotSales,double& TotSum,std::string& Name); ///<Получение информации по группам товаров
	MyError GetDepInfoInCheck(int Department,char& TaxGr,double& Price,int& RecSales,double& RecQuanSales,double& RecSumSales,int& RecReturns, double& RecQuanReturns,double& RecSumReturns,int& TotSales,double& TotQuanSales,double& TotSumSales,int& TotReturns,double& TotQuanReturns,double& TotSumReturns,std::string& Name); ///<Получение информации по отделу в текущем чеке
	MyError TestOfFiscalMemory(bool Mode, int& Records);
	MyError DiagnosticInfo(std::string& Name,std::string& FwRev,std::string& FwDate,std::string& FwTime,std::string& Checksum,std::string& Sw,std::string& DevNumber); ///<Диагностическая информация

	MyError SetManufacturersSerialNumber(std::string Serial,std::string& Country);
	MyError PrintDivideLine(char Type); //Печать разделительной линии

	MyError FiscalReportByDate(char Type,std::string Start,std::string End,std::string InspPssword); ///<Полный фискальный отчет за период заданный датами
	MyError FiscalReportByNumber(char Type,int Start,int End,std::string InspPssword); //Фискальный отчет по номерам Z-отчетов
	MyError SetSoftwarePassword(std::string Pwd);

	MyError SetOperatorPassword(std::string OpCode,std::string OldPwd,std::string NewPwd); ///<Установка пароля оператора
	MyError InfoByCurrentInv(int& Type,double& SumVATA,double& SumVATB,double& SumVATC); ///<Информация о текущем чеке
	MyError OperatorReport(int FirstOper,int LastOper,char Clear); ///<Отчет по операторам
	MyError OpenCashDrawer(int MSec = 0); ///<Открытие денежного ящика

	MyError PrgAndReadArticleI(int& Total,int& Prog,int& NameLen); ///<Информация о товаре
	MyError PrgAndReadArticleP(int PLU,char TaxGr,int Dep,int Group,char PriceType,double Price,char AddQty,double Quantity,std::string Bar1,std::string Bar2,std::string Bar3,std::string Bar4,std::string Name,int UnitCode, int MarkType); ///<Программирование товара
	MyError PrgAndReadArticleA(int PLU,double Quantity); ///<Изменение доступного количества товара
	MyError PrgAndReadArticleD(int FirstPLU,int LastPLU); ///<Удаление товара
	MyError PrgAndReadArticleR(int PLU,char& TaxGr,int& Dep,int& Group,char& PriceType,double& Price,double& Turnover,double& SoldQty,double& StockQty,std::string& Bar1,std::string& Bar2,std::string& Bar3,std::string& Bar4,std::string& Name, int& UnitCode, int& MarkType); ///<Считывание данных товара
	MyError PrgAndReadArticleF(int& PLU,char& TaxGr,int& Dep,int& Group,char& PriceType,double& Price,double& Turnover,double& SoldQty,double& StockQty,std::string& Bar1,std::string& Bar2,std::string& Bar3,std::string& Bar4,std::string& Name, int& UnitCode, int& MarkType); ///<Возврат данных первого найденного запрограммированного товара
	MyError PrgAndReadArticleL(int PLU,char& TaxGr,int& Dep,int& Group,char& PriceType,double& Price,double& Turnover,double& SoldQty,double& StockQty,std::string& Bar1,std::string& Bar2,std::string& Bar3,std::string& Bar4,std::string& Name, int& UnitCode, int& MarkType); ///<Возврат данных последнего найденного запрограммированного товара
	MyError PrgAndReadArticleN(int& PLU,char& TaxGr,int& Dep,int& Group,char& PriceType,double& Price,double& Turnover,double& SoldQty,double& StockQty,std::string& Bar1,std::string& Bar2,std::string& Bar3,std::string& Bar4,std::string& Name, int& UnitCode, int& MarkType); ///<Возврат данных следующего найденного запрограммированного товара
	MyError PrgAndReadArticleFF(int PLU,char& TaxGr,int& Dep,int& Group,char& PriceType,double& Price,double& Turnover,double& SoldQty,double& StockQty,std::string& Bar1,std::string& Bar2,std::string& Bar3,std::string& Bar4,std::string& Name, int& UnitCode, int& MarkType); ///<Возврат данных первого найденного товара имеющего обороты продаж
	MyError PrgAndReadArticleLL(int PLU,char& TaxGr,int& Dep,int& Group,char& PriceType,double& Price,double& Turnover,double& SoldQty,double& StockQty,std::string& Bar1,std::string& Bar2,std::string& Bar3,std::string& Bar4,std::string& Name, int& UnitCode, int& MarkType); ///<Возврат данных последнего найденного товара имеющего обороты продаж
	MyError PrgAndReadArticleNN(int& PLU,char& TaxGr,int& Dep,int& Group,char& PriceType,double& Price,double& Turnover,double& SoldQty,double& StockQty,std::string& Bar1,std::string& Bar2,std::string& Bar3,std::string& Bar4,std::string& Name, int& UnitCode, int& MarkType); ///<Возврат данных следующего найденного товара имеющего обороты продаж
	MyError PrgAndReadArticleX(int PLU,int& FirstPLU); ///<Поиск первого незапрограммированного товара
	MyError PrgAndReadArticleXX(int PLU,int& LastPLU); ///<Поиск последнего незапрограммированного товара
	MyError GetPLUTurnoversByZReport(char Option,int Parameters,int& PLU,std::string& Name,double& SoldQty,double& Turnover); //Get PLU turnovers by Z-report

	MyError DailyReportByTypesOfPayment(char Type,double& Pay0,double& Pay1,double& Pay2,double& Pay3); ///<(110)Дневной отчет по типам оплаты
	MyError ReportByArticle(char Type,int FirstPLU,int LastPLU); //(111)Отчет по артикулам
	MyError ReportByOperators(int Operator,int& Receipts,double& Total,int& nDiscount,double& Discount,int& nSurcharge,double& Surcharge,int& nVoid,double& Void,int& nAllVoided,double& AllVoided,int& nCancelled,double& Cancelled,int& RetReceipts,double& RetTotal,int& RetnDiscount,double& RetDiscount,int& RetnSurcharge,double& RetSurcharge,int& RetnVoid,double& RetVoid,int& RetnAllVoided,double& RetAllVoided,int& RetnCancelled,double& RetCancelled,int& nCashIn,double& CashIn,int& nCashOut,double& CashOut); ///<Отчет по операторам
	MyError ReportByOperators0(long Operator,double& Pay0,double& Pay1,double& Pay2,double& Pay3); ///<Payments in sales receipts
	MyError ReportByOperators1(long Operator,double& Pay0,double& Pay1,double& Pay2,double& Pay3); ///<Payments in refund receipts
	MyError ReportByOperators2(long Operator,long& Num,double& Sum); ///<Number and sum of sells
	MyError ReportByOperators3(long Operator,long& Num,double& Sum); ///<Number and sum of refund
	MyError ReportByOperators4(long Operator,long& qSur,double& sSur,long& qDis,double& sDis); ///<Number and sum of discounts and surcharges from sales
	MyError ReportByOperators5(long Operator,long& qSur,double& sSur,long& qDis,double& sDis); ///<Number and sum of discounts and surcharges from refund
	MyError ReportByOperators6(long Operator,long& qVoid,double& sVoid,long& qAnul,double& sAnul,long& qCancel,double& sCancel); ///<Number and sum of corrections and annulled receipts from sales
	MyError ReportByOperators7(long Operator,long& qVoid,double& sVoid,long& qAnul,double& sAnul,long& qCancel,double& sCancel); ///<Number and sum of corrections and annulled receipts from refund
	MyError ReportByOperators8(long Operator,long& qCashIn,double& sCashIn,long& qCashOut,double& sCashOut); ///<Number and sum of cash in and cash out operations

	MyError GetSales(int Znumber);
	MyError GetSalesPLU(int PLU, char& TaxCode,int& Dep,int& Group, char& PriceType,double& Price,double& Turnover,double& SoldQty,double& StockQty, std::string& Bar1, std::string& Bar2, std::string& Bar3, std::string& Bar4, std::string& Name,int& UnitCode,int& MarkType);
	MyError GetSalesNextPLU(int& PLU, char& TaxCode, int& Dep, int& Group, char& PriceType, double& Price, double& Turnover, double& SoldQty, double& StockQty, std::string& Bar1, std::string& Bar2, std::string& Bar3, std::string& Bar4, std::string& Name, int& UnitCode, int& MarkType);

	MyError ReadFiscalMemoryBlock(int Address,int nBytes,std::string& Data); ///<Считывание ФП

	MyError ReadDeviceInfo1(std::string& SerialNumber, std::string& REGnumber, std::string&  TAXnumber, std::string& HeaderLine1, std::string& HeaderLine2, std::string& HeaderLine3, std::string& HeaderLine4); ///< Информация об устройстве
	MyError ReadDeviceInfo2(std::string& APN,std::string& APNUserName,std::string& APNPassword,std::string& ServerAddress,std::string& ServerPort, std::string&  ServerVersion); ///< Информация об устройстве
	MyError ReadDeviceInfo3(int& RecSales,std::string& DateSales,int& RecReturns,std::string& DateReturns,int& Znumber,std::string& Zdate); ///< Информация об устройстве

	MyError GetDocInEJByDate(std::string StartDate,std::string EndDate,char DocType,std::string& DateFirst,std::string& DateLast,int& NumFirst,int& NumLast);///< Поиск документа в ЭЖ по дате

	MyError GetInfoFromEJ0(int DocNum,char DocType,int& GlobalNum,int& DocNumber,int& RecNumber,std::string& Date,char& DocTypeRez,int& Znumber); ///< Информация из ЭЖ. Установка документа для чтения
	MyError GetInfoFromEJ1(std::string& TextData); ///< Информация из ЭЖ. Чтение одной строки текста. Для считывания всего документа необходимо выполнить команду несколько раз
	MyError GetInfoFromEJ2(std::string& Data); ///< Информация из ЭЖ. Чтение данных. Для считывания всего документа необходимо выполнить команду несколько раз
	MyError GetInfoFromEJ3(int DocNum,char DocType); ///< Информация из ЭЖ. Печать документа

	MyError SetServiceParam(std::string Type, std::string Value, std::string& IsUnblocked); ///< Установка сервисных параметров
	MyError Programming(std::string Name,std::string Index,std::string& Value); ///< Программирование

	MyError UploadImage(std::string Data,std::string& crc); //Загрузка фотографии в принтер
	MyError PowerOff();
	MyError Restart();
	MyError UploadStamp(std::string Data,std::string& crc); //Загрузить изображение для штампа

	MyError CheckUpdate();
	MyError PrintStamp(char Type,std::string Name);

};

#endif /* DP25_H_ */
