#include <IRremote.h>
#include "LCDBank.h"
// define your setup
#define totalLCDs 8
// define input pins
const int irPin = 2;
// define the lcd pins
const int lcdDataPin = 4;
const int lcdShiftPin = 5;
const int lcdLatchPin = 6;
// create LCDBank object with the data pins
LCDBank lcdBank(lcdDataPin, lcdShiftPin, lcdLatchPin);
// create IRrecv object for remote
IRrecv ir(irPin);
void setup() {
  // Initialize the LCDBank with the number of displays
  lcdBank.init(totalLCDs);
  // Start the IR receiver
  ir.enableIRIn();
}
// *** TEST PROGRAM FOR LCDBank class ***
void loop() {
  // set up the displays
  lcdBank.all();
  lcdBank.clear();
  lcdBank.pos(0, 0);
  lcdBank.send("LCD Remote Test");
  lcdBank.pos(0, 1);
  for (int i = 0; i < lcdBank.total(); i++)
  {
    lcdBank.set(i);
    lcdBank.sendI(i);
    lcdBank.send(": ");
  }
  bool running = true;
  while (running)
  {
    if (ir.decode())
    {
      running = remoteCommand(ir.decodedIRData.command);
      ir.resume();
    }
  }
}
// Test Program Functions
bool remoteCommand(byte command)
{
  switch (command)
  {
    case 104:     // 0
      lcdBank.set(0);
      lcdBank.send("0");
      break;
    case 48:      // 1
      lcdBank.set(1);
      lcdBank.send("1");
      break;
    case 24:      // 2
      lcdBank.set(2);
      lcdBank.send("2");
      break;
    case 122:     // 3
      lcdBank.set(3);
      lcdBank.send("3");
      break;
    case 16:      // 4
      lcdBank.set(4);
      lcdBank.send("4");
      break;
    case 56:      // 5
      lcdBank.set(5);
      lcdBank.send("5");
      break;
    case 90:      // 6
      lcdBank.set(6);
      lcdBank.send("6");
      break;
    case 66:      // 7
      lcdBank.set(7);
      lcdBank.send("7");
      break;
    case 74:      // 8
      lcdBank.all();
      lcdBank.send("8");
      break;
    case 162:     // POWER
      // reset program
      return false;
      break;
    case 224:     // PREV
      // clear LCDs 7-0
      for (int i = lcdBank.total(); i != 0; i--)
      {
        lcdBank.set(i - 1);
        lcdBank.clear();
        delay(100);
      }
      return false;
      break;
    case 144:     // NEXT
      // clear LCDs 0-7
      for (int i = 0; i < lcdBank.total(); i++)
      {
        lcdBank.set(i);
        lcdBank.clear();
        delay(100);
      }
      return false;
      break;
    case 168:     // PLAY
      // run progress bar animation
      runProgressBar();
      return false;
      break;
    case 2:       // PLUS
      lcdBank.cursor(true,false);
      break;
    case 152:     // MINUS
      lcdBank.cursor(false,true);
      break;
    case 192:     // BACK
      lcdBank.cursor(false,false);
      break;
  }
  return true;
}
// progress bar animation by Koepel
void runProgressBar()
{
  bool done = false;
  // 16 characters per LCD
  // 8 LCD displays
  // That is a bar graph of 128 positions
  int direction = 1;
  int bar_pos = 0;
  while (!done)
  {
    // Find the display and column
    int disp = bar_pos / 16;
    int column = bar_pos % 16;
    lcdBank.set(disp);
    if (direction > 0)
    {
      lcdBank.pos(column, 0);
      lcdBank.send("\xFF");
      lcdBank.pos(column, 1);
      lcdBank.send("\xFF");
    }
    else
    {
      lcdBank.pos(column, 0);
      lcdBank.send(" ");
      lcdBank.pos(column, 1);
      lcdBank.send(" ");
    }
    bar_pos += direction;
    if (bar_pos == (lcdBank.total() * 16) )
    {
      direction = -direction;
      bar_pos = (lcdBank.total() * 16) - 1;
    }
    else if (bar_pos < 0)
    {
      done = true;
    }
    delay(5);
  }
}