#ifndef SHARED_MEM_BUFFER_INCLUDED_H
#define SHARED_MEM_BUFFER_INCLUDED_H

#include <cinttypes>
#include <atomic>

#include <QSharedMemory>

struct SharedMemBuffer {
    struct rs {
        char comportName[16]; // z.B. "COM48"
        char baudStr[16];     // z.B. "19200"
        int  baudNr;          // 0...5 oder -1
        uint8_t connect;      // 0,1
        bool portIsOpen;
    } rs;

    char AutoEmissionOn;     // 1: zyklisch Anfragen zum Slave senden

    struct datif {
        uint16_t sendingPeriod;
        bool     sendingPer_changed;
    } datif;

#if 0
    // controlBus.cpp
    char        txt4comStateLine[32];
    char        txt4HsStateLine[32];
    char        txt4masterStateLine[32];
    char        txt4resultStateLine[32];
    char        txt4dataLine[32];
    char        txt4datifReceive[32];
    char        txt4diagWindow[32];
    char        sndTxt4diagWindow[32];
    bool        Sdata_serialTestResult[32];
    uint8_t     Sdata_pProtResultOk[32];
    uint16_t    Sdata_receivedDataLength[32];
    uint8_t     Sdata_receivedDataBlock[64];

    // datif.cpp
    uint8_t     dif_dataStep;
    uint8_t     dif_scanStep;
    uint8_t     RDBLKNR;
    uint8_t     datif_OutCmdpara1;
    uint8_t     datif_OutCmdpara2;
    uint8_t     datif_OutCmdpara3;
    uint8_t     datif_OutCmdpara4;

    uint16_t    datif_OutCmdpara5;
    uint32_t    datif_OutCmdpara6;
    uint8_t     cycl_running;

    // dcBL.cpp
    uint8_t     dcBL_LastBLcmd;   // stored the last sent cmd in order to analys response
    uint8_t     dcBL_AtbBinFile[300000];
    uint32_t    dcBL_fileSize;
    uint16_t    dcBL_nrOfBlocks;
    uint16_t    dcBL_fileCrc;
    uint8_t     dcBL_myBuf[300000]; // same content like "dcBL_AtbBinFile" but bytewise

    char        BlResp[50][32];
    uint8_t     dcBL_step;
    uint8_t     dcBL_state;
    uint16_t    dcBL_BlkCtr;
    uint16_t    dcBL_cyclCtr;
    uint16_t    repeatCtr;
    uint8_t     Sdata_rawData[150];
    uint8_t     Sdata_LengthRawData;

    // hwapi.cpp
    uint16_t    hwapi_shutterTime;
    char        ticketTemplate[1024];

    // sendWRcmd.cpp
    uint16_t    nextAsynchsendCmd0[16];
    uint8_t     nrOfCmdsInQueue;
    uint16_t    nextAsynchsendCmd4[8];
    uint8_t     nextCmd4para1[8];
    uint8_t     nextCmd4para2[8];
    uint8_t     nextCmd4para3[8];
    uint8_t     nextCmd4para4[8];
    uint8_t     nrOfCmds4InQueue;
    uint16_t    nextAsynchsendCmd8[4];
    uint8_t     nextCmd8para1[4];
    uint8_t     nextCmd8para2[4];
    uint16_t    nextCmd8para3[4];
    uint32_t    nextCmd8para4[4];
    uint8_t     nrOfCmds8InQueue;
    uint8_t     sendAsynchDataBuf[160]; // no stack, only ONE buffer
    uint8_t     sendAsyDatLen;
    uint8_t     Sdata_mdbSendBuffer[64];
    uint8_t     Sdata_mdbSendLen;
    uint8_t     prnDataParameters[4];
    uint8_t     prnDataBufferUser;
    char        Sdata_PRN_TEXT[20][64];
    uint8_t     pPrnDataBuff;        // points to next PRINTER_BLOCK
    uint8_t     nextFDwrCmd[16];
    uint8_t     nextFDrdCmd[16];
    uint8_t     nextFDblkNr[16];

    uint8_t     nextFDpara1[16];
    uint8_t     nextFDpara2[16];
    uint8_t     nextFDpara3[16];
    uint8_t     nextFDpara4[16];
    uint8_t     p_nextFDcmdsInQueue;
    uint8_t     longFDwrCmd[16];
    uint8_t     longFDrdCmd[16];
    uint8_t     longFDblkNr[16];
    uint8_t     longFDlength[16];

    uint8_t     longFDpara[16][64];
    uint8_t     p_longFDcmdsInQueue;

    // storeInData.cpp
    bool        indat_savePrnPwr;
    bool        indat_saveMifPwr;
    bool        indat_MdbIsOn;
#endif

    uint8_t     ndbs;
    uint8_t     pari;
    uint8_t     nsb;
    uint8_t     br;

#define MAXNROF_GENSTR 16
    char        genStrings[MAXNROF_GENSTR][64];

#define MAXNROF_AI 4
    uint16_t    AI_val[MAXNROF_AI];

