#include <SPI.h>;
#include <mcp2515.h>;
#include "MeyCan.h";
#include "MeyRule.h";

#define PIN8 8
#define PIN9 9

const int16_t SW_FLUR = 0XD238;
const int16_t SW_ANBAU = 0x87A9;
const int16_t SW_WOHNZIMMER = 0x87CA;
const int16_t SW_TERRASSE = 0x618A;


const int16_t UP_WOHNZIMMER_TUER = 0x051F;  // [X X]
const int16_t UP_WOHNZIMMER_TERASSE = 0x05df;
const int16_t UP_FLUR_EINGANG = 0x0769;  // [X]
const int16_t UP_BUERO = 0x1177;
const int16_t UP_FLUR_BUERO = 0x05A1;  // [X]
const int16_t UP_FLUR_KUECHE = 0x01EF;
const int16_t UP_KINDERZIMMER = 0x0196;  // [X X]
const int16_t UP_FLUR_ELTERN = 0x0632;
const int16_t UP_ELTERN = 0x08AE;
const int16_t UP_KUECHE_FLUR = 0x07F5;  // [X]
const int16_t UP_KUECHE_BAD = 0x0585;   // [X X]

struct can_frame incomingCanFrame;

/*
Software matching Hardware of meycan v8.1
*/
void setup() {
  SPI.begin();


  AddToggle(UP_WOHNZIMMER_TUER, 1, SW_WOHNZIMMER, 5);
  AddToggle(UP_WOHNZIMMER_TUER, 1, SW_WOHNZIMMER, 6);
  AddSimple(UP_WOHNZIMMER_TUER, 2, SW_WOHNZIMMER, 7);
  AddSimple(UP_WOHNZIMMER_TUER, 3, SW_WOHNZIMMER, 8);


  AddToggle(UP_KINDERZIMMER, 3, SW_FLUR, 6);
  AddToggle(UP_KINDERZIMMER, 3, SW_WOHNZIMMER, 2);
  AddToggle(UP_KINDERZIMMER, 2, SW_FLUR, 3);
  AddSimple(UP_KINDERZIMMER, 4, SW_FLUR, 4);
  AddSimple(UP_KINDERZIMMER, 1, SW_FLUR, 5);


  AddToggle(UP_FLUR_EINGANG, 1, SW_FLUR, 1);
  AddToggle(UP_FLUR_EINGANG, 2, SW_FLUR, 6);
  AddToggle(UP_FLUR_EINGANG, 2, SW_WOHNZIMMER, 2);

  AddToggle(UP_ELTERN, 1, SW_FLUR, 2);

  AddToggle(UP_BUERO, 1, SW_WOHNZIMMER, 3);

  AddToggle(UP_FLUR_BUERO, 1, SW_FLUR, 6);
  AddToggle(UP_FLUR_BUERO, 1, SW_WOHNZIMMER, 2);

  AddToggle (UP_WOHNZIMMER_TERASSE, 1, SW_WOHNZIMMER, 7);  // Licht 1 von Terassenschalter
  AddToggle (UP_WOHNZIMMER_TERASSE, 2, SW_WOHNZIMMER, 8);  // Licht
  AddToggle (UP_WOHNZIMMER_TERASSE, 3, SW_TERRASSE, 2);  // Pergola

  /// RULE FOR SWITCH WOHNZIMMER (BOTH) OF TERASSE
  // AddSimple (UP_WOHNZIMMER_TERASSE, 3, SW_WOHNZIMMER, 5);  // Eingangstür Flur Licht 2
  // AddSimple (UP_WOHNZIMMER_TERASSE, 3, SW_WOHNZIMMER, 6);  // Eingangstür Flur Licht 2


  AddToggle(UP_KUECHE_FLUR, 1, SW_ANBAU, 3);
  AddToggle(UP_KUECHE_FLUR, 2, SW_ANBAU, 2);
  AddToggle(UP_KUECHE_BAD, 1, SW_ANBAU, 3);
  AddToggle(UP_KUECHE_BAD, 2, SW_ANBAU, 1);
  AddToggle(UP_KUECHE_BAD, 3, SW_ANBAU, 4);

  AddToggle(UP_FLUR_KUECHE, 1, SW_FLUR, 6);
  AddToggle(UP_FLUR_KUECHE, 1, SW_WOHNZIMMER, 2);


  SetMeyPin(1, PIN3);
  SetMeyPin(2, PIN5);
  SetMeyPin(3, PIN7);
  SetMeyPin(4, PIN9);
  SetMeyPin(5, PIN8);
  SetMeyPin(6, PIN6);
  SetMeyPin(7, PIN4);
  SetMeyPin(8, PIN2);

  SetDevicedId(0x87, 0xCA);
  AddLocalPinChangedHandler(SetLocalPinStateAdapter);

  AddCanInterface(PIN_A0);
  AddCanInterface(PIN_A1);
  AddCanInterface(PIN_A2);
  AddCanInterface(PIN_A3);

  SetupMeyCan(8, 0, 2);
}

void loop() {
  ForEachCanInterface(CheckCanInterface);
}


void SetLocalPinStateAdapter(can_frame *frame)
{
  SetLocalPinState(frame);
}

void CheckCanInterface(MCP2515 *interface) {
  if (interface->readMessage(&incomingCanFrame) == MCP2515::ERROR_OK) {
    HandleFrame(&incomingCanFrame, interface);
    HandleRules(&incomingCanFrame);
  }
}
