/*
  rdm.h

  Copyright (c) 2021 Kevin Matz (kevin.matz@gmail.com)

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
*/
#pragma once

#include "dmx/dmx.h"
#include "E1.37-1.h"
#include "E1.37-2.h"
#include "E1.37-7.h"

#include <string>

namespace RDM {

  using PID = uint16_t; //!< Parameter Identification number

  /// 10.5.1 Get Device Info (DEVICE_INFO)
  /// RDM Protocol Version:
  /// The version of this standard is 1.0
  static const uint16_t RDM_PROTOCOL_VERSION = 0x0100;

  /// Appendix A: Defined Parameters (Normative)

  /// START Codes (Slot 0)
  static const uint8_t SC_RDM = 0xCC;

  /// RDM Protocol Data Structure ID’s (Slot 1)
  static const uint8_t SC_SUB_MESSAGE = 0x01;

  /// Broadcast Device UID’s
  static const uint64_t BROADCAST_ALL_DEVICES_ID = 0xFFFFFFFFFFFF; //!< Broadcast all Manufacturers
  static const uint64_t ALL_DEVICE_ID_MASK       = 0x0000FFFFFFFF; //!< Specific Manufacturer ID in hight 2 bytes
  static const uint16_t SUB_DEVICE_ALL_CALL      = 0xFFFF;

  /// Table A-1: Command Class Defines (Slot 20)
  static const uint8_t DISCOVERY_COMMAND          = 0x10;
  static const uint8_t DISCOVERY_COMMAND_RESPONSE = 0x11;
  static const uint8_t GET_COMMAND                = 0x20;
  static const uint8_t GET_COMMAND_RESPONSE       = 0x21;
  static const uint8_t SET_COMMAND                = 0x30;
  static const uint8_t SET_COMMAND_RESPONSE       = 0x31;

  /// Table A-2: Response Type Defines (Slot 16)
  static const uint8_t RESPONSE_TYPE_ACK          = 0x00;
  static const uint8_t RESPONSE_TYPE_ACK_TIMER    = 0x01;
  static const uint8_t RESPONSE_TYPE_NACK_REASON  = 0x02; //!< See Table A-17
  static const uint8_t RESPONSE_TYPE_ACK_OVERFLOW = 0x03; //!< Additional Response Data available beyond single response length.

  /// Table A-3: RDM Categories/Parameter ID Defines
  /// Category – Network Management
  static const PID DISC_UNIQUE_BRANCH    = 0x0001;
  static const PID DISC_MUTE             = 0x0002;
  static const PID DISC_UN_MUTE          = 0x0003;
  static const PID PROXIED_DEVICES       = 0x0010;
  static const PID PROXIED_DEVICE_COUNT  = 0x0011;
  static const PID COMMS_STATUS          = 0x0015;
  /// Category - Status Collection
  static const PID QUEUED_MESSAGE        = 0x0020; // See Table A-4
  static const PID STATUS_MESSAGES       = 0x0030; // See Table A-4
  static const PID STATUS_ID_DESCRIPTION = 0x0031;
  static const PID CLEAR_STATUS_ID       = 0x0032;
  static const PID SUB_DEVICE_STATUS_REPORT_THRESHOLD = 0x0033; // See Table A-4
  /// Category - RDM Information
  static const PID SUPPORTED_PARAMETERS  = 0x0050;
  static const PID PARAMETER_DESCRIPTION = 0x0051;
  /// Category – Product Information
  static const PID DEVICE_INFO           = 0x0060;
  static const PID PRODUCT_DETAIL_ID_LIST = 0x0070;
  static const PID DEVICE_MODEL_DESCRIPTION = 0x0080;
  static const PID MANUFACTURER_LABEL    = 0x0081;
  static const PID DEVICE_LABEL          = 0x0082;
  static const PID FACTORY_DEFAULTS      = 0x0090;
  static const PID LANGUAGE_CAPABILITIES = 0x00A0;
  static const PID LANGUAGE              = 0x00B0;
  static const PID SOFTWARE_VERSION_LABEL = 0x00C0;
  static const PID BOOT_SOFTWARE_VERSION_ID = 0x00C1;
  static const PID BOOT_SOFTWARE_VERSION_LABEL = 0x00C2;
  /// Category - DMX512 Setup
  static const PID DMX_PERSONALITY       = 0x00E0;
  static const PID DMX_PERSONALITY_DESCRIPTION = 0x00E1;
  static const PID DMX_START_ADDRESS     = 0x00F0;
  static const PID SLOT_INFO             = 0x0120;
  static const PID SLOT_DESCRIPTION      = 0x0121;
  static const PID DEFAULT_SLOT_VALUE    = 0x0122;
  /// Category – Sensors
  static const PID SENSOR_DEFINITION     = 0x0200;
  static const PID SENSOR_VALUE          = 0x0201;
  static const PID RECORD_SENSORS        = 0x0202;
  /// Category – Power/Lamp Settings
  static const PID DEVICE_HOURS          = 0x0400;
  static const PID LAMP_HOURS            = 0x0401;
  static const PID LAMP_STRIKES          = 0x0402;
  static const PID LAMP_STATE            = 0x0403;
  static const PID LAMP_ON_MODE          = 0x0404;
  static const PID DEVICE_POWER_CYCLES   = 0x0405;
  /// Category - Display Settings
  static const PID DISPLAY_INVERT        = 0x0500;
  static const PID DISPLAY_LEVEL         = 0x0501;
  /// Category – Configuration
  static const PID PAN_INVERT            = 0x0600;
  static const PID TILT_INVERT           = 0x0601;
  static const PID PAN_TILT_SWAP         = 0x0602;
  static const PID REAL_TIME_CLOCK       = 0x0603;
  /// Category – Control
  static const PID IDENTIFY_DEVICE       = 0x1000;
  static const PID RESET_DEVICE          = 0x1001;
  static const PID POWER_STATE           = 0x1010;
  static const PID PERFORM_SELFTEST      = 0x1020;
  static const PID SELF_TEST_DESCRIPTION = 0x1021;
  static const PID CAPTURE_PRESET        = 0x1030;
  static const PID PRESET_PLAYBACK       = 0x1031;

