#include <EthernetServer.h>
#include <Dhcp.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <Dns.h>

#include <DHT.h>

#include <OneWire.h>
#include <DallasTemperature.h>
#include <Ethernet.h> //Load Ethernet Library
#include <EthernetUdp.h> //Load UDP Library
#include <SPI.h> //Load the SPI Library

#define DHTTYPE DHT22

#define sump_low 2
#define sump_high 3//
#define biofilter_low A5
#define biofilter_high 5//
#define DHTambient 6
#define DHTdome 7
#define ONE_WIRE_BUS 8
#define sumpWarn 9
#define pump A0//
#define blower A1//
#define uv A2//
#define bioPump A3//
#define growoutWarn A4
//#define power A5


OneWire oneWire(ONE_WIRE_BUS);
DHT dht_ambient(DHTambient, DHTTYPE);
DHT dht_dome(DHTdome, DHTTYPE);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

byte mac[] = { 0x90, 0xA1, 0xDA, 0x00, 0x59, 0x09 };

byte gateway[] = { 192, 168, 0, 254 };
byte subnet[] = { 255, 255, 255, 0 };
EthernetServer server(80);
String readString;



int buttonState1;             // the current reading from the input pin
int lastButtonState1 = HIGH;   // the previous reading from the input pin
int buttonState2;             // the current reading from the input pin
int lastButtonState2 = HIGH;
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime1 = 0;
long lastDebounceTime2 = 0; // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers



unsigned long blowerOntime = 0;
unsigned long blowerOfftime = 0;
long blowerOninterval = 3000000;
long blowerOffinterval = 600000;
//long blowerOffinterval = 5000;
//long blowerOninterval = 10000;


byte blower_state = 1;
byte depthstatusSump = 1;
byte depthstatusBiofilter = 1;





void setup() {
  Serial.begin(19200);
  Ethernet.hostName("BREEDING");

  Serial.println("Hi Chris");

  pinMode(DHTambient, INPUT);
  pinMode(DHTdome, INPUT);
  pinMode(ONE_WIRE_BUS, INPUT);
  pinMode(sumpWarn, INPUT_PULLUP);
  pinMode(growoutWarn, INPUT_PULLUP);

  pinMode(pump, OUTPUT);
  pinMode(blower, OUTPUT);
  pinMode(uv, OUTPUT);
  pinMode(bioPump, OUTPUT);
  pinMode(sump_low, INPUT_PULLUP);
  pinMode(sump_high, INPUT_PULLUP);
  pinMode (biofilter_low, INPUT_PULLUP);
  pinMode (biofilter_high, INPUT_PULLUP);
//  pinMode (power, INPUT_PULLUP);
  sensors.begin();
  dht_dome.begin();
  dht_ambient.begin();

  Ethernet.begin(mac); //Initialize Ethernet
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  Serial.println(Ethernet.getHostName());




}

// how much serial data we expect before a newline
const unsigned int MAX_INPUT = 100;
// the maximum length of paramters we accept
const int MAX_PARAM = 15;


// Example GET line: GET /?foo=bar HTTP/1.1
void processGet (const char * data)
{
  // find where the parameters start
  const char * paramsPos = strchr (data, '?');
  if (paramsPos == NULL)
    return;  // no parameters
  // find the trailing space
  const char * spacePos = strchr (paramsPos, ' ');
  if (spacePos == NULL)
    return;  // no space found
  // work out how long the parameters are
  int paramLength = spacePos - paramsPos - 1;
  // see if too long
  if (paramLength >= MAX_PARAM)
    return;  // too long for us
  // copy parameters into a buffer
  char param [MAX_PARAM];
  memcpy (param, paramsPos + 1, paramLength);  // skip the "?"
  param [paramLength] = 0;  // null terminator

  // do things depending on argument (GET parameters)

  if (strcmp (param, "blowerOn") == 0)
  {
    Serial.println (F("Activating blower"));
    blower_state = 1;
  } else if (strcmp (param, "blowerOff") == 0)
  {
    Serial.println (F("Deactivating blower"));
    blower_state = 0;
  }
  if (strcmp (param, "sumpPumpOn") == 0)
  {
    Serial.println (F("activating pump"));
    depthstatusSump = 1;
  } else if (strcmp (param, "sumpPumpOff") == 0)
  {
    Serial.println (F("Deactivating pump"));
    depthstatusSump = 0;
  } 
  if (strcmp (param, "bioPumpOn") == 0)
  {
    Serial.println (F("activating pump"));
    depthstatusBiofilter = 1;
  } else if (strcmp (param, "bioPumpOff") == 0)
  {
    Serial.println (F("Deactivating pump"));
    depthstatusBiofilter = 0;
  }
}  // end of processGet

