using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace GetEJDocuments_DevGr_C
{
    class StructuredInfoRegister_DeviceGroup_B
    {
        const int SZ_PLU_NAME = 22;
        const int MAX_PRINT_COLUMNS = 42;

        public StructuredInfoRegister_DeviceGroup_B.tagRClass Type;
        public byte[] DocData;

        public StructuredInfoRegister_DeviceGroup_B(byte[] data)
        {
            this.DocData = data;

            StructuredInfoRegister_DeviceGroup_B.tagRCMType type = StructuredInfoRegister_DeviceGroup_B.ByteArrayToStructure<StructuredInfoRegister_DeviceGroup_B.tagRCMType>(DocData);
            Type = type.type;
        }

        public tagRCMDsell CmdSell => ByteArrayToStructure<tagRCMDsell>(DocData);
        public tagRCMDopen CmdOpen => ByteArrayToStructure<tagRCMDopen>(DocData);
        public tagRCMDpay CmdPay => ByteArrayToStructure<tagRCMDpay>(DocData);
        public tagRCMDtotal CmdTotal => ByteArrayToStructure<tagRCMDtotal>(DocData);
        public tagRCMDrapo CmdRapo => ByteArrayToStructure<tagRCMDrapo>(DocData);
        public tagRCMDperc CmdPerc => ByteArrayToStructure<tagRCMDperc>(DocData);
        public tagRCMDallvoid CmdAllVoid => ByteArrayToStructure<tagRCMDallvoid>(DocData);
        public tagRCMDhdrftr CmdHeaderFooter => ByteArrayToStructure<tagRCMDhdrftr>(DocData);
        public tagRCMDtextline CmdTextLine => ByteArrayToStructure<tagRCMDtextline>(DocData);


        //------------------------------------------------------------------------------
        // КОМАНДИ ИЗПОЛЗВАНИ В РЕЖИМ РЕГИСТРИРАНЕ И ЗА ГЕНЕРИРАНЕ НА АРХИВА
        // маркираните с '*' не се записват в архива
        //------------------------------------------------------------------------------
        public enum tagRClass : byte
        {
            UNKNOWN = 0,         //*невалиден 
            PLUSELL = 1,         // продажба на артикул
            DPxSELL = 2,         // продажба на департамент
            PAYMENT = 3,         // плащане
            OTS_NDB = 4,         // отсъпка/надбавка
            RA_PO = 5,         // служебно въведени/изведени
            QTYSET = 6,         //*установяване на количество
            PRCSET = 7,         //*установяване на цена
            VD_PLUSELL = 8,         // войд на продажба на артикул
            VD_DPxSELL = 9,         // войд на продажба на департамент
            VD_OTS_NDB = 10,        // войд на отстъпка/надбавка
            ABONAT = 11,        // печат на номер на абонат
            BEGPAY = 12,        // начало на плащане (текста "Обща сума")
            BOTTLE = 13,        //*продажба/приемане на амбалаж
            VD_BOTTLE = 14,        //*войд на продажба/приемане на амбалаж
            COUPON = 15,        //*купони ( за гръцки модели )
            TICKET = 16,        //*билет( куверт ) ( за гръцки модели )
            //RETURN_PLUSELL = 17,        // замяна на артикул
            ALL_VOID = 18,        // анулиране на целия бон
            REPORTS = 19,        // всички отчети
            TEXT_LINE = 20,        // печат на текстов ред
            OPEN_BON = 21,        // отваряне на бон
            CLOSE_BON = 22,        // затваряне на бон
            HEADER_FOOTER = 23,        // заглавие и рекламни редове на касова бележка
            PINPAD_INFO = 24,        // печат на информация за бележката от пинпад
            INTERNAL = 254        // служебен запис в архива
        };

        public struct tagRCMType
        {
            public tagRClass type;           // 00       Тип на командата
        }

        public enum tagRSubClassPay : byte
        {
            PY_PY0 = 0,         // Плащане 'В БРОЙ'
            PY_PY1 = 1,         // Плащане #1
            PY_PY2 = 2,         // Плащане #2
            PY_PY3 = 3,         // Плащане #3
            PY_PY4 = 4,         // Плащане #4
            PY_PY5 = 5,         // Плащане #5
            PY_FOREIGN1 = 6,         // Плащане в алтернативна валута
            PY_TOTAL = 7,         // общо платена сума
            PY_STL = 14,        // междинна сума
            PY_STL_FOREIGN = 15,        // междинна сума в алтернативна валута
            PY_RESTO = 16,        // ресто в основна валута
            PY_RESTO_FOREIG = 17,        // ресто в алтернативна валута
            PY_ORDERS = 18,        // край на поръчка в ресторантска версия
        };

        public enum tagRSubClassRAPO : byte
        {
            RECD_ON = 0,         // служебно въведени суми в основна валута
            PAID_OUT = 1,         // служебно изведени суми в основна валута
            RECD_ON_FOREIGN = 2,         // служебно въведени суми в алтернативна валута
            PAID_OUT_FOREIGN = 3          // служебно изведени суми в алтернативна валута
        };

        public enum tagRSubClassPerc : byte
        {
            PERC_NONE = 0,         // няма оперция 'отстъпки/надбавки'
            PERC_SURCHARGE = 1,         // процентна надбавка
            PERC_DISCOUNT = 2,         // процентна отстъпка
            VAL_SURCHARGE = 3,         // стойностна надбавка
            VAL_DISCOUNT = 4,         // стойностна отсъпка
            PERC_UNKNOWN = 5,         // неизвестно, ползва се при войд операции за да се провери дали има "отс/надб"
            VAL_DISCOUNTplu = 6,         // специална стойностна отсъпкa над артикул
            VAL_DISCOUNTstl = 7          // специална стойностна отсъпкa над междинна сума
        };

        public enum tagRSubClassBottle : byte
        {
            BOTTLE_SELL = 0,         // касиера дава на амбалаж
            BOTTLE_TAKE = 1          // касиера приема на амбалаж
        };

        public enum tagRSubClassReports : byte
        {
            REPORT_DAILYZ = 0,         // дневен отчет с нулиране
            REPORT_DAILYX = 1,         // дневен отчет без нулиране
            REPORT_OPERZ = 2,         // отчет оператори с нулиране
            REPORT_OPERX = 3,         // отчет оператори без нулиране
            REPORT_PLUZ = 4,         // отчет продадени артикули с нулиране
            REPORT_PLUX = 5,         // отчет продадени артикули без нулиране
            REPORT_PLUPARAM = 6,         // отчет параметри на артикули
            REPORT_DEPART = 7,         // отчет департаменти
            REPORT_ITEMGRP = 8,         // отчет стокови групи
        };

        public enum tagOpenSubtype : byte
        {
            OPEN_SELL = 0,
            OPEN_INV = 1,
            OPEN_OTHER = 2,
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDbuffer
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)]
            byte[] bf;
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDtextline
        {
            public tagRClass type;         // 00       Тип на операцията 'TEXT_LINE'
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
            public byte[] filler0;          // 01       1 байта не се ползват
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_PRINT_COLUMNS)]
            public byte[] text; // 02-2B    до 42 байта текст
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 51)]
            public byte[] filler1;         // 2C-5E    51 байта не се ползват
            public byte checksum;            // 5F       контролна сума
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDopen
        {
            public tagRClass type;         // 00   Тип OPEN_BON
            public scDATE_TIME strDateTime;//      Дата и час на бона по който е сторното
            public byte nOperator;           //
            public Int32 nBon;               //      Номер на бон
            public Int32 flags;              //      Флагове
            public Int64 invN;               //      Номер на фактура
            public Int64 strToInvoice;       //      Номер на фактура към която е сторното (за случай на кредитно известие)
            public Int32 strNumberDoc;       //      Номер на бона по който е сторното
            public Int16 klenType;           //      Тип на бона (тип с който се записва в индекса на КЛЕН)
            public byte strType;             //      Тип на сторно операцията: 0 - операторска грешка, 1 - връщане/рекламация
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8 + 1)]
            public char[] strFMnumber; //      Номер на фискалната памет на бона по който е сторното
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
            public char[] nSale;        //      Уникален номер на продажба ако е от програма за продажбите CCCCCCCC-CCCC-DDDDDDD трябват 21+1, но оставяме 32
            public byte dp;                  //      Позиция на десетичната точка (да има т.к.ще потрябва).
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8 + 1)]
            public char[] deviceID;    //
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
            byte[] dummy;            //
            public byte checksum;            // 5F       контролна сума
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDsell
        {
            public tagRClass type;           // 00       Тип на командата  'SELL'            *** PLU/DEP ***  
            public byte cancel;         // 01       флаг за void операция               *** PLU/DEP ***  
            public byte fMyPluDB;       // 02       Артикул програмиран в нашата база   *** PLU ***
            public byte vat;            // 03       Дан.група          (vat)            *** PLU/DEP ***  
            public Int32 prc;            // 04-07    Единична цена      (price)          *** PLU/DEP ***  
            public Int64 suma;           // 08-0F    Сума = qty*prc                      *** PLU/DEP ***  
            public Int64 icode;          // 10-17    Номенклатурен код  (item code)      *** PLU ***
            public Int64 bcode;          // 18-1F    Бар код            (bar code)       *** PLU ***
            public Int32 qty;            // 20-23    Продадено кол-во   (sold qty)       *** PLU/DEP ***  
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = SZ_PLU_NAME)]
            public char[] name;    // 24-39    Име                (name)           *** PLU/DEP ***  
            public tagRSubClassPerc typeIncDec;     // 3A       тип на отс./над   "Търсене на VD"   *** PLU/DEP ***  
            public byte dep;            // 3B       Номер на щанд      (department)     *** PLU/DEP ***  
            public Int32 sIncDec;        // 3C-3F    процент или ст-ст "Търсене на VD"   *** PLU/DEP ***  
            public byte grp;            // 40       Номер на ст.група  (group)          *** PLU ***
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
            byte[] filler1;     // 41       1  байта не се ползват
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = SZ_PLU_NAME)]
            public char[] ext_name; // 42-58    разширител на името                 *** PLU ***
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
            byte[] filler2;     // 59-5Е    7  байта не се ползват
            public byte checksum;       // 5F       контролна сума
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDpay
        {
            public tagRClass type;           // 00       Тип на командата PAYMENT'        
            public tagRSubClassPay subtype;        // 01       Подтип на командата  
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public byte[] name_currency;// 02-07    имената на валутите (напр. "ЛВ EUR")
            public Int64 sInput;         // 08-0F    Въведена сума                    
            public Int64 sResto;         // 10-17    Рестото
            public Int64 sRestoForeign;  // 18-1F    Ресто в алтернативна валута
            public Int64 sPYN;           // 20-27    Сума подадена от клиента в алт.валута
            public Int64 sPYosnov;       // 28-2F    sPYN, но преизчислена в осн.валута
            public Int64 sTLneosn;       // 30-37    сумата на бона преизчислена според курса
            public Int32 sExchRate;      // 38-3B    курс на основна -> алт.валута
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
            public char[] pay_name;   // 3C-45    име на плащането
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]
            byte[] filler1;    // 46-5E    25 байта не се ползват
            public byte checksum;       // 5F       контролна сума
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDtotal
        {
            public tagRClass type;           // 00       Тип на командата BEGPAY'
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public byte[] name_currency;// 01-06    имената на валутите (напр. "ЛВ EUR")
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
            byte[] filler0;     // 07       1 байта не се ползват
            public Int64 sSTL;           // 08-0F    Обща сума
            //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public Int64 sVAT;        // 10-4F    Разпределение по данъчни групи
            public Int64 sVAT9;          // 50-57    8 байта не се ползват
            public Int32 sExchRate;      // 58-5B    курс на основна -> алт.валута
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
            byte[] filler1;     // 5C-5E    3 байта не се ползват
            public byte checksum;       // 5F       контролна сума
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDrapo
        {
            public tagRClass type;           // 00       Тип на командата RAPO            
            public tagRSubClassRAPO subtype;        // 01       Подтип на командата          
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public byte[] name_currency;// 02-07    имената на валутите (напр. "ЛВ EUR")
            public Int64 sInput;         // 08-0F    Въведена сума
            public Int32 sExchRate;      // 10-13    курс на основна -> алт.валута
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 75)]
            byte[] filler1;    // 14-5E    75 байта не се ползват
            public byte checksum;       // 5F       контролна сума
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDperc
        {
            public tagRClass type;           // 00       Тип на командата OTS_NDB         
            public tagRSubClassPerc subtype;        // 01       Подтип на командата
            public byte cancel;         // 02       флаг за void oоперация         
            public byte flagSTL;        // 03       Флаг за операция над STL,ako!=0
            public byte nVAT;           // 04       Показва към коя дан.гр.да се натрупа 
            public byte dep;            // 05       департамент
            public byte grp;            // 06       секция
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
            byte[] filler0;     // 07       1 байта не се ползват   
            public Int64 sSuma;          // 08-0F    Сума на транзакцията           
            public Int64 sSTL;           // 10-17    Обща сума по дан.групи преди %STL 
            //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public Int64 sVAT;        // 18-57    Разпределение по данъчни групи
                                      //          Сума по дан.групи преди %STL, 
                                      //          тези регистри ще ми трябват само ако 
                                      //          ще се прави отстъпка/надбавка над 
                                      //          междинна сума да не е последната транзакция
            public Int16 percIncDec;     // 58-59    Стойност на отстъпка/надбавка  
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
            byte[] filler1;     // 5А-5Е    5 байта не се ползват   
            public byte checksum;       // 5F       контролна сума
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDallvoid
        {
            public tagRClass type;           // 00       Тип на командата ALL_VOID
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
            byte[] filler0;     // 01-07    7 байта не се ползват
            public Int16 nCorrections;   //          Брой поцизии, които трябва да се отброят като корекции в дн. отчет
            public Int64 sTL;            // 08-0F    Обща сума на операциите
            //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public Int64 sVAT;        // 10-4F    Разпределение по данъчни групи
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)]
            byte[] filler1;    // 50-5Е    15 байта не се ползват
            public byte checksum;       // 5F       контролна сума
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDhdrftr
        {
            public tagRClass type;        // 00  Тип на командата HEADER_FOOTER
            public byte subtype;     // 01       Подтип 0=хедър; 1=футър;
            public Int16 nLine;       // 02-03    номер на ред
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
            public char[] text;    // 04-1B    текст за отпечатване
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 67)]
            byte[] filler1; // 1C-5E    67 байта не се ползват
            public byte checksum;    // 5F       контролна сума
        };

        //-------------------------------------------------------------------------------------------------------------
        //-------------------------------------------------------------------------------------------------------------
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct scDATE_TIME
        {
            public byte DD;
            public byte MM;
            public byte YY;
            public byte hh;
            public byte mm;
            public byte ss;
        };

        public static string DateToString(scDATE_TIME date)
        {
            return date.DD.ToString("D2") + "-" + date.MM.ToString("D2") + "-" + date.YY.ToString("D2") + " " + date.hh.ToString("D2") + ":" + date.mm.ToString("D2") + ":" + date.ss.ToString("D2");
        }

        //---------------------------------------------------------------------------------------------------------------
        //---------------------------------------------------------------------------------------------------------------


        public static T ByteArrayToStructure<T>(byte[] bytes) where T : struct
        {
            T stuff;
            GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
            try
            {
                stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
            }
            finally
            {
                handle.Free();
            }
            return stuff;
        }

        public static int Size<T>() where T : struct
        {
            T x = new T();
            return Marshal.SizeOf(x);
        }
    }

    class StructuredInfoRegister_DeviceGroup_C
    {
        const int SZ_PLU_NAME = 72;
        const int MAX_PRINT_COLUMNS = 64;

        public StructuredInfoRegister_DeviceGroup_C.tagRClass Type;
        public byte[] DocData;

        public StructuredInfoRegister_DeviceGroup_C(byte[] data)
        {
            this.DocData = data;

            StructuredInfoRegister_DeviceGroup_C.tagRCMType type = StructuredInfoRegister_DeviceGroup_C.ByteArrayToStructure<StructuredInfoRegister_DeviceGroup_C.tagRCMType>(DocData);
            Type = type.type;
        }

        public tagRCMDsell CmdSell => ByteArrayToStructure<tagRCMDsell>(DocData);
        public tagRCMDopen CmdOpen => ByteArrayToStructure<tagRCMDopen>(DocData);
        public tagRCMDClose CmdClose => ByteArrayToStructure<tagRCMDClose>(DocData);
        public tagRCMDpay CmdPay => ByteArrayToStructure<tagRCMDpay>(DocData);
        public tagRCMDtotal CmdTotal => ByteArrayToStructure<tagRCMDtotal>(DocData);
        public tagRCMDrapo CmdRapo => ByteArrayToStructure<tagRCMDrapo>(DocData);
        public tagRCMDperc CmdPerc => ByteArrayToStructure<tagRCMDperc>(DocData);
        public tagRCMDallvoid CmdAllVoid => ByteArrayToStructure<tagRCMDallvoid>(DocData);
        public tagRCMDtextline CmdTextLine => ByteArrayToStructure<tagRCMDtextline>(DocData);
        public tagRCMDInvoice CmdInvoice => ByteArrayToStructure<tagRCMDInvoice>(DocData);
        public tagRCMDAbonat CmdAbonat => ByteArrayToStructure<tagRCMDAbonat>(DocData);
        public tagRCMDAddInfo CmdAddInfo => ByteArrayToStructure<tagRCMDAddInfo>(DocData);
        public tagRCMDCargo CmdCargo => ByteArrayToStructure<tagRCMDCargo>(DocData);
        public tagRCMDBonus CmdBonus => ByteArrayToStructure<tagRCMDBonus>(DocData);
        public tagRCMDBarcodeLine CmdBarcodeLine => ByteArrayToStructure<tagRCMDBarcodeLine>(DocData);

        public enum tagRClass : byte
        {
            UNKNOWN = 0,         //*невалиден 
            PLUSELL = 1,         // продажба на артикул
            DPxSELL = 2,         // продажба на департамент
            PAYMENT = 3,         // плащане
            OTS_NDB = 4,         // отсъпка/надбавка
            RA_PO = 5,         // служебно въведени/изведени
            //QTYSET = 6,         //*установяване на количество
            //PRCSET = 7,         //*установяване на цена
            VD_PLUSELL = 8,         // войд на продажба на артикул
            VD_DPxSELL = 9,         // войд на продажба на департамент
            VD_OTS_NDB = 10,        // войд на отстъпка/надбавка
            ABONAT = 11,        // печат на номер на абонат
            BEGPAY = 12,        // начало на плащане (текста "Обща сума")
            //BOTTLE = 13,        //*продажба/приемане на амбалаж
            //VD_BOTTLE = 14,        //*войд на продажба/приемане на амбалаж
            //COUPON = 15,        //*купони ( за гръцки модели )
            //TICKET = 16,        //*билет( куверт ) ( за гръцки модели )
            //RETURN_PLUSELL = 17,        // замяна на артикул
            ALL_VOID = 18,        // анулиране на целия бон
                                  // REPORTS = 19,        // всички отчети
            TEXT_LINE = 20,        // печат на текстов ред
            PINPAD_INFO = 24,        // печат на информация за бележката от пинпад
            INVOICE = 27,            // информация за фактура
            OPEN_BON = 101,        // отваряне на бон
            CLOSE_BON = 102,        // затваряне на бон
            ADD_INFO = 103,         // допълнителна информация only in DP-05C
            CARGO = 104,            // карго only in DP-05C
            BONUS = 105, // бонус текстове при продажба
            BARCODE_LINE = 220        // баркод
        };

        public enum tagRSubClassPerc : byte
        {
            PERC_NONE = 0,         // няма оперция 'отстъпки/надбавки'
            PERC_SURCHARGE = 1,         // процентна надбавка
            PERC_DISCOUNT = 2,         // процентна отстъпка
            VAL_SURCHARGE = 3,         // стойностна надбавка
            VAL_DISCOUNT = 4,         // стойностна отсъпка
            PERC_UNKNOWN = 5,         // неизвестно, ползва се при войд операции за да се провери дали има "отс/надб"
            VAL_DISCOUNTplu = 6,         // специална стойностна отсъпкa над артикул
            VAL_DISCOUNTstl = 7,          // специална стойностна отсъпкa над междинна сума
            CARD_DISCOUNT = 8             // картова отстъпка
        };

        public enum tagRSubClassPay : byte
        {
            PY_PY0 = 0,         // Плащане 'В БРОЙ'
            PY_PY1 = 1,         // Плащане #1
            PY_PY2 = 2,         // Плащане #2
            PY_PY3 = 3,         // Плащане #3
            PY_PY4 = 4,         // Плащане #4
            PY_PY5 = 5,         // Плащане #5
            PY_FOREIGN1 = 6,         // Плащане в алтернативна валута
            PY_TOTAL = 7,         // общо платена сума
            PY_STL = 14,        // междинна сума
            PY_STL_FOREIGN = 15,        // междинна сума в алтернативна валута
            PY_RESTO = 16,        // ресто в основна валута
            PY_RESTO_FOREIG = 17,        // ресто в алтернативна валута
            PY_AMOUNT = 19,        // край на поръчка в ресторантска версия
            PY_AMOUNT_FOREIGN = 20,        // край на поръчка в ресторантска версия


        };

        public enum tagRSubClassRAPO : byte
        {
            RECD_ON = 0,         // служебно въведени суми в основна валута
            PAID_OUT = 1,         // служебно изведени суми в основна валута
            RECD_ON_FOREIGN = 2,         // служебно въведени суми в алтернативна валута
            PAID_OUT_FOREIGN = 3          // служебно изведени суми в алтернативна валута
        };

        public enum tagRSubClassOpen : byte
        {
            SELL = 0,       // продажба
            INVOICE = 1,        //фактура
            OTHER = 2           // други
        };

        public enum tagRSubClassBarcode : byte
        {
            LEFTSIDE = 0,
            RIGHTSIDE = 1
        };

        public struct tagRCMType
        {
            public tagRClass type;           // 00       Тип на командата
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDsell
        {
            public tagRClass type;           // 00       Тип на командата  'SELL'            *** PLU/DEP ***  
            public byte cancel;         // 01       флаг за void операция               *** PLU/DEP ***  
            public byte fMyPluDB;       // 02       Артикул програмиран в нашата база   *** PLU ***
            public byte vat;            // 03       Дан.група          (vat)            *** PLU/DEP ***  
            public Int32 prc;            // 04-07    Единична цена      (price)          *** PLU/DEP ***  
            public Int64 suma;           // 08-0F    Сума = qty*prc                      *** PLU/DEP ***  
            public Int64 icode;          // 10-17    Номенклатурен код  (item code)      *** PLU ***
            public Int64 bcode;          // 18-1F    Бар код            (bar code)       *** PLU ***
            public Int32 qty;            // 20-23    Продадено кол-во   (sold qty)       *** PLU/DEP ***  
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = SZ_PLU_NAME)]
            public char[] name;    // 24-39    Име                (name)           *** PLU/DEP ***  
            public tagRSubClassPerc typeIncDec;     // 3A       тип на отс./над   "Търсене на VD"   *** PLU/DEP ***  
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
            byte[] filler1;     // 41       3  байта не се ползват
            public Int32 sIncDec;        // 3C-3F    процент или ст-ст "Търсене на VD"   *** PLU/DEP ***  
            public byte dep;            // 3B       Номер на щанд      (department)     *** PLU/DEP ***  
            public byte grp;            // 40       Номер на ст.група  (group)          *** PLU ***
            public byte unit;       // 
            public byte fVDstorno; //
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDpay
        {
            public tagRClass type;           // 00       Тип на командата PAYMENT'        
            public tagRSubClassPay subtype;        // 01       Подтип на командата  
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public byte[] name_currency;// 02-07    имената на валутите (напр. "ЛВ EUR")
            public Int64 sInput;         // 08-0F    Въведена сума                    
            public Int64 sResto;         // 10-17    Рестото
            public Int64 sRestoForeign;  // 18-1F    Ресто в алтернативна валута
            public Int64 sPYN;           // 20-27    Сума подадена от клиента в алт.валута
            public Int64 sPYosnov;       // 28-2F    sPYN, но преизчислена в осн.валута
            public Int64 sTLneosn;       // 30-37    сумата на бона преизчислена според курса
            public Int64 sumRestoOsnovna;  //          Ресто, в основна, преизчислено спрямо курса
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public char[] reserved;// 02-07    
            public Int32 sExchRate;      // 38-3B    курс на основна -> алт.валута
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public char[] pay_name;   // 3C-45    име на плащането

        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDperc
        {
            public tagRClass type;           // 00       Тип на командата OTS_NDB         
            public tagRSubClassPerc subtype;        // 01       Подтип на командата
            public byte cancel;         // 02       флаг за void oоперация         
            public byte flagSTL;        // 03       Флаг за операция над STL,ako!=0
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public byte[] nVAT;           // 04       Показва към коя дан.гр.да се натрупа 
            public byte dep;            // 05       департамент
            public byte grp;            // 06       секция
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
            byte[] filler0;     // 07       1 байта не се ползват   
            public Int64 sSuma;          // 08-0F    Сума на транзакцията           
            public Int64 sSTL;           // 10-17    Обща сума по дан.групи преди %STL 
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public UInt64[] sBRUT;        // 18-57    Разпределение по данъчни групи
                                          //          Сума по дан.групи преди %STL, 
                                          //          тези регистри ще ми трябват само ако 
                                          //          ще се прави отстъпка/надбавка над 
                                          //          междинна сума да не е последната транзакция
            public Int16 percIncDec;     // 58-59    Стойност на отстъпка/надбавка   
            public byte fVDstorno;       // 5F       контролна сума
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDrapo
        {
            public tagRClass type;           // 00       Тип на командата RAPO            
            public tagRSubClassRAPO subtype;        // 01       Подтип на командата          
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public byte[] name_currency;// 02-07    имената на валутите (напр. "ЛВ EUR")
            public Int64 sInput;         // 08-0F    Въведена сума
            public Int32 sExchRate;      // 10-13    курс на основна -> алт.валута

        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDAbonat
        {
            public tagRClass type;           // 00       Тип на командата ABONAT   
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 15)]
            public char[] AbonatNomer;// 02-07    абонатен номер
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public char[] AbonatKarta;// 02-07    абонатна карта

        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDtotal
        {
            public tagRClass type;           // 00       Тип на командата BEGPAY'
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public byte[] name_currency;// 01-06    имената на валутите (напр. "ЛВ EUR")
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
            byte[] filler0;     // 07       1 байта не се ползват
            public Int64 sSTL;           // 08-0F    Обща сума
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public UInt64[] sBRUT;        // 10-4F    
            public Int32 sExchRate;      // 58-5B    курс на основна -> алт.валута

        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDallvoid
        {
            public tagRClass type;           // 00       Тип на командата ALL_VOID
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
            byte[] filler0;     // 01-07    7 байта не се ползват
            public Int64 sTL;            // 08-0F    Обща сума на операциите
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public UInt64[] sBRUT;        // 10-4F    
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDtextline
        {
            public tagRClass type;         // 00       Тип на операцията 'TEXT_LINE'
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_PRINT_COLUMNS)]
            public byte[] text; // 02-2B    до 42 байта текст
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDInvoice
        {
            public tagRClass type;         // 00       Тип на операцията 'Invoice'
            public Int64 invoiceNumber;            // Номер на фактура
        };

        //[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        //public struct tagRCMDbuffer
        //{
        //    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 320)]
        //    byte[] bf;
        //};

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDopen
        {
            public tagRClass type;         // 00   Тип OPEN_BON
            public tagRSubClassOpen subtype;        // 01       Подтип на командата  
            public byte nClerk;           //
            public byte stornoType;           //
            public byte dec_point;           //
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
            byte[] filler;
            public Int64 nInvoice;               //      Номер на фактура
            public Int64 nInvoiceStorno;               //      Номер на сторно фактура
            //public Int32 flags;              //      Флагове
            //public Int64 invN;               //      Номер на фактура
            //public Int64 strToInvoice;       //      Номер на фактура към която е сторното (за случай на кредитно известие)
            public Int32 strNumberDoc;       //      Номер на бона по който е сторното
            public scDATE_TIME bonDateTime;//      Дата и час на бона 
            public scDATE_TIME strDateTime;//      Дата и час на бона по който е сторното
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public byte[] paymentRemap;             //    
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
            public char[] strFMnumber; //      Номер на фискалната памет на бона по който е сторното
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 22)]
            public char[] nSale;        //      Уникален номер на продажба ако е от програма за продажбите CCCCCCCC-CCCC-DDDDDDD трябват 21+1, но оставяме 32

        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        public struct tagRCMDClose
        {
            public tagRClass type;         // 00   Тип 
            public tagRSubClassOpen subtype;        // 01       Подтип на командата  
            public byte ClientEikType;           //
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
            byte[] filler;
            public Int64 nInvoice;               //      Номер на фактура
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            byte[] filler1;
            public scDATE_TIME bonDateTime;//      Дата и час на бона 
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
            public char[] clientEIK; //     
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
            public char[] IDnumber;
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDAddInfo
        {
            public tagRClass type;         // 00   Тип 
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 65)]
            public char[] bonus; //

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
            byte[] filler;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 72)]
            public char[] name; //     
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public char[] TaxN; //   
            public byte typeTaxN;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 72)]
            public char[] RECname; //     

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
            public char[] VATN; //     
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 36)]
            public char[] Address1;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 36)]
            public char[] Address2;
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDCargo
        {
            public tagRClass type;         // 00   Тип 
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
            public char[] tovaritelnica; //
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDBonus
        {
            public tagRClass type;         // 115   Тип 
            public byte index;        // 01       Подтип на командата  
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
            public char[] bonus;

        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 8)]
        public struct tagRCMDBarcodeLine
        {
            public tagRClass type;         // 220   Тип 
            public tagRSubClassBarcode subtype;        // 01       Подтип на командата  
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
            public char[] base64Text;

        };
        //-----------------------------------------------------------------------------------------------------
        //-----------------------------------------------------------------------------------------------------


        public struct scDATE_TIME
        {
            public UInt16 year;
            public byte MM;
            public byte dd;
            public byte hh;
            public byte mm;
            public byte ss;
            public byte dst;
        };


        public static string DateToString(scDATE_TIME date)
        {
            if (date.dst.ToString() == "1")
                return date.dd.ToString("D2") + "-" + date.MM.ToString("D2") + "-" + date.year.ToString("D4") + " " + date.hh.ToString("D2") + ":" + date.mm.ToString("D2") + ":" + date.ss.ToString("D2") + " DST";
            else return date.dd.ToString("D2") + "-" + date.MM.ToString("D2") + "-" + date.year.ToString("D4") + " " + date.hh.ToString("D2") + ":" + date.mm.ToString("D2") + ":" + date.ss.ToString("D2");
            //return date.date.ToString("D2" + "-" + "D2" + "-" + "D4") + " " + date.dst.ToString() + date.hh.ToString("D2") + ":" + date.mm.ToString("D2") + ":" + date.ss.ToString("D2");
        }

        public static T ByteArrayToStructure<T>(byte[] bytes) where T : struct
        {
            T stuff;
            GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
            try
            {
                stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
            }
            finally
            {
                handle.Free();
            }
            return stuff;
        }

        public static int Size<T>() where T : struct
        {
            T x = new T();
            return Marshal.SizeOf(x);
        }

    }
}