  /// Table A-4: Status Type Defines
  static const uint8_t STATUS_NONE              = 0x00; //!< Not allowed for use with GET: QUEUED_MESSAGE
  static const uint8_t STATUS_GET_LAST_MESSAGE  = 0x01;
  static const uint8_t STATUS_ADVISORY          = 0x02;
  static const uint8_t STATUS_WARNING           = 0x03;
  static const uint8_t STATUS_ERROR             = 0x04;
  static const uint8_t STATUS_ADVISORY_CLEARED  = 0x12;
  static const uint8_t STATUS_WARNING_CLEARED   = 0x13;
  static const uint8_t STATUS_ERROR_CLEARED     = 0x14;

  std::string ProductCategoryDescription(const uint16_t PRODUCT_CATEGORY);
  /// Table A-5: Product Category Defines
  static const uint16_t PRODUCT_CATEGORY_NOT_DECLARED             = 0x0000;
  /// Fixtures – intended as source of illumination
  static const uint16_t PRODUCT_CATEGORY_FIXTURE                  = 0x0100; //!< No Fine Category declared
  static const uint16_t PRODUCT_CATEGORY_FIXTURE_FIXED            = 0x0101; //!< No pan / tilt / focus style functions
  static const uint16_t PRODUCT_CATEGORY_FIXTURE_MOVING_YOKE      = 0x0102;
  static const uint16_t PRODUCT_CATEGORY_FIXTURE_MOVING_MIRROR    = 0x0103;
  static const uint16_t PRODUCT_CATEGORY_FIXTURE_OTHER            = 0x01FF; //!< For example, focus but no pan/tilt.
  /// Fixture Accessories – add-ons to fixtures or projectors
  static const uint16_t PRODUCT_CATEGORY_FIXTURE_ACCESSORY        = 0x0200; //!< No Fine Category declared.
  static const uint16_t PRODUCT_CATEGORY_FIXTURE_ACCESSORY_COLOR  = 0x0201; //!< Scrollers / Color Changers
  static const uint16_t PRODUCT_CATEGORY_FIXTURE_ACCESSORY_YOKE   = 0x0202; //!< Yoke add-on
  static const uint16_t PRODUCT_CATEGORY_FIXTURE_ACCESSORY_MIRROR = 0x0203; //!< Moving mirror add-on
  static const uint16_t PRODUCT_CATEGORY_FIXTURE_ACCESSORY_EFFECT = 0x0204; //!< Effects Discs
  static const uint16_t PRODUCT_CATEGORY_FIXTURE_ACCESSORY_BEAM   = 0x0205; //!< Gobo Rotators / Iris / Shutters / Dousers / Beam modifiers.
  static const uint16_t PRODUCT_CATEGORY_FIXTURE_ACCESSORY_OTHER  = 0x02FF;
  /// Projectors - light source capable of producing realistic images from another media
  static const uint16_t PRODUCT_CATEGORY_PROJECTOR                = 0x0300; //!< No Fine Category declared.
  static const uint16_t PRODUCT_CATEGORY_PROJECTOR_FIXED          = 0x0301; //!< No pan / tilt functions.
  static const uint16_t PRODUCT_CATEGORY_PROJECTOR_MOVING_YOKE    = 0x0302;
  static const uint16_t PRODUCT_CATEGORY_PROJECTOR_MOVING_MIRROR  = 0x0303;
  static const uint16_t PRODUCT_CATEGORY_PROJECTOR_OTHER          = 0x03FF;
  /// Atmospheric Effect – earth/wind/fire
  static const uint16_t PRODUCT_CATEGORY_ATMOSPHERIC              = 0x0400; //!< No Fine Category declared.
  static const uint16_t PRODUCT_CATEGORY_ATMOSPHERIC_EFFECT       = 0x0401; //!< Fogger / Hazer / Flame, etc.
  static const uint16_t PRODUCT_CATEGORY_ATMOSPHERIC_PYRO         = 0x0402; //!< See Note 2.
  static const uint16_t PRODUCT_CATEGORY_ATMOSPHERIC_OTHER        = 0x04FF;
  /// Intensity Control (specifically Dimming equipment)
  static const uint16_t PRODUCT_CATEGORY_DIMMER                   = 0x0500; //!< No Fine Category declared.
  static const uint16_t PRODUCT_CATEGORY_DIMMER_AC_INCANDESCENT   = 0x0501; //!< AC > 50VAC
  static const uint16_t PRODUCT_CATEGORY_DIMMER_AC_FLUORESCENT    = 0x0502;
  static const uint16_t PRODUCT_CATEGORY_DIMMER_AC_COLDCATHODE    = 0x0503; //!< High Voltage outputs such as Neon or other cold cathode.
  static const uint16_t PRODUCT_CATEGORY_DIMMER_AC_NONDIM         = 0x0504; //!< Non-Dim module in dimmer rack.
  static const uint16_t PRODUCT_CATEGORY_DIMMER_AC_ELV            = 0x0505; //!< AC <= 50V such as 12/24V AC Low voltage lamps.
  static const uint16_t PRODUCT_CATEGORY_DIMMER_AC_OTHER          = 0x0506;
  static const uint16_t PRODUCT_CATEGORY_DIMMER_DC_LEVEL          = 0x0507; //!< Variable DC level output.
  static const uint16_t PRODUCT_CATEGORY_DIMMER_DC_PWM            = 0x0508; //!< Chopped (PWM) output.
  static const uint16_t PRODUCT_CATEGORY_DIMMER_CS_LED            = 0x0509; //!< Specialized LED dimmer.
  static const uint16_t PRODUCT_CATEGORY_DIMMER_OTHER             = 0x05FF;
  /// Power Control (other than Dimming equipment)
  static const uint16_t PRODUCT_CATEGORY_POWER                    = 0x0600; //!< No Fine Category declared.
  static const uint16_t PRODUCT_CATEGORY_POWER_CONTROL            = 0x0601; //!< No Fine Category declared.
  static const uint16_t PRODUCT_CATEGORY_POWER_SOURCE             = 0x0602; //!< Generators
  static const uint16_t PRODUCT_CATEGORY_POWER_OTHER              = 0x06FF;
  /// Scenic Drive – including motorized effects unrelated to light source.
  static const uint16_t PRODUCT_CATEGORY_SCENIC                   = 0x0700;
  static const uint16_t PRODUCT_CATEGORY_SCENIC_DRIVE             = 0x0701; //!< Rotators / Kabuki drops, etc.
  static const uint16_t PRODUCT_CATEGORY_SCENIC_OTHER             = 0x07FF;
  /// DMX Infrastructure, conversion and interfaces
  static const uint16_t PRODUCT_CATEGORY_DATA                     = 0x0800;
  static const uint16_t PRODUCT_CATEGORY_DATA_DISTRIBUTION        = 0x0801;
  static const uint16_t PRODUCT_CATEGORY_DATA_CONVERSION          = 0x0802;
  static const uint16_t PRODUCT_CATEGORY_DATA_OTHER               = 0x08FF;
  /// Audio-Visual Equipment
  static const uint16_t PRODUCT_CATEGORY_AV                       = 0x0900;
  static const uint16_t PRODUCT_CATEGORY_AV_AUDIO                 = 0x0901;
  static const uint16_t PRODUCT_CATEGORY_AV_VIDEO                 = 0x0902;
  static const uint16_t PRODUCT_CATEGORY_AV_OTHER                 = 0x09FF;
  /// Parameter Monitoring Equipment
  static const uint16_t PRODUCT_CATEGORY_MONITOR                  = 0x0A00;
  static const uint16_t PRODUCT_CATEGORY_MONITOR_ACLINEPOWER      = 0x0A01;
  static const uint16_t PRODUCT_CATEGORY_MONITOR_DCPOWER          = 0x0A02;
  static const uint16_t PRODUCT_CATEGORY_MONITOR_ENVIRONMENTAL    = 0x0A03;
  static const uint16_t PRODUCT_CATEGORY_MONITOR_OTHER            = 0x0AFF;
  /// Controllers, Backup devices
  static const uint16_t PRODUCT_CATEGORY_CONTROL                  = 0x7000;
  static const uint16_t PRODUCT_CATEGORY_CONTROL_CONTROLLER       = 0x7001;
  static const uint16_t PRODUCT_CATEGORY_CONTROL_BACKUPDEVICE     = 0x7002;
  static const uint16_t PRODUCT_CATEGORY_CONTROL_OTHER            = 0x70FF;
  /// Test Equipment
  static const uint16_t PRODUCT_CATEGORY_TEST                     = 0x7100; //!< No Fine Category declared.
  static const uint16_t PRODUCT_CATEGORY_TEST_EQUIPMENT           = 0x7101;
  static const uint16_t PRODUCT_CATEGORY_TEST_EQUIPMENT_OTHER     = 0x71FF;
  /// Miscellaneous
  static const uint16_t PRODUCT_CATEGORY_OTHER                    = 0x7FFF; //!< For devices that aren’t described within this table.