    struct DigitalInputs {
        uint8_t doorSwitch;
        uint8_t vaultSwitch;
        uint8_t lockSwitch;
        uint8_t opto;
        uint8_t aux;
        bool wakeFromPtu;
        bool wakeFromMdb;
        bool wakeFromModem;
        bool PrnReady;
        bool CoinAttach;
        bool CoinEscrowOpen;
        bool mifCardTap;
        bool contactPwrOn;
        bool mifarePwrOn;
        bool rdbk_mdbTxd;
        bool AuxPwrOn;
        bool gsmPwrOn;
        bool creditPwrOn;
        bool printerPwrOn;
        bool mdbPwrOn;
        bool rejMot_home;
        uint8_t npe_sensor;
    } din;

    struct DigitalOutputs {
        uint8_t mbdRxTst;
        uint8_t motorBits;
        uint8_t serialSwitch;                 // serial drv on/off, Serial mux1, Serial mux2
        uint8_t ledsAndFan;
        uint8_t laermUndRelay;
        uint8_t ptuWake;
        uint8_t auxPower;
        uint8_t coinShutter;
        uint8_t coinEscrow;
        uint8_t printerPower;
    } dout;

    struct Sdata {
#define NROFMIFSTATEBYTES       40
#define PRN_STATE_ARRAY_SIZE    20
#define PRN_STATE_FONT_SIZE     20
        uint8_t MIF_STATE[NROFMIFSTATEBYTES];
        uint8_t MIF_DATA[12][64];
        uint8_t PRN_STATE[PRN_STATE_ARRAY_SIZE];
        uint8_t PRN_FONTS[PRN_STATE_FONT_SIZE];
        bool mdb_busRdy;
        bool mdb_V12on;
        bool mdb_V5on;
        uint8_t mdbNrOfRecData;
        uint8_t RecBuff[40];
        uint8_t empNrOfsettings;
        uint8_t emp_settingsBuff[66];
        uint8_t NrOfDeviceSetting;
        uint8_t DeviceSettingBuff[66];
        uint8_t NrOfMachineIDSetting;
        uint8_t NrOfMachineIDBuff[66];
        uint64_t slaveUID;
        uint8_t UIDstr[8];
#define MAXNROF_MEASURE 4
        uint32_t measurement[MAXNROF_MEASURE];
        bool serialTestResult;
        uint8_t pProtResultOk;
        uint16_t receivedDataLength;
        uint8_t receivedDataBlock[64];
    } Sdata;

    uint8_t mif_cardType;
    uint8_t mif_cardHolder[8];

#define MEMDEPTH_GOTCOINS (16)
    struct T_coin {
        uint8_t valid;
        uint8_t signal;
        uint8_t error;
        uint8_t pad;
        uint16_t value;
    } gotCoin[MEMDEPTH_GOTCOINS];
    uint8_t ctr_gotCoin;

    struct store {
        uint32_t insertedAmount;
        uint16_t lastCoinType[64];
        uint16_t lastCoinValue[64];
        uint64_t wakeSrc;
        uint8_t rbDevParamLen;
        uint8_t rbDevParams[66];
        uint8_t deviceCondLen;
        uint8_t deviceCond[66];
        uint8_t machCondLen;
        uint8_t machCond[66];
        uint8_t DcBackupNrOfAccNr;
        uint16_t DcBackupAccNr[16];    // z.Z. nur 8
        uint8_t gotNrBlocksOfVaultRec;
        uint8_t vaultrecord[360];
        uint32_t amount;
        uint16_t nrOfCoins;
        bool    dcDataValid;
        uint8_t wakeReason;

    } store;

    struct T_globTime {
        // Reihenfolge nicht vertauschen!!!!!
        uint8_t     hour;
        uint8_t     minute;
        uint8_t     second;
        uint8_t     Year;
        uint8_t     Month;
        uint8_t     DayOfMonth;
        uint8_t     DayOfWeek;          // 1=monday...7
        uint8_t     reserve1;

        uint16_t     MinutesOfToday;
        uint16_t     reserve2;

        uint32_t     SecondsOfToday;

        uint8_t      IsLeapyear;
        uint8_t      nextLeap;
        uint8_t      lastLeap;
        uint8_t      hoursOfWeek;

        uint16_t     minOfWeek;
        uint16_t     hoursOfMonth;
        uint16_t     minOfMonth;
        uint16_t     dayOfYear;
        uint16_t     hoursOfYear;
        uint16_t     reserve3;

        uint32_t     minOfYear;

        uint8_t      squareOutMode;
        uint8_t      free1;
        uint16_t     reserve4;
        uint32_t     minOfMillenium;
        // bis hierher 44byts
        uint32_t    free2;
        uint32_t    free3;
        uint32_t    free4;
    } getGlobalTime;

    static QSharedMemory *getShm(std::size_t s = 0);
    static SharedMemBuffer *getData() {
        return (SharedMemBuffer *)getShm()->data();
    }
    static SharedMemBuffer const *getDataConst() {
        return (SharedMemBuffer const *)getShm()->data();
    }

#if 0
    static std::atomic<bool> __sharedMemLocked;

    static bool sharedMemLocked() {
        return __sharedMemLocked;
    }
    static void setSharedMemLocked() {
        __sharedMemLocked = true;
    }
    static void setSharedMemUnlocked() {
        __sharedMemLocked = false;
    }
#endif
};

#endif // SHARED_MEM_BUFFER_INCLUDED_H