/***************************************************
Smart Lights
 ****************************************************/
#include <EEPROM.h>
#include <YunClient.h>
#include <YunServer.h>
#include <Adafruit_NeoPixel.h>

// Neo pixel configuration
#define     PIXEL_PIN1              4    // The pin which is connected to the neo pixel strip input.
#define     PIXEL_PIN2              8    // The pin which is connected to the neo pixel strip input.
#define     PIXEL_COUNT            120   // The number of neo pixels in the strip.
Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN2, NEO_GRB + NEO_KHZ800);

char UserRed_Str[ ] = "UserRed";
char UserGreen_Str[ ] = "UserGreen";
char UserBlue_Str[ ] = "UserBlue";
char NightRed_Str[ ] = "NightRed";
char NightGreen_Str[ ] = "NightGreen";
char NightBlue_Str[ ] = "NightBlue";
char AlarmRed_Str[ ] = "AlarmRed";
char AlarmGreen_Str[ ] = "AlarmGreen";
char AlarmBlue_Str[ ] = "AlarmBlue";
char Button1_Str[ ] = "Button1";
char Button2_Str[ ] = "Button2";
char DayTime_SOD_Str[ ] = "DayTime_SOD";
char NightTime_SOD_Str[ ] = "NightTime_SOD";
char MaxDayUserOnTime_SOD_Str[ ] = "MaxDayUserOnTime_SOD";
char MaxNightUserOnTime_SOD_Str[ ] = "MaxNightUserOnTime_SOD";
char UserFadeUp_s_Str[ ] = "UserFadeUp_s";
char AutoFadeDown_s_Str[ ] = "AutoFadeDown_s";
char WeekdayAlarm_SOD_Str[ ] = "WeekdayAlarm_SOD";
char WeekendAlarm_SOD_Str[ ] = "WeekendAlarm_SOD";
char AlarmFadeUpTime_s_Str[ ] = "AlarmFadeUpTime_s";
char AlarmAutoOffTime_s_Str[ ] = "AlarmAutoOffTime_s";
char DayModeMaxBrightness_Percent_Str[ ] = "DayModeMaxBrightness_Percent";
char NightModeMaxBrightness_Percent_Str[ ] = "NightModeMaxBrightness_Percent";
char NightModeMinBrightness_Percent_Str[ ] = "NightModeMinBrightness_Percent";
char IsAlarm1On_Str[ ] = "IsAlarm1On";
char IsAlarm2On_Str[ ] = "IsAlarm2On";
char Diag_Str[ ] = "Diag";
char PartyMode_Str[ ] = "PartyMode";
char Invalid_Str[ ] = "Invalid Command";
char Tab_Str[ ] = "\t";
char colon_Str[]= ": ";
char DayOfWeek_Str[] = "Day of Week";
char Network_SOD_Str[] = "Network_SOD";
char Current_SOD_Str[] = "Current_SOD";

int EEPROMLoadedCount = 0;
byte SW1StatePin = 5;
byte SW1LEDPin = 6;
byte SW2StatePin = 9;
byte SW2LEDPin = 10;

byte SW1State = 0;
byte LastSW1State = 0;
byte SW2State = 0;
byte LastSW2State = 0;
byte ProgramDiagnostics;
// Setup the Base Variables
enum LightState_T{DAYMODE = 0, NIGHTMODE, ALARMON, ALARMENABLING, ALARMDISABLING, ALARMOFF, USEROFF, USERFADEUP, USERON, USERFADEDOWN, AUTOFADEDOWN, CURRENTTIME};

// Color scheme definitions.
struct Color_S {
  uint8_t red;
  uint8_t green;
  uint8_t blue;
  Color_S(uint8_t red, uint8_t green, uint8_t blue): red(red), green(green), blue(blue) {}
  Color_S(): red(0), green(0), blue(0) {}
};
Color_S UserColor;
Color_S NightLightColor;
Color_S AlarmColor;

// Create an instance of the YunServer to listen for HTTP requests.
YunServer server;