  std::string ProductDetailDescription(const uint16_t PRODUCT_DETAIL);
  /// Table A-6: Product Detail
  static const uint16_t PRODUCT_DETAIL_NOT_DECLARED               = 0x0000;
  /// Generally applied to fixtures
  static const uint16_t PRODUCT_DETAIL_ARC                        = 0x0001;
  static const uint16_t PRODUCT_DETAIL_METAL_HALIDE               = 0x0002;
  static const uint16_t PRODUCT_DETAIL_INCANDESCENT               = 0x0003;
  static const uint16_t PRODUCT_DETAIL_LED                        = 0x0004;
  static const uint16_t PRODUCT_DETAIL_FLUROESCENT                = 0x0005;
  static const uint16_t PRODUCT_DETAIL_COLDCATHODE                = 0x0006;
  static const uint16_t PRODUCT_DETAIL_ELECTROLUMINESCENT         = 0x0007;
  static const uint16_t PRODUCT_DETAIL_LASER                      = 0x0008;
  static const uint16_t PRODUCT_DETAIL_FLASHTUBE                  = 0x0009;
  /// Generally applied to fixture accessories
  static const uint16_t PRODUCT_DETAIL_COLORSCROLLER              = 0x0100;
  static const uint16_t PRODUCT_DETAIL_COLORWHEEL                 = 0x0101;
  static const uint16_t PRODUCT_DETAIL_COLORCHANGE                = 0x0102;
  static const uint16_t PRODUCT_DETAIL_IRIS_DOUSER                = 0x0103;
  static const uint16_t PRODUCT_DETAIL_DIMMING_SHUTTER            = 0x0104;
  static const uint16_t PRODUCT_DETAIL_PROFILE_SHUTTER            = 0x0105;
  static const uint16_t PRODUCT_DETAIL_BARNDOOR_SHUTTER           = 0x0106;
  static const uint16_t PRODUCT_DETAIL_EFFECTS_DISC               = 0x0107;
  static const uint16_t PRODUCT_DETAIL_GOBO_ROTATOR               = 0x0108;
  /// Generally applied to Projectors
  static const uint16_t PRODUCT_DETAIL_VIDEO                      = 0x0200;
  static const uint16_t PRODUCT_DETAIL_SLIDE                      = 0x0201;
  static const uint16_t PRODUCT_DETAIL_FILM                       = 0x0202;
  static const uint16_t PRODUCT_DETAIL_OILWHEEL                   = 0x0203;
  static const uint16_t PRODUCT_DETAIL_LCDGATE                    = 0x0204;
  /// Generally applied to Atmospheric Effects
  static const uint16_t PRODUCT_DETAIL_FOGGER_GLYCOL              = 0x0300;
  static const uint16_t PRODUCT_DETAIL_FOGGER_MINERALOIL          = 0x0301;
  static const uint16_t PRODUCT_DETAIL_FOGGER_WATER               = 0x0302;
  static const uint16_t PRODUCT_DETAIL_C02                        = 0x0303;
  static const uint16_t PRODUCT_DETAIL_LN2                        = 0x0304;
  static const uint16_t PRODUCT_DETAIL_BUBBLE                     = 0x0305;
  static const uint16_t PRODUCT_DETAIL_FLAME_PROPANE              = 0x0306;
  static const uint16_t PRODUCT_DETAIL_FLAME_OTHER                = 0x0307;
  static const uint16_t PRODUCT_DETAIL_OLEFACTORY_STIMULATOR      = 0x0308;
  static const uint16_t PRODUCT_DETAIL_SNOW                       = 0x0309;
  static const uint16_t PRODUCT_DETAIL_WATER_JET                  = 0x030a;
  static const uint16_t PRODUCT_DETAIL_WIND                       = 0x030b;
  static const uint16_t PRODUCT_DETAIL_CONFETTI                   = 0x030c;
  static const uint16_t PRODUCT_DETAIL_HAZARD                     = 0x030d;
  /// Generally applied to Dimmers/Power controllers
  static const uint16_t PRODUCT_DETAIL_PHASE_CONTROL              = 0x0400;
  static const uint16_t PRODUCT_DETAIL_REVERSE_PHASE_CONTROL      = 0x0401;
  static const uint16_t PRODUCT_DETAIL_SINE                       = 0x0402;
  static const uint16_t PRODUCT_DETAIL_PWM                        = 0x0403;
  static const uint16_t PRODUCT_DETAIL_DC                         = 0x0404;
  static const uint16_t PRODUCT_DETAIL_HFBALLAST                  = 0x0405;
  static const uint16_t PRODUCT_DETAIL_HFHV_NEONBALLAST           = 0x0406;
  static const uint16_t PRODUCT_DETAIL_HFHV_EL                    = 0x0407;
  static const uint16_t PRODUCT_DETAIL_MHR_BALLAST                = 0x0408;
  static const uint16_t PRODUCT_DETAIL_BITANGLE_MODULATION        = 0x0409;
  static const uint16_t PRODUCT_DETAIL_FREQUENCY_MODULATION       = 0x040a;
  static const uint16_t PRODUCT_DETAIL_HIGHFREQUENCY_12V          = 0x040b;
  static const uint16_t PRODUCT_DETAIL_RELAY_MECHANICAL           = 0x040c;
  static const uint16_t PRODUCT_DETAIL_RELAY_ELECTRONIC           = 0x040d;
  static const uint16_t PRODUCT_DETAIL_SWITCH_ELECTRONIC          = 0x040e;
  static const uint16_t PRODUCT_DETAIL_CONTACTOR                  = 0x040f;
  /// Generally applied to Scenic drive
  static const uint16_t PRODUCT_DETAIL_MIRRORBALL_ROTATOR         = 0x0500;
  static const uint16_t PRODUCT_DETAIL_OTHER_ROTATOR              = 0x0501;
  static const uint16_t PRODUCT_DETAIL_KABUKI_DROP                = 0x0502;
  static const uint16_t PRODUCT_DETAIL_CURTAIN                    = 0x0503;
  static const uint16_t PRODUCT_DETAIL_LINESET                    = 0x0504;
  static const uint16_t PRODUCT_DETAIL_MOTOR_CONTROL              = 0x0505;
  static const uint16_t PRODUCT_DETAIL_DAMPER_CONTROL             = 0x0506;
  /// Generally applied to Data Distribution
  static const uint16_t PRODUCT_DETAIL_SPLITTER                   = 0x0600;
  static const uint16_t PRODUCT_DETAIL_ETHERNET_NODE              = 0x0601;
  static const uint16_t PRODUCT_DETAIL_MERGE                      = 0x0602;
  static const uint16_t PRODUCT_DETAIL_DATAPATCH                  = 0x0603;
  static const uint16_t PRODUCT_DETAIL_WIRELESS_LINK              = 0x0604;
  /// Generally applied to Data Conversion and Interfaces
  static const uint16_t PRODUCT_DETAIL_PROTOCOL_CONVERTOR         = 0x0701;
  static const uint16_t PRODUCT_DETAIL_ANALOG_DEMULTIPLEX         = 0x0702;
  static const uint16_t PRODUCT_DETAIL_ANALOG_MULTIPLEX           = 0x0703;
  static const uint16_t PRODUCT_DETAIL_SWITCH_PANEL               = 0x0704;
  /// Generally applied to Audio or Video (AV) devices
  static const uint16_t PRODUCT_DETAIL_ROUTER                     = 0x0800;
  static const uint16_t PRODUCT_DETAIL_FADER                      = 0x0801;
  static const uint16_t PRODUCT_DETAIL_MIXER                      = 0x0802;
  /// Generally applied to Controllers, Backup devices and Test Equipment
  static const uint16_t PRODUCT_DETAIL_CHANGEOVER_MANUAL          = 0x0900;
  static const uint16_t PRODUCT_DETAIL_CHANGEOVER_AUTO            = 0x0901;
  static const uint16_t PRODUCT_DETAIL_TEST                       = 0x0902;
  /// Could be applied to any category
  static const uint16_t PRODUCT_DETAIL_GFI_RCD                    = 0x0A00;
  static const uint16_t PRODUCT_DETAIL_BATTERY                    = 0x0A01;
  static const uint16_t PRODUCT_DETAIL_CONTROLLABLE_BREAKER       = 0x0A02;
  /// for where the Manufacturer believes that none of the defined details apply.
  static const uint16_t PRODUCT_DETAIL_OTHER                      = 0x7FFF;

