#include <Arduino.h>
#include "printHelpers.h"
#include <LiquidCrystal_I2C.h>

//////////////////////////////////////////////////
// Functions forward declaration(s)
//////////////////////////////////////////////////
void reverseCode(char* const lsbString, char* const msbString);
uint64_t hex2dec(const char* hexString); 

//////////////////////////////////////////////////
// Definitions
//////////////////////////////////////////////////

// Convert hexadecimal chars to Integer 
// A-F must be uppercase
#define hex2int(C) \
(((C) >= '0' && (C) <= '9' ) ? C-'0' : ((C) >= 'A' && (C) <= 'F') ? C -'A' + 10 : -1)

//////////////////////////////////////////////////
// Global constants and variables
//////////////////////////////////////////////////
LiquidCrystal_I2C lcd(0x27,16,2);  // A4 SDA, A5 SCL

//////////////////////////////////////////////////////////////////////////////
/// @brief Setup program parameters
/// 
//////////////////////////////////////////////////////////////////////////////
void setup() {
  char input[]="171A9253A3";
  //char input[]="FFFF";
  char msbInput[11];
  
  Serial.begin(74880);
  lcd.init();                 // initialize the lcd 
  lcd.backlight();

  reverseCode(input,msbInput);
  lcd.setCursor ( 0, 0 );
  lcd.print ("Marken-ID:");
  lcd.setCursor ( 0, 1 );
  lcd.print(print64(hex2dec(msbInput)));

  //Serial.println(print64(hex2dec(msbInput)));
}

//////////////////////////////////////////////////////////////////////////////
/// @brief Main Loop
///
//////////////////////////////////////////////////////////////////////////////
void loop() {
}

//////////////////////////////////////////////////////////////////////////////
/// @brief The hex value string is inverted. The byte order is swapped from right to left.
///        E.g. the string "A31B27" becomes "72B13A"
///
/// @param lsbString String to be inverted.
/// @param msbString Inverted string.
//////////////////////////////////////////////////////////////////////////////

void reverseCode(char* const lsbString, char* const msbString) {
  int len = strlen(lsbString);
  for(int i=len-1, y=0; i > -1; --i, ++y){
    msbString[y]=lsbString[i];
  }
  msbString[len]='\0';
}

//////////////////////////////////////////////////////////////////////////////
/// @brief The hex value string is converted into a decimal number.
///        E.g. FFFF becomes 65535
///
/// @param hexstring  Character string that is to be converted
/// @return uint64_t  Decimal value
//////////////////////////////////////////////////////////////////////////////

uint64_t hex2dec(const char* hexString) {
  static uint64_t res;
  static uint64_t tmp;
  int len = strlen(hexString);
  int digit;

  res=0;
  for(int i=0,y=len-1; i < len ; i++,y--) {
    digit = hex2int(hexString[i]);
    tmp = ((uint64_t) 1 << (y*4));
    tmp *= digit;
    res += tmp;
  }
  return res;
}