// Dynamic Time Parameters
int DayofWeek = 0;
unsigned long Network_SOD = 0;
unsigned long CurrentTime_SOD = 0;
unsigned short UserOnTime_s = 15;
unsigned long Fade0_L1_ms;
unsigned long Fade0_L2_ms;
unsigned long NetworkUpdateTime_ms = 0;
unsigned short FadeIncrement_L1_ms = 0;
unsigned short FadeIncrement_L2_ms = 0;
int AlarmOnIndex = 0;
int DateSet = 0;
unsigned long  NumberOfAlarmIndecies = PIXEL_COUNT/2;

// User Configurable Time Parameters
unsigned long DayTime_SOD;
unsigned long NightTime_SOD;
unsigned long MaxDayUserOnTime_SOD;
unsigned long MaxNightUserOnTime_SOD;
unsigned long UserFadeUp_s;
unsigned long AutoFadeDown_s;
unsigned long WeekdayAlarm_SOD;
unsigned long WeekendAlarm_SOD;
unsigned long AlarmFadeUpTime_s;
unsigned long AlarmAutoOffTime_s;

// User Configurable Brightness Parameters
int DayModeMaxBrightness_Percent;
int NightModeMaxBrightness_Percent;
int NightModeMinBrightness_Percent;
int PartyMode = 0;

// Dynamic Brightness Parameters
int MaxUserBrightness_Percent = 0;
int MinUserBrightness_Percent = 0;
int CurrentUserBrightness_L1_Percent = 0;
int CurrentUserBrightness_L2_Percent = 0;

int IsAlarm1On = 1;
int IsAlarm2On = 0;

LightState_T CurrentAlarmState = ALARMOFF;
LightState_T CurrentDNState = DAYMODE;
LightState_T CurrentUserState_L1 = USEROFF;
LightState_T CurrentUserState_L2 = USEROFF;

Process date;                 // process used to get the date

// SETUP!
void setup() {
  Serial.begin(115200);

  // Initialize Yun bridge library.
  Bridge.begin();
  //Load all the Parameters from EEprom
  LoadEepromValues();
  
  // Initialize the neo pixel strip.
  strip1.begin();
  strip1.show();
  
  pinMode(SW1StatePin, INPUT); // Switch State
  pinMode(SW1LEDPin, OUTPUT); // Backlit Switch LED 
  
  // Light 2 Parameters
  strip2.begin();
  strip2.show();
  pinMode(SW2StatePin, INPUT); // Switch State
  pinMode(SW2LEDPin, OUTPUT);  // Backlit Switch LED 

  // Connect the server library to the Linio OS and start listening for connections.
  server.begin();
  //server.listenOnLocalhost();
    // run an initial date process. Should return:
  // hh:mm:ss :
  if (!date.running())  {
    date.begin("date");
    date.addParameter("+%T,%u");
    date.run();
  }
}


void HandleSwitches(){
//  if (EEPROMLoadedCount < 10)
//  {
//    LoadEepromValues();
//    EEPROMLoadedCount ++;
//  }
   if (digitalRead(SW1StatePin) && LastSW1State == 0)
    {
      SW1State = 1;
      LastSW1State = 1;
    }
    else if(!digitalRead(SW1StatePin) && LastSW1State == 1)
    {
      SW1State = 0;
      LastSW1State = 0;
    }
    if (digitalRead(SW2StatePin) && LastSW2State == 0)
    {
      SW2State = 1;
      LastSW2State = SW2State;
    }
    else if(!digitalRead(SW2StatePin) && LastSW2State == 1)
    {
      SW2State = 0;
      LastSW2State = SW2State;
    }
}
void loop() 
{  
    HandleSwitches();
    HandleWebCmds();
    ManageTime();  
    CheckMaxMinUserBrightness();
    
    ManageUserLightSource(1);
    ManageUserLightSource(2);
    CheckAlarms();
    DisplayUserLightSource();
    if(ProgramDiagnostics){DisplayClock();}

      strip1.show(); 
      strip2.show();
    //Reset Button State for Next Loop
    SW1State = 0;
    SW2State = 0;

}