  /// Table A-7: Preset Playback Defines
  static const uint16_t PRESET_PLAYBACK_OFF   = 0x0000;
  static const uint16_t PRESET_PLAYBACK_ALL   = 0xFFFF;

  /// Table A-8: Lamp State Defines
  static const uint8_t LAMP_OFF               = 0x00;
  static const uint8_t LAMP_ON                = 0x01;
  static const uint8_t LAMP_STRIKE            = 0x02;
  static const uint8_t LAMP_STANDBY           = 0x03;
  static const uint8_t LAMP_NOT_PRESENT       = 0x04;
  static const uint8_t LAMP_ERROR             = 0x7F;

  /// Table A-9: Lamp On Mode Defines
  static const uint8_t LAMP_ON_MODE_OFF       = 0x00;
  static const uint8_t LAMP_ON_MODE_DMX       = 0x01;
  static const uint8_t LAMP_ON_MODE_ON        = 0x02;
  static const uint8_t LAMP_ON_MODE_AFTER_CAL = 0x03;

  /// Table A-10: Self Test Defines
  static const uint8_t SELF_TEST_OFF          = 0x00;
  static const uint8_t SELF_TEST_ALL          = 0xFF;

  /// Table A-11: Power State Defines
  static const uint8_t POWER_STATE_FULL_OFF   = 0x00;
  static const uint8_t POWER_STATE_SHUTDOWN   = 0x01;
  static const uint8_t POWER_STATE_STANDBY    = 0x02;
  static const uint8_t POWER_STATE_NORMAL     = 0xFF;

