#ifndef Mk3Types_h
#define Mk3Types_h
#include <stdint.h>
#include "CommonEpdTypes.h"
#include <vector>
#define MAX_COUNTERS 6
// Mk3 Measurands 
#define MK3_MEAS_HP10   0
#define MK3_MEAS_HP07   1
#define MK3_MEAS_HP10G  2
#define MK3_MEAS_HP10N  3
enum class CounterType : uint16_t
{
  Counter_Hg1 = 0, // MK2 HG
  Counter_Hg2 = 1,
  Counter_Sg1 = 2,  // Mk2 SG
  Counter_Sg2 = 3,  // Mk2 BC
  Counter_Sg3 = 4,
  Counter_Fb1 = 5,  // Mk2 FB
  Counter_Fb2 = 6,
  Counter_An1 = 7,
  Counter_Fn2 = 8
};
#define MAX_DET_THRESHOLDS MAX_COUNTERS
#pragma pack (push)
#pragma pack (1)
typedef struct
{
    uint16_t eventId;
  uint16_t info;
    uint32_t timestamp;
}EventLog;
typedef struct
{
  uint16_t type;
  uint32_t  value;  
}Counter_t;
typedef struct
{
  uint16_t type;
  uint16_t  value;
}DetectorThreshold_t;
typedef struct
{
  CounterType id;
  uint16_t  scaledDeadTime;
  uint16_t  scaledCoefficient;
}DeadTimeCoefficient_t;
typedef struct
{
  CounterType id;
  uint8_t  value;
}DetectorTestLimit_t;
typedef struct
{
  uint16_t type;
  uint16_t  va;
  uint16_t  vb;
}DetectorThresholdLimit_t;
enum class OffModeDutyCycle :uint8_t
{
  Off = 0,  
  On = 1,   
  Pct50 = 2, 
  Pct33 = 3,  
  Pct25 = 4, 
  Pct10 = 5, 
  NoChange = 255 
};
enum class SensitivityId
{
    //Hp10 Gamma contributors
    Hg1Sens10G = 0,  // Mk2 HGSens10 (K1)
    Hg2Sens10G = 1,  
    Sg1Sens10G = 2,  // Mk2 SGSens10 (K2) 
    Sg2Sens10G = 3,
    Sg3Sens10G = 4,
    //Hp10 Neutron contributors
    //Hp07 Gamma contributors
    Hg1Sens07G = 5,  // Mk2 HGSens07 (K3)
    Hg2Sens07G = 6,
    Sg1Sens07G = 7,  // Mk2 SGSens07 (K4)
    Sg2Sens07G = 8,
    Sg3Sens07G = 9,
    //Hp07 Beta contributors
    Fb1Sens07B = 10,  // Mk2 FBSens07 (K5)
    Fb2Sens07B = 11,
    Sg2Sens07B = 12,  // Mk2 BCSens07 (K6)
    Sg3Sens07B = 13,
    MaxSensitivity
};
#define MAX_SENSITIVITIES ((uint16_t)SensitivityId::MaxSensitivity)
#define LAST_SENSITIVITY (((uint16_t)SensitivityId::MaxSensitivity) - 1)
enum class MeasurementId : uint16_t
{
  Meas_Hp10,  
  Meas_Hp07,  
  Meas_Hp10G,  
  Meas_Hp10N   
};
#define MAX_MEASUREMENTS 4
enum class ThresholdId
{
  Thres_DoseAlarm = 0,  
  Thres_DoseWarning = 1,  
  Thres_RateAlarm = 2,  
  Thres_RateWarning = 3  
};
#define MAX_ALM_THRESHOLDS 4
enum class WearerIdType
{
  WearerId_Name,    
  WearerId_Primary, 
  WearerId_Id2,     
  WearerId_Id3      
};
#define MAX_WEARER_ID_TYPES 4
enum class TaskIdType
{
  Task_Name,   
  Task_Primary 
};
#define MAX_TASK_ID_TYPES 2
enum class WearerAndTaskIdType_t : uint16_t
{
  WearerId_Name,     
  WearerId_Primary,  
  WearerId_Id2,      
  WearerId_Id3,      
  TaskName,          
  TaskID,            
  WearerDBID,        
  TaskDBID           
};
#define MAX_WEARER_TASK_ID_TYPES 8
typedef struct
{
  uint8_t RecordType;  
  uint8_t Measurand;   
  int32_t TimeStamp;    
  uint32_t Value;       
}DoseProfileRecord_t;
typedef struct
{
  float DoseIncrement;  
  uint16_t Interval;    
  uint16_t NumberOfMeasurands;  
  MeasurementId Enables[MAX_MEASUREMENTS];  
}DoseProfileConfig_t;
typedef struct
{
  uint16_t  id;  
  float  value; 
}CalSensitivity_t;
typedef struct
{
  uint16_t  id;  
  float  value; 
}CalGain_t;
typedef struct
{
  uint16_t  id;  
  float  value; 
}MeasValue_t;
typedef struct 
{
  uint16_t id;  
  float value; 
  uint32_t timestamp;  
}PeakRate_t;
typedef struct
{
  uint32_t Utc;
  uint16_t NumberOfMeasurands;
  MeasValue_t Measurements[MAX_MEASUREMENTS];
}MeasurandDoseOrRate_t;
typedef struct
{
  uint8_t Major; 
  uint8_t Minor;
  uint8_t Patch;
  uint16_t Build;
}VersionNumber_t;
typedef struct MarkNumberTag
{
  uint8_t Major;
  uint8_t Minor;
  uint8_t Revision;
  uint8_t Build;
} MarkNumber_t;
#define PART_NUM_LENGTH 10
typedef uint8_t PartNumber_t[PART_NUM_LENGTH];
#define PCB_PART_NUM_LENGTH 14
typedef uint8_t PcbPartNumber_t[PCB_PART_NUM_LENGTH];
#define FIRMWARE_PART_NUM_LENGTH 16
typedef uint8_t FirmwarePartNumber_t[FIRMWARE_PART_NUM_LENGTH];
#define MODEL_NAME_LENGTH 32
typedef struct ModelNameTag
{
  uint8_t Name[MODEL_NAME_LENGTH];
} ModelName_t;
#define CAL_PROCESS_LENGTH 12
typedef struct CalProcessTag
{
  uint8_t Process[CAL_PROCESS_LENGTH];
} CalProcess_t;
#define CAL_FACILITY_LENGTH 8
typedef struct CalFacilityTag
{
  uint8_t Name[CAL_FACILITY_LENGTH];
} CalFacility_t;
#define MAX_ID_STRING_LENGTH 64
typedef struct IdStringTag
{
  uint16_t IdType;
  uint16_t Length;
  uint8_t Utf8String[MAX_ID_STRING_LENGTH];
} IdString_t;
#define DB_ID_LENGTH 16
typedef struct DbIdTag
{
  uint8_t Id[DB_ID_LENGTH];
} DatabaseId_t;
#define MAX_GRAPHIC_WIDTH 112
#define MAX_GRAPHIC_HEIGHT 24
#define MAX_GRAPHIC_PIXELS (MAX_GRAPHIC_WIDTH * MAX_GRAPHIC_HEIGHT)
#define MAX_GRAPHIC_ID 1
#define MAX_GRAPHIC_BYTES ((MAX_GRAPHIC_PIXELS)/8)
typedef struct GraphicSizeTag
{
  uint16_t Id;  
  uint16_t Height;  
  uint16_t Width;   
} GraphicSize_t;
typedef struct
{
  GraphicSize_t Meta;  
  uint16_t DataLength;  
  uint8_t Data[MAX_GRAPHIC_BYTES];  
} GraphicBitmap_t;
enum class OpStatusFlags : uint32_t {
  EpdOn = 0x0001,                  
  EpdIssued = 0x0002,              
  DetectorTestRequested = 0x0004,  
  DetectorTestPassed = 0x0008,     
  TelemetryOn = 0x0010,            
  TelemetryConnected = 0x0020,     
  CalibrationDue = 0x0040,         
  CalibrationInProgress = 0x0080,  
  GainAdjustable = 0x0100,         
  GainAdjusted = 0x0200,           
  ReducedRateOverrange = 0x0400,   
  DoseWriteEnabled = 0x0800,       
  ClearOnOnEnabled = 0x1000,       
  Golden = 0x2000,                 
  ProtectedSession = 0x4000,       
  //NotYetDefined = 0x8000,
  ResponderEnabled = 0x00010000,   
  ResponderTriggered = 0x00020000, 
  AlkalineFitted = 0x00040000,     
  DeepSleep = 0x00080000,          
  CovertMode = 0x00100000,         
  PulsedModeEnabled = 0x00200000,  
  PulsedModeActive = 0x00400000,   
  PulsedModeIndustrial=0x00800000, 
};
enum class FaultStatusFlags : uint32_t {
  NotInitialized = 0x0001,         
  BadThreshold = 0x0002,           
  BadSensitivities = 0x0004,       
  DetectorTestFail = 0x0008,       
  NotCalibrated = 0x0010,          
  EepromFailure = 0x0020,          
  ErrorLogged = 0x0040,            
  EpdFaulty = 0x0080,              
  TimeInvalid = 0x0100,            
  EarlyCommsTermination = 0x0200,  
  SounderFailure = 0x0400,         
  ResetWhileIssued = 0x0800,       
};
enum class AlarmStatusFlags : uint32_t {
  DoseWarning = 0x00000001,          
  DoseAlarm = 0x00000002,            
  DoseOverrange = 0x00000004,        
  TotalDoseOverrange = 0x00000008,   
  RateWarning = 0x00000010,          
  RateAlarm = 0x00000020,            
  RateOverrange = 0x00000040,        
  PulseOverrange = 0x00000080,       
  LatchedRateWarning = 0x00000100,   
  LatchedRateAlarm = 0x00000200,     
  LatchedRateOverrange = 0x00000400, 
  LatchedPulseOverrange = 0x00000800,
  StayTimeExceeded = 0x00010000,     
  ReturnForRead = 0x00020000,        
  AbuseAlarm = 0x00040000,           
  LowBattery = 0x00080000,           
  TelemetryAlert = 0x00100000        
};
enum class DoseAlarmFlags : uint32_t {
  DoseWarning = 0x0001,          
  DoseAlarm = 0x0002,            
  DoseOverrange = 0x0004,        
  TotalDoseOverrange = 0x0008,   
  RateWarning = 0x0010,          
  RateAlarm = 0x0020,            
  RateOverrange = 0x0040,        
  LatchedRateWarning = 0x0100,   
  LatchedRateAlarm = 0x0200,     
  LatchedRateOverrange = 0x0400  
};
enum class Mk2StatusFlags : uint32_t {
  ADSIssued = 0x0001,
  OneSecCountsProcessing = 0x0002,
  RadioBatteryLow = 0x0004
};
typedef struct
{
  uint16_t Id;    
  DoseAlarmFlags Status;  
}Mk3DoseStatus_t;
typedef struct
{
  OpStatusFlags OperatingStatus;  
  FaultStatusFlags FaultStatus;   
  AlarmStatusFlags AlarmStatus;   
  uint16_t IssueCount;            
  uint16_t FaultCode;             
  uint32_t OtherBits;             
  uint16_t NumberDoseAlarmWords;  
  Mk3DoseStatus_t DoseAlarms[MAX_MEASUREMENTS];  
}StatusData_t;
enum class QualityFlags
{
  DoseOverrange = 0x0001,    
  RateOverrange = 0x0002,    
  AbuseWarning = 0x0004,     
  CrcFailure = 0x0008,       
  CounterOverrange = 0x0010, 
  DetectorFail = 0x0040      
};
typedef struct
{
  uint16_t PowerCycles;  
  uint16_t Knocks;       
  QualityFlags Flags;    
}Mk3QualityData_t;
typedef struct
{
  uint16_t Id;   
  float Value;   
}Mk3AlarmThreshold_t;
typedef struct
{
  uint16_t MeasId;   
  uint16_t NumberThresholds;  
  Mk3AlarmThreshold_t Thresholds[MAX_ALM_THRESHOLDS];  
}Mk3AlarmThresholds_t;
typedef struct
{
  uint16_t MeasId;
  std::vector<ThresholdId> Thresholds;
}Mk3AlarmThresholdsRequest_t;
typedef struct
{
  uint16_t MeasId; 
  uint16_t Value;  
}Mk3RatePercentage_t;
typedef struct
{
  uint16_t MeasId;     
  uint16_t AlarmFlags; 
  float Dose;          
}Mk3SnapshotDoseAndFlags_t;
typedef struct
{
  uint16_t SnapshotNumber;  
  uint16_t IssueCount;      
  uint32_t StartTime;       
  uint32_t EndTime;         
  DatabaseId_t WearerDbId;  
  DatabaseId_t TaskDbId;    
  uint32_t OperatingStatus; 
  uint32_t FaultStatus;     
  uint32_t AlarmStatus;     
  uint16_t NumberOfMeasurands;  
  Mk3SnapshotDoseAndFlags_t DoseAndFlags[MAX_MEASUREMENTS];  
}Mk3SnapshotSummary_t;
typedef struct
{
  uint16_t MeasId;      
  uint16_t AlarmFlags;  
  float Dose;           
  float TriggeredDose;  
  float TotalDose;      
  float PeakRate;       
  uint32_t PeakRateTime; 
}Mk3SnapshotMeasurement_t;
typedef struct
{
  uint16_t SnapshotNumber;      
  uint16_t NumberOfMeasurands;  
  Mk3SnapshotMeasurement_t DoseAndFlags[MAX_MEASUREMENTS]; 
}Mk3SnapshotMeasurements_t;
typedef struct
{
  uint16_t CounterId;   
  uint32_t StartCount;  
  uint32_t EndCount;    
}Mk3SnapshotCount_t;
typedef struct
{
  uint16_t SnapshotNumber;   
  uint16_t NumberOfCounters;  
  uint32_t StartTime;        
  uint32_t EndTime;          
  Mk3SnapshotCount_t Counters[MAX_COUNTERS];  
}Mk3SnapshotCounters_t;
typedef struct
{
  float DoseWarning;  
  float DoseAlarm;    
  float RateWarning;  
  float RateAlarm;    
  uint16_t MeasId;    
}Mk3SnapshotAlarmThreshold_t;
typedef struct
{
  uint16_t SnapshotNumber;    
  uint16_t NumberOfMeasurands; 
  Mk3SnapshotAlarmThreshold_t Thresholds[MAX_MEASUREMENTS]; 
}Mk3SnapshotAlarmThresholds_t;
// ****************
// Access Level
//
#define COMMAND_ID_MAP_SIZE 64
#define ENCRYPT_IV_SIZE 16
#define ENCRYPT_KEY_SIZE 32
#define ENCRYPT_CIPHER_SIZE 16
typedef uint8_t EncryptionKey[ENCRYPT_KEY_SIZE];
typedef uint8_t EncryptionText[ENCRYPT_CIPHER_SIZE];
typedef uint8_t PlainText[ENCRYPT_CIPHER_SIZE];
enum class AccessLevel_t : uint8_t 
{
  Open = 0,        
  Admin = 1,       
  Regulator = 2,   
  Manufacturer = 3 
};
typedef struct SetAccessLevelRqTag
{
  bool Granted;
  EncryptionText Code;
  EncryptionKey Key;
  AccessLevel_t Level;
} SetAccessLevelRq_t;
typedef struct SetAccessPasswordRqTag
{
  EncryptionKey Key;
  AccessLevel_t Level;
} SetAccessPasswordRq_t;
typedef struct CommandIdPermissionsTag
{
  AccessLevel_t Level;
  uint8_t CommandIdPermissions[COMMAND_ID_MAP_SIZE];
}CommandIdPermissions_t;
// ****************
// UI Config
//
#define MAX_QUICK_ACCESS_DISPLAYS 6 /*5 + default display*/
typedef struct QuickAccessDisplayTag
{
  uint8_t  Position;  
  uint8_t  DisplayId;  
}QuickAccessDisplay_t;
typedef struct DisplayEnablesTag
{
  uint8_t  MenuId;      
  uint16_t EnableMask;  
  uint16_t  Enables;    
}DisplayAttributeMap_t;
#define MAX_MENUS 15
typedef struct DisplayEnablePrivilegesTag
{
  AccessLevel_t Level;
  uint8_t NumMenus;
  uint16_t Privileges[MAX_MENUS];
} DisplayEnablePrivileges_t;
enum class DisplayCapability_t :uint8_t
{
  DefaultDisplay = 1,
  QuickDisplay = 2,
};
enum class OffModeDisplayId_t : uint8_t
{
  Undefined = 0,     
  OffText = 1,       
  CalDueDate = 2,    
  UserBitmap = 3,    
  Manufacturer_PartnerLogo = 4,  
  CustomerLogo = 5,  
  ModelVersion=6     
};
enum class AlarmIds : uint16_t
{
  DoseAlarm = 0,          
  DoseWarning = 1,        
  RateWarning = 2,        
  RateAlarm = 3,          
  DoseOrRateOverRange = 4, 
  FailureAlarm = 5,       
  AbuseAlarm = 6,         
  BatteryLow = 7,         
  ReturnForRead = 8       
};
#define MAX_OTHER_ALARMS 5
typedef struct AlarmConfigTag
{
  AlarmIds AlarmId;          
  uint16_t MeasurandId;      
  uint16_t  AlarmConfigMask; 
  uint16_t  AlarmConfigBits; 
  uint16_t  Duration;        
}AlarmConfig_t;
typedef struct AlarmConfigIdTag
{
  AlarmIds AlarmId;      
  uint16_t MeasurandId;  
}AlarmConfigId;
// ****************
// Telemetry
//
typedef struct TeleAdvConfigTag
{
  uint8_t  operatingMode;      
  uint16_t undirectedInterval; 
  uint16_t directedInterval;   
  uint16_t directedTimeout;    
}TeleAdvConfig_t;
typedef struct TeleCxnConfigTag
{
  uint16_t minInterval;  
  uint16_t maxInterval;  
  uint16_t slaveLatency; 
  uint16_t supervisoryTimeout;  
}TeleCxnConfig_t;
// ****************
// Debug Registers
//
typedef struct DebugRegisterValueTag
{
  uint8_t  registerId;
  uint32_t value;
}DebugRegisterValue_t;
// ****************
// Battery Low Thesholds
//
typedef struct BatteryLowThresholdTag
{
  uint8_t  batteryType;
  uint16_t mv;
}BatteryLowThreshold_t;
// ****************
// Battery Critical Timing
//
typedef struct BatteryCriticalTimingTag
{
  uint16_t timeToCritical; 
  uint16_t timeToShutdown;
}BatteryCriticalTiming_t;
// ****************
// Battery Critical Timing
//
typedef struct MeasuredVoltagesTag
{
  uint16_t vbat0;
  uint16_t vbat1;
  uint16_t vcpu;
}MeasuredVoltages_t;
#pragma pack (pop)
#endif