#include <LiquidCrystal.h>

class DisplayText   // Object for displaying on a lcd screen
{
  public:
    LiquidCrystal lcd;

    DisplayText(int pinRS, int pinE, int pin0, int pin1, int pin2, int pin3)
      : lcd(pinRS, pinE, pin0, pin1, pin2, pin3)
    {}

    DisplayText()
      : lcd(0,0,0,0,0,0)
    {}

    void begin()
    {
      lcd.begin(16, 2);
      lcd.clear();
      lcd.setCursor(0, 0);
    }
};


class DisplayManager   // manages various display types (currently only text lcds
{
  public:

    DisplayText *Displays;
    unsigned displayCount;

    void begin()
    {
      for (unsigned i = 0; i < displayCount; i++)
        Displays[i].begin();
    }

    DisplayManager(byte _textLCDs[][6], const unsigned count) : displayCount(count)
    {
      // allocates memory for number of lcds based on array of pins
      Displays = new DisplayText[displayCount];

      for (unsigned i = 0; i < displayCount; i++)
      {
        Displays[i] = DisplayText(
          _textLCDs[i][0],
          _textLCDs[i][1],
          _textLCDs[i][2],
          _textLCDs[i][3],
          _textLCDs[i][4],
          _textLCDs[i][5]); // initialize each lcd
      }
    }
};

byte textLCDsSetup[][6] =
{
  { 52, 48, 36, 34, 32, 30 },
  { 53, 51, 36, 34, 32, 30 },
  { 50, 49, 36, 34, 32, 30 },
  { 46, 47, 36, 34, 32, 30 },
};

const unsigned DisplayCount = sizeof textLCDsSetup / sizeof textLCDsSetup[0];

DisplayManager manager(textLCDsSetup, DisplayCount); // initialize manager

void setup()
{
  manager.begin(); // Initialize displays

  // Put text on the first display
  manager.Displays[0].lcd.print("number one");
  manager.Displays[1].lcd.print("number two");
  manager.Displays[2].lcd.print("number three");
  manager.Displays[3].lcd.print("number four");
}

void loop() 
{
  manager.Displays[0].lcd.setCursor(0, 1);
  manager.Displays[0].lcd.print( random(0, 10000));

  manager.Displays[2].lcd.setCursor(0, 1);
  manager.Displays[2].lcd.print( millis());

  static int sweep = 0, direction = 1;
  sweep += direction;
  if( sweep == 15 or sweep == 0)
    direction = -direction;
  manager.Displays[3].lcd.setCursor( 0, 1);
  manager.Displays[3].lcd.print( "                ");
  manager.Displays[3].lcd.setCursor( sweep, 1);
  manager.Displays[3].lcd.print( '#');

  delay( 100);
}