  /// Table A-12: Sensor Type Defines
  static const uint8_t SENS_TEMPERATURE       = 0x00;
  static const uint8_t SENS_VOLTAGE           = 0x01;
  static const uint8_t SENS_CURRENT           = 0x02;
  static const uint8_t SENS_FREQUENCY         = 0x03;
  static const uint8_t SENS_RESISTANCE        = 0x04;
  static const uint8_t SENS_POWER             = 0x05;
  static const uint8_t SENS_MASS              = 0x06;
  static const uint8_t SENS_LENGTH            = 0x07;
  static const uint8_t SENS_AREA              = 0x08;
  static const uint8_t SENS_VOLUME            = 0x09;
  static const uint8_t SENS_DENSITY           = 0x0a;
  static const uint8_t SENS_VELOCITY          = 0x0b;
  static const uint8_t SENS_ACCELERATION      = 0x0c;
  static const uint8_t SENS_FORCE             = 0x0d;
  static const uint8_t SENS_ENERGY            = 0x0e;
  static const uint8_t SENS_PRESSURE          = 0x0f;
  static const uint8_t SENS_TIME              = 0x10;
  static const uint8_t SENS_ANGLE             = 0x11;
  static const uint8_t SENS_POSITION_X        = 0x12;
  static const uint8_t SENS_POSITION_Y        = 0x13;
  static const uint8_t SENS_POSITION_Z        = 0x14;
  static const uint8_t SENS_ANGULAR_VELOCITY  = 0x15;
  static const uint8_t SENS_LUMINOUS_INTENSITY = 0x16;
  static const uint8_t SENS_LUMINOUS_FLUX     = 0x17;
  static const uint8_t SENS_ILLUMINANCE       = 0x18;
  static const uint8_t SENS_CHROMINANCE_RED   = 0x19;
  static const uint8_t SENS_CHROMINANCE_GREEN = 0x1a;
  static const uint8_t SENS_CHROMINANCE_BLUE  = 0x1b;
  static const uint8_t SENS_CONTACTS          = 0x1c;
  static const uint8_t SENS_MEMORY            = 0x1d;
  static const uint8_t SENS_ITEMS             = 0x1e;
  static const uint8_t SENS_HUMIDITY          = 0x1f;
  static const uint8_t SENS_COUNTER_16BIT     = 0x20;
  static const uint8_t SENS_OTHER             = 0x7f;