// here to process incoming serial data after a terminator received
void processData (const char * data)
{
  Serial.println (data);
  if (strlen (data) < 4)
    return;

  if (memcmp (data, "GET ", 4) == 0)
    processGet (&data [4]);
}  // end of processData

bool processIncomingByte (const byte inByte)
{
  static char input_line [MAX_INPUT];
  static unsigned int input_pos = 0;
  switch (inByte)
  {
    case '\n':   // end of text
      input_line [input_pos] = 0;  // terminating null byte
      if (input_pos == 0)
        return true;   // got blank line
      // terminator reached! process input_line here ...
      processData (input_line);
      // reset buffer for next time
      input_pos = 0;
      break;

    case '\r':   // discard carriage return
      break;

    default:
      // keep adding if not full ... allow for terminating null byte
      if (input_pos < (MAX_INPUT - 1))
        input_line [input_pos++] = inByte;
      break;
  }  // end of switch
  return false;    // don't have a blank line yet
} // end of processIncomingByte


void loop()
{


  //debug();
  //delay(500);
//Serial.println(digitalRead(sump_low));  //Serial.println(blowerOntime);
  //Serial.println(blowerOfftime);


  if (digitalRead(sump_low) == LOW)
  {
    depthstatusSump = 0;
  }
  if (digitalRead(sump_high) == HIGH)
  {
    depthstatusSump = 1;
  }

  if (depthstatusSump == 1)
  {
    digitalWrite(pump, HIGH);
    digitalWrite(uv, HIGH);
  } else if (depthstatusSump == 0)
  {
    digitalWrite(pump, LOW);
    digitalWrite(uv, LOW);
  }
  if (digitalRead(biofilter_low) == LOW)
  {
    depthstatusBiofilter = 0;
  }
  if (digitalRead(biofilter_high) == HIGH)
  {
    depthstatusBiofilter = 1;
  }
  if (depthstatusBiofilter == 1)
  {
    digitalWrite(bioPump, HIGH);

  } else if (depthstatusBiofilter == 0)
  {
    digitalWrite(bioPump, LOW);

  }


  if (blower_state == 1)
  {
    blowerOfftime = millis();
  } else if (blower_state == 0)
  {
    blowerOntime = millis();
  }

  if (millis() - blowerOntime > blowerOninterval)
  {
    blower_state = 0;
    //Serial.println("blower off");
    //Serial.println(blowerOntime);
  } else if (millis() - blowerOfftime > blowerOffinterval)
  {
    blower_state = 1;
    //Serial.println("blower on");
    //Serial.println(blowerOfftime);
  }

  if (blower_state == 1)
  {
    digitalWrite(blower, HIGH);
  } else if (blower_state == 0)
  {
    digitalWrite(blower, LOW);
  }
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client)
  {
    sensors.requestTemperatures(); // Send the command to get temperatures
    
    float sumptemp = sensors.getTempCByIndex(0);
    float tanktemp = sensors.getTempCByIndex(1);
    float domeH = dht_dome.readHumidity();
    float domeAirtemp = dht_dome.readTemperature();
    float ambientH = dht_ambient.readHumidity();
    float ambientAirtemp = dht_ambient.readTemperature();

    Serial.println(F("Client connected"));
    // an http request ends with a blank line
    boolean done = false;
    while (client.connected() && !done)
    {
      while (client.available () > 0 && !done)
        done = processIncomingByte (client.read ());
    }  // end of while client connected

    // send a standard http response header

    client.print(sumptemp);
    client.print(",");
    client.print(tanktemp);
    client.print(",");
    client.print(domeAirtemp);
    client.print(",");
    client.print(domeH);
    client.print(",");
    client.print(ambientAirtemp);
    client.print(",");
    client.print(ambientH);
    client.print(",");
    client.print(digitalRead(pump));
    client.print(",");
    client.print(digitalRead(blower));
    client.print(",");
    client.print(digitalRead(sumpWarn));
    client.print(",");
    client.print(digitalRead(growoutWarn));

    // give the web browser time to receive the data
    delay(10);
    // close the connection:
    client.stop();
    Serial.println(F("Client disconnected"));
  }  // end of got a new client



}

