// Made by Lester Matthew Sollano

// Class Constructor:
// ShiftRegisterClass objectName ( dataPin, clockPin )
// dataPin - DS Pin of 74HC595
// clockPin - SHCP Pin of 74HC595

// Class Functions:
// write ( pin, state )

// Global Functions:
// globalWrite ( pin, state )


#define print(x) Serial.println(x)
#define latchPin 2

int binStrToInt ( String binStr )
{
  return strtol ( binStr.c_str(), NULL, 2 );
}

String binIntToStr ( int binInt )
{
  return String( binInt, BIN );
}

class ShiftRegisterClass
{
  private:
  int dataPin, clockPin, firstDataInt, secondDataInt;
  String firstDataStr = "00000000", secondDataStr = "00000000", tempStr;

  public:
  ShiftRegisterClass ( int dataPin, int clockPin )
  {
    this->dataPin = dataPin;
    this->clockPin = clockPin;
  }

  write ( int pin, int state )
  {
    if ( pin <= 8 ) {
      tempStr = firstDataStr;
      firstDataStr = "";
      for ( int i = 0; i < 8; i++ )
      {
        if ( i+1 != pin )
        {
          firstDataStr = firstDataStr + tempStr[i];
        } else
        {
          firstDataStr = firstDataStr + binIntToStr( state );
        }
      }
      firstDataInt = binStrToInt ( firstDataStr );
    } else
    {
      tempStr = secondDataStr;
      secondDataStr = "";
      for ( int i = 0; i < 8; i++ )
      {
        if ( i+9 != pin )
        {
          secondDataStr = secondDataStr + tempStr[i];
        } else
        {
          secondDataStr = secondDataStr + binIntToStr( state );
        }
      }
      secondDataInt = binStrToInt ( secondDataStr );
    }
    shiftOut ( dataPin, clockPin, LSBFIRST, secondDataInt );
    shiftOut ( dataPin, clockPin, LSBFIRST, firstDataInt );
    digitalWrite ( latchPin, HIGH );
    digitalWrite ( latchPin, LOW );
  }
};

ShiftRegisterClass SR[] = {ShiftRegisterClass( 4, 3 ), ShiftRegisterClass( 5, 6 )};

void globalWrite ( int pin, int state )
{
  int classIndex = (pin-1) / 16;
  int outputPin = pin % 16;
  if ( outputPin == 0 )
  {
    outputPin = 16;
  }
  SR[classIndex].write ( outputPin, state );
}

void allMode( int firstPin, int lastPin, int IO )
{
  int amtOfPins = lastPin - firstPin + 1;
  for ( int counter = firstPin; counter <= lastPin; counter++ )
  {
    pinMode( counter, IO );
  }
}


void setup()
{
  Serial.begin(9600);
  allMode ( 0, 53, OUTPUT );
}

//edit the LOOP lol idc
void loop()
{
  for ( int i = 1; i <= 16; i++ )
  {
    globalWrite ( random( 1, 17 ), HIGH );
    globalWrite ( i, HIGH );
    delay(50);
    globalWrite ( i, LOW );
    delay(50);
  }
}
74HC595
74HC595