  /// Table A-13: Sensor Unit Defines
  static const uint8_t UNITS_NONE                         = 0x00;
  static const uint8_t UNITS_CENTIGRADE                   = 0x01;
  static const uint8_t UNITS_VOLTS_DC                     = 0x02;
  static const uint8_t UNITS_VOLTS_AC_PEAK                = 0x03;
  static const uint8_t UNITS_VOLTS_AC_RMS                 = 0x04;
  static const uint8_t UNITS_AMPERE_DC                    = 0x05;
  static const uint8_t UNITS_AMPERE_AC_PEAK               = 0x06;
  static const uint8_t UNITS_AMPERE_AC_RMS                = 0x07;
  static const uint8_t UNITS_HERTZ                        = 0x08;
  static const uint8_t UNITS_OHM                          = 0x09;
  static const uint8_t UNITS_WATT                         = 0x0A;
  static const uint8_t UNITS_KILOGRAM                     = 0x0B;
  static const uint8_t UNITS_METERS                       = 0x0C;
  static const uint8_t UNITS_METERS_SQUARED               = 0x0D;
  static const uint8_t UNITS_METERS_CUBED                 = 0x0E;
  static const uint8_t UNITS_KILOGRAMMES_PER_METER_CUBED  = 0x0F;
  static const uint8_t UNITS_METERS_PER_SECOND            = 0x10;
  static const uint8_t UNITS_METERS_PER_SECOND_SQUARED    = 0x11;
  static const uint8_t UNITS_NEWTON                       = 0x12;
  static const uint8_t UNITS_JOULE                        = 0x13;
  static const uint8_t UNITS_PASCAL                       = 0x14;
  static const uint8_t UNITS_SECOND                       = 0x15;
  static const uint8_t UNITS_DEGREE                       = 0x16;
  static const uint8_t UNITS_STERADIAN                    = 0x17;
  static const uint8_t UNITS_CANDELA                      = 0x18;
  static const uint8_t UNITS_LUMEN                        = 0x19;
  static const uint8_t UNITS_LUX                          = 0x1A;
  static const uint8_t UNITS_IRE                          = 0x1B;
  static const uint8_t UNITS_BYTE                         = 0x1C;

