#ifndef SRC_SINWA_PROTO_H_
#define SRC_SINWA_PROTO_H_
#include <stdint.h>

#include <klog.h>


#define SHINWA_CHARGE_MOS(_x)           (_x & (1 << 5))			//data0
#define SHINWA_DISCHARGE_MOS(_x)        (_x & (1 << 6))         //data0
#define SHINWA_VOLTAGE_MODULE(_x)       (_x & (1 << 7))         //data0
#define SHINWA_NTC_LINE(_x)             ((_x >> 8) & 1)			//data1
#define SHINWA_CURRENT_MODULE(_x)       ((_x >> 8) & (1 << 1))  //data1
#define SHINWA_CHARGE_REVERSED(_x)      ((_x >> 8) & (1 << 2))  //data1
#define SHINWA_ANTI_THEFT(_x)           ((_x >> 8) & (1 << 7))  //data1
#define SHINWA_DISCHARGE_OT(_x)         ((_x >> 16) & 1)        //data2
#define SHINWA_DISCHARGE_UT(_x)         ((_x >> 16) & (1 << 1)) //data2
#define SHINWA_CHARGING(_x)             ((_x >> 24) & 1)        //data3
#define SHINWA_DISCHARGING(_x)          ((_x >> 24) & (1 << 1)) //data3
#define SHINWA_SHORT_CURRENT(_x)        ((_x >> 24) & (1 << 2)) //data3
#define SHINWA_OVER_CURRENT(_x)         ((_x >> 24) & (1 << 3)) //data3
#define SHINWA_OVER_VOLTAGE(_x)         ((_x >> 24) & (1 << 4)) //data3
#define SHINWA_UNDER_VOLTAGE(_x)        ((_x >> 24) & (1 << 5)) //data3
#define SHINWA_CHARGE_OT(_x)            ((_x >> 24) & (1 << 6)) //data3
#define SHINWA_CHARGE_UT(_x)            ((_x >> 24) & (1 << 7)) //data3

class ShinwaRequest
{
   uint8_t *mData;
   int mDataLen;
   uint8_t mAddress;
   uint8_t mCID;

public:
   ShinwaRequest(uint8_t address, uint8_t CID, uint8_t *data, uint8_t len);
   virtual ~ShinwaRequest();

   int getFrame(uint8_t *buffer, int len);
};

class ShinwaCell
{
public:
   uint8_t  mFlags;
   float mVoltage;

   ShinwaCell();
   ShinwaCell(uint8_t *data_bytes);
   ~ShinwaCell(){};
};

class ShinwaAlarm
{
public:
   ShinwaAlarm();
   ~ShinwaAlarm(){}

   uint8_t mFlags[10];

   uint32_t getFirst();
};

class ShinwaTelemetry
{
   cKlog logger;
public:

   ShinwaCell mCells[16];
   float mCurrent;
   float mSOC;
   float mCapacity;
   float mTemperatures[8];
   ShinwaAlarm mAlarm;
   float mCycles;
   float mPackVoltage;
   float mSOH;

   ShinwaTelemetry();
   ~ShinwaTelemetry(){};

   void debugInfo();
};

class ShinwaReply
{
   enum eParseState
   {
      START,
      ADDRESS,
      CID,
      LENGTH,
      DATA,
      END
   }mParseState;

   cKlog logger;
   uint8_t *mData;
   int mMaxDataLen;
   int mPackedLength;
   int mDataLen;

public:

   uint8_t mAddress;
   uint8_t mCID;

   ShinwaReply(uint8_t len);
   virtual ~ShinwaReply();

   bool pack(uint8_t byte);
   int getData(uint8_t *buffer, int len);
};


class ShinwaChildCMD
{
   cKlog logger;

   int parseCommand(ShinwaTelemetry *battery, uint8_t *buffer, int len);

public:
   ShinwaChildCMD();
   virtual ~ShinwaChildCMD();
   //ShinwaBattery mBattery;
   void parse(ShinwaTelemetry *battery, uint8_t *buffer, int len);

};

#endif /* SRC_SINWA_PROTO_H_ */
