#ifndef __config
#define __config

#include <stdint.h>


class Config
{
  public:
    /*

      Buttons

    */
    static const uint8_t ButtonPinTop = 3;
    static const uint8_t ButtonPinMiddle = 5;
    static const uint8_t ButtonPinBottom = 6;


    /*

      Display
        Settings for an ST7789 based 240x240 pixel LCD.

        Note that all screen class implementations are only tested against
        this resolution, changing it may have unexpected results.
    */
    static const uint8_t DisplayWidth = 240;
    static const uint8_t DisplayHeight = 240;
    static const uint8_t DisplayRotation = 2;


    // Control pins. Data is sent over the hardware SPI pins.
    static const uint8_t DisplayPinCS = 10;
    static const uint8_t DisplayPinRST = 9;
    static const uint8_t DisplayPinDC = 8;
    static const uint8_t DisplayPinBL = 7;


    static const uint16_t DisplayIdleTime = 10000;
    static const uint16_t DisplayRefreshRate = 1000;


    /*
      Height sensor
        Settings for a VL53L0X time-of-flight sensor.

    */
    // Note that this must correspond to the default address of the module,
    // the initialisation code skips reassigning the address to save calls.
    static const uint8_t HeightSensorI2CAddress = 0x29;

    static const uint32_t HeightSensorBudget = 200000;


    // Values above this will be disregarded as invalid
    static const uint16_t HeightMeasurementMax = 1500;

    // How much the measurements can change to still be considered "stable"
    static const uint8_t HeightMeasurementDeltaStable = 10;
    static const uint8_t HeightMeasurementDeltaStableCount = 3;
    static const uint16_t HeightMeasurementDeltaStableMoveTimeout = 2000;

    // How far in advance to stop the motor
    static const uint8_t HeightMeasurementDeltaStop = 0;

    // How far off we can be from the target height to still be considered on target
    static const uint8_t HeightMeasurementDeltaOnTarget = 15;

    // How long we allow invalid measurements until the move operation is aborted
    static const uint16_t HeightMeasurementAbortTimeout = 500;



    /*

      Motor driver
        Settings for a Polulu G2 driver board.

    */
    static const uint8_t MotorPinPWM = 14;
    static const uint8_t MotorPinDirection = 15;
    static const uint8_t MotorPinSleep = 16;
    static const uint8_t MotorPinCurrentSensing = 17;

    /*

      Colors

    */
    // A useful RGB565 calculator: http://www.rinkydinkelectronics.com/calc_rgb565.php
    #define ColorBlack 0x0000
    #define ColorWhite 0xFFFF
    #define ColorYellow 0xFFE0
    #define ColorRed 0xF800
    #define ColorGreen 0x07E0

    #define ColorLightGray 0x9492
    #define ColorDarkGray 0x528A
    #define ColorDarkerGray 0x2965

    #define ColorStopRed 0xF9A6
    #define ColorDarkRed 0x4861
    #define ColorSoftGreen 0x2BE7
    #define ColorSoftBlue 0x3376
    #define ColorDarkBlue 0x0907

    #define ColorOrange 0xF443


    // Init sequence
    static const uint16_t ColorInitSeqBackground = ColorBlack;
    static const uint16_t ColorInitSeqTitle = ColorYellow;
    static const uint16_t ColorInitSeqItems = ColorWhite;
    static const uint16_t ColorInitSeqSuccess = ColorGreen;
    static const uint16_t ColorInitSeqError = ColorRed;


    // Home
    static const uint16_t ColorHomeBackground = ColorBlack;

    static const uint16_t ColorHomeMenuText = ColorWhite;
    static const uint16_t ColorHomeMenuArrow = ColorDarkGray;

    static const uint16_t ColorNonPresetText = ColorLightGray;
    static const uint16_t ColorNonPresetBackground = ColorBlack;

    static const uint16_t ColorPresetText = ColorLightGray;
    static const uint16_t ColorPresetBackground = ColorDarkerGray;
    static const uint16_t ColorPresetArrow = ColorDarkGray;

    static const uint16_t ColorPresetSelectedText = ColorWhite;
    static const uint16_t ColorPresetSelectedBackground = ColorSoftGreen;


    // Move
    static const uint16_t ColorMoveBackground = ColorBlack;

    static const uint16_t ColorMoveArrow = ColorDarkGray;
    static const uint16_t ColorMoveTarget = ColorWhite;
    static const uint16_t ColorMoveCurrent = ColorWhite;
    static const uint16_t ColorMoveStop = ColorStopRed;


    // Move error / overcurrent
    static const uint16_t ColorErrorBackground = ColorDarkRed;
    static const uint16_t ColorErrorText = ColorStopRed;


    // Menu
    static const uint16_t ColorMenuHeaderText = ColorWhite;
    static const uint16_t ColorMenuHeaderBackground = ColorSoftBlue;

    static const uint16_t ColorMenuSelectedText = ColorWhite;
    static const uint16_t ColorMenuSelectedBackground = ColorDarkBlue;

    static const uint16_t ColorCalibrateBackground = ColorBlack;
    static const uint16_t ColorCalibrateIndicators = ColorWhite;
    static const uint16_t ColorCalibrateValue = ColorWhite;
    static const uint16_t ColorCalibrateInvalidValue = ColorOrange;
    static const uint16_t ColorCalibrateDigitMarker = ColorWhite;
};

#endif