  /// Table A-14: Sensor Unit Prefix
  static const uint8_t PREFIX_NONE    = 0x00;
  static const uint8_t PREFIX_DECI    = 0x01;
  static const uint8_t PREFIX_CENTI   = 0x02;
  static const uint8_t PREFIX_MILLI   = 0x03;
  static const uint8_t PREFIX_MICRO   = 0x04;
  static const uint8_t PREFIX_NANO    = 0x05;
  static const uint8_t PREFIX_PICO    = 0x06;
  static const uint8_t PREFIX_FEMPTO  = 0x07;
  static const uint8_t PREFIX_ATTO    = 0x08;
  static const uint8_t PREFIX_ZEPTO   = 0x09;
  static const uint8_t PREFIX_YOCTO   = 0x0a;
  static const uint8_t PREFIX_DECA    = 0x11;
  static const uint8_t PREFIX_HECTO   = 0x12;
  static const uint8_t PREFIX_KILO    = 0x13;
  static const uint8_t PREFIX_MEGA    = 0x14;
  static const uint8_t PREFIX_GIGA    = 0x15;
  static const uint8_t PREFIX_TERRA   = 0x16;
  static const uint8_t PREFIX_PETA    = 0x17;
  static const uint8_t PREFIX_EXA     = 0x18;
  static const uint8_t PREFIX_ZETTA   = 0x19;
  static const uint8_t PREFIX_YOTTA   = 0x1a;

  /// Table A-15: Data Type Defines
  static const uint8_t DS_NOT_DEFINED     = 0x00;
  static const uint8_t DS_BIT_FIELD       = 0x01; //!< Data is bit packed
  static const uint8_t DS_ASCII           = 0x02; //!< Data is a string
  static const uint8_t DS_UNSIGNED_BYTE   = 0x03; //!< Data is an array of unsigned bytes
  static const uint8_t DS_SIGNED_BYTE     = 0x04; //!< Data is an array of signed bytes
  static const uint8_t DS_UNSIGNED_WORD   = 0x05; //!< Data is an array of unsigned 16-bit words
  static const uint8_t DS_SIGNED_WORD     = 0x06; //!< Data is an array of signed 16-bit words
  static const uint8_t DS_UNSIGNED_DWORD  = 0x07; //!< Data is an array of unsigned 32-bit words
  static const uint8_t DS_SIGNED_DWORD    = 0x08;

  /// Table A-16 Parameter Description Command Class
  static const uint8_t CC_GET     = 0x01; //!< PID supports GET only
  static const uint8_t CC_SET     = 0x02; //!< PID supports SET only
  static const uint8_t CC_GET_SET = 0x03;

  std::string NackReasonDescription(const uint16_t NR);
  /// Table A-17: Response NACK Reason Code
  static const uint16_t NR_UNKNOWN_PID                = 0x0000;
  static const uint16_t NR_FORMAT_ERROR               = 0x0001;
  static const uint16_t NR_HARDWARE_FAULT             = 0x0002;
  static const uint16_t NR_PROXY_REJECT               = 0x0003;
  static const uint16_t NR_WRITE_PROTECT              = 0x0004;
  static const uint16_t NR_UNSUPPORTED_COMMAND_CLASS  = 0x0005;
  static const uint16_t NR_DATA_OUT_OF_RANGE          = 0x0006;
  static const uint16_t NR_BUFFER_FULL                = 0x0007;
  static const uint16_t NR_PACKET_SIZE_UNSUPPORTED    = 0x0008;
  static const uint16_t NR_SUB_DEVICE_OUT_OF_RANGE    = 0x0009;
  static const uint16_t NR_PROXY_BUFFER_FULL          = 0x000A;

  std::string StatusMessageDescription(const uint16_t status);
  /// Appendix B: Status Message ID’s (Normative)
  /// %d  Decimal Number     -- as decimal number
  /// %x  Hexadecimal Number -- as hexadecimal number
  /// %L  Slot Label Code    -- as text description of Slot Label Code
  static const uint16_t STS_CAL_FAIL            = 0x0001; //!< “%L failed calibration”
  static const uint16_t STS_SENS_NOT_FOUND      = 0x0002; //!< “%L sensor not found”
  static const uint16_t STS_SENS_ALWAYS_ON      = 0x0003; //!< “%L sensor always on”
  static const uint16_t STS_LAMP_DOUSED         = 0x0011; //!< “Lamp doused”
  static const uint16_t STS_LAMP_STRIKE         = 0x0012; //!< “Lamp failed to strike”
  static const uint16_t STS_OVERTEMP            = 0x0021; //!< “Sensor %d over temp at %d degrees C”
  static const uint16_t STS_UNDERTEMP           = 0x0022; //!< “Sensor %d under temp at %d degrees C”
  static const uint16_t STS_SENS_OUT_RANGE      = 0x0023; //!< “Sensor %d out of range”
  static const uint16_t STS_OVERVOLTAGE_PHASE   = 0x0031; //!< “Phase %d over voltage at %d V.”
  static const uint16_t STS_UNDERVOLTAGE_PHASE  = 0x0032; //!< “Phase %d under voltage at %d V.”
  static const uint16_t STS_OVERCURRENT         = 0x0033; //!< “Phase %d over current at %d A.”
  static const uint16_t STS_UNDERCURRENT        = 0x0034; //!< “Phase %d under current at %d A.”
  static const uint16_t STS_PHASE               = 0x0035; //!< “Phase %d is at %d degrees”
  static const uint16_t STS_PHASE_ERROR         = 0x0036; //!< “Phase %d Error.”
  static const uint16_t STS_AMPS                = 0x0037; //!< “%d Amps”
  static const uint16_t STS_VOLTS               = 0x0038; //!< “%d Volts”
  static const uint16_t STS_DIMSLOT_OCCUPIED    = 0x0041; //!< “No Dimmer”
  static const uint16_t STS_BREAKER_TRIP        = 0x0042; //!< “Tripped Breaker”
  static const uint16_t STS_WATTS               = 0x0043; //!< “%d Watts”
  static const uint16_t STS_DIM_FAILURE         = 0x0044; //!< “Dimmer Failure”
  static const uint16_t STS_DIM_PANIC           = 0x0045; //!< “Panic Mode”
  static const uint16_t STS_READY               = 0x0050; //!< “%L ready”
  static const uint16_t STS_NOT_READY           = 0x0051; //!< “%L not ready”
  static const uint16_t STS_LOW_FLUID           = 0x0052; //!< “%L low fluid”


  /// Appendix C: Slot Info (Normative)

  /// Table C-1: Slot Type
  static const uint8_t ST_PRIMARY           = 0x00; //!< Slot directly controls parameter (represents Coarse for 16-bit parameters)
  static const uint8_t ST_SEC_FINE          = 0x01; //!< Fine, for 16-bit parameters
  static const uint8_t ST_SEC_TIMING        = 0x02; //!< Slot sets timing value for associated parameter
  static const uint8_t ST_SEC_SPEED         = 0x03; //!< Slot sets speed/velocity for associated parameter
  static const uint8_t ST_SEC_CONTROL       = 0x04; //!< Slot provides control/mode info for parameter
  static const uint8_t ST_SEC_INDEX         = 0x05; //!< Slot sets index position for associated parameter
  static const uint8_t ST_SEC_ROTATION      = 0x06; //!< Slot sets rotation speed for associated parameter
  static const uint8_t ST_SEC_INDEX_ROTATE  = 0x07; //!< Combined index/rotation control
  static const uint8_t ST_SEC_UNDEFINED     = 0xff; //!< Undefined secondary type

  /// Table C-2: Slot ID Definitions
  /// Intensity Functions
  static const uint16_t SD_INTENSITY          = 0x0001;
  static const uint16_t SD_INTENSITY_MASTER   = 0x0002;
  /// Movement Functions
  static const uint16_t SD_PAN                = 0x0101;
  static const uint16_t SD_TILT               = 0x0102;
  /// Color Functions
  static const uint16_t SD_COLOR_WHEEL        = 0x0201;
  static const uint16_t SD_COLOR_SUB_CYAN     = 0x0202;
  static const uint16_t SD_COLOR_SUB_YELLOW   = 0x0203;
  static const uint16_t SD_COLOR_SUB_MAGENTA  = 0x0204;
  static const uint16_t SD_COLOR_ADD_RED      = 0x0205;
  static const uint16_t SD_COLOR_ADD_GREEN    = 0x0206;
  static const uint16_t SD_COLOR_ADD_BLUE     = 0x0207;
  static const uint16_t SD_COLOR_CORRECTION   = 0x0208;
  static const uint16_t SD_COLOR_SCROLL       = 0x0209;
  static const uint16_t SD_COLOR_SEMAPHORE    = 0x0210;
  /// Image Functions
  static const uint16_t SD_STATIC_GOBO_WHEEL  = 0x0301;
  static const uint16_t SD_ROTO_GOBO_WHEEL    = 0x0302;
  static const uint16_t SD_PRISM_WHEEL        = 0x0303;
  static const uint16_t SD_EFFECTS_WHEEL      = 0x0304;
  /// Beam Functions
  static const uint16_t SD_BEAM_SIZE_IRIS     = 0x0401;
  static const uint16_t SD_EDGE               = 0x0402;
  static const uint16_t SD_FROST              = 0x0403;
  static const uint16_t SD_STROBE             = 0x0404;
  static const uint16_t SD_ZOOM               = 0x0405;
  static const uint16_t SD_FRAMING_SHUTTER    = 0x0406;
  static const uint16_t SD_SHUTTER_ROTATE     = 0x0407;
  static const uint16_t SD_DOUSER             = 0x0408;
  static const uint16_t SD_BARN_DOOR          = 0x0409;
  /// Control Functions
  static const uint16_t SD_LAMP_CONTROL       = 0x0501;
  static const uint16_t SD_FIXTURE_CONTROL    = 0x0502;
  static const uint16_t SD_FIXTURE_SPEED      = 0x0503;
  static const uint16_t SD_MACRO              = 0x0504;
  static const uint16_t SD_UNDEFINED          = 0xffff;

} // namespace RDM
