// Letter definitions based on 5 bit-wise columns (5 x 7 font)
#define SP {0, 0, 0, 0, 0}
#define EX {0, 125, 0, 0, 0}  // !
#define ST {0,1,0,0,0}
#define A {31, 36, 68, 36, 31}
#define B {127, 73, 73, 73, 54}
#define C {62, 65, 65, 65, 34}
#define D {127, 65, 65, 34, 28}
#define E {127, 73, 73, 65, 65}
#define FF {127, 72, 72, 72, 64}
#define G {62, 65, 65, 69, 38}
#define H {127, 8, 8, 8, 127}
#define I {65, 65, 127, 65, 65}
#define J {2, 1, 1, 1, 126}
#define K {127, 8, 20, 34, 65}
#define L {127, 1, 1, 1, 1}
#define M {127, 32, 16, 32, 127}
#define N {127, 32, 16, 8, 127}
#define O {62, 65, 65, 65, 62}
#define P {127, 72, 72, 72, 48}
#define Q {62, 65, 69, 66, 61}
#define R {127, 72, 76, 74, 49}
#define S {50, 73, 73, 73, 38}
#define T {64, 64, 127, 64, 64}
#define U {126, 1, 1, 1, 126}
#define V {124, 2, 1, 2, 124}
#define W {126, 1, 6, 1, 126}
#define X {99, 20, 8, 20, 99}
#define Y {96, 16, 15, 16, 96}
#define Z {67, 69, 73, 81, 97}

const int coinInt = 1;
float coinstot = 0.00;
float coinsold = 0.00;
volatile float coinsval = 0.00;
unsigned long times, elapsed;
int valll=0;
int coinsChange = 0;
int waitMillis = 0;

int spid = 3;                    // Constrols scroll speed (1 minimum, way too fast)
byte bit[8] = {128, 64, 32, 16, 8, 4, 2, 1};    // Used for bit comparisons
byte colVals[8] = {0, 0, 0, 0, 0, 0, 0, 0};  // Hold display columns (initaly blank)

// Define display string here
const int charNum = 80;                 // Number of letters in display string
byte string[charNum][5] = {C,A,S,H,SP,R,U,L,E,S,SP,E,V,E,R,Y,T,H,I,N,G,SP,A,R,O,U,N,D,SP,M,E,SP,C,ST,R,ST,E,ST,A,ST,M,ST,SP,G,E,T,SP,T,H,E,SP,M,O,N,E,Y,SP,D,O,L,L,A,SP,D,O,L,L,A,SP,B,I,L,L,SP,Y,A,L,L,EX,EX};

int cloc = 10;
int data = 11;
int sync= 12;
    int i,l,c,zmk;
      int f=1;
      int time=0;

byte line[8] = {B11111000,B11111001,B11111010,B11111011,B11111100,B11111101,B11111110,B11111111};
//byte line[7] = {B10011111,B01011111,B11011111,B00111111,B10111111,B01111111,B11111111};
byte display[999];
byte bitmap[7][54];
byte tempdisplay= B00000000;

void setup()
{
   attachInterrupt(coinInt, coinInserted, RISING);

 for (int ltr = 0; ltr < 260; ltr++){// For each letter in string array
        // For each columin in letter + one space
 display[ltr]= B00000000;        // or empty space between


  }
valll=random(16);
 Serial.println(valll);
  if (valll<1){byte string[charNum][5] = {C,A,S,H,SP,R,U,L,E,S,SP,E,V,E,R,Y,T,H,I,N,G,SP,A,R,O,U,N,D,SP,M,E,SP,C,ST,R,ST,E,ST,A,ST,M,ST,SP,G,E,T,SP,T,H,E,SP,M,O,N,E,Y,SP,D,O,L,L,A,SP,D,O,L,L,A,SP,B,I,L,L,SP,Y,A,L,L,EX,EX};
}
  else {if (valll<2){byte string[charNum][5] = {W,E,SP,S,H,A,P,E,SP,O,U,R,SP,T,O,O,L,S,SP,A,N,D,SP,T,H,E,N,SP,O,U,R,SP,T,O,O,L,S,SP,S,T,E,A,L,SP,Y,O,U,R,SP,M,O,N,E,Y};
}
  else { if (valll<3){byte string[charNum][5] = {P,R,E,S,S,SP,I,P,SP,T,O,SP,S,T,A,R,T};
}
  else {if (valll<4){byte string[charNum][5] = {K,A,P,S,A,L,O,N,SP,L,A,H,M,A,C,U,N,SP,D,O,N,E,R,SP,K,E,B,A,B,SP,B,O,R,E,K};
}
  else {if (valll<5){byte string[charNum][5] = {E,R,R,O,R,EX,SP,I,N,S,E,R,T,SP,A,N,O,T,H,E,R,SP,C,O,I,N};
}
  else {if (valll<6){byte string[charNum][5] = {I,N,S,E,R,T,SP,A,SP,B,I,T,C,O,I,N,SP,T,O,SP,S,T,A,R,T};
}
  else {if (valll<7){byte string[charNum][5] = {T,H,A,N,K,S,SP,N,O,W,SP,W,E,SP,C,A,N,SP,G,O,SP,T,O,SP,T,H,E,SP,C,O,FF,FF,E,E,S,H,O,P};
}
  else {if (valll<8){byte string[charNum][5] = {T,H,E,SP,C,R,I,S,I,S,SP,O,FF,SP,T,O,D,A,Y,SP,I,S,SP,T,H,E,SP,J,O,K,E,SP,O,FF,SP,T,O,M,O,R,R,O,W};
}
  else {if (valll<9){byte string[charNum][5] = {S,N,A,I,L,S,SP,C,A,N,SP,S,L,E,E,P,SP,FF,O,R,SP,U,P,SP,T,O,SP,T,H,R,E,E,SP,Y,E,A,R,S};
}
  else {if (valll<10){byte string[charNum][5] = {T,R,Y,SP,A,G,A,I,N};
}
  else {if (valll<11){byte string[charNum][5] = {W,O,W,SP,T,H,A,T,S,SP,N,E,A,R,L,Y,SP,A,SP,E,U,R,O,S,H,O,P,P,E,R,SP,B,I,E,R};
}
  else {if (valll<12){byte string[charNum][5] = {L,E,D,SP,S,I,G,N,S,SP,S,U,C,K};
}
  else {if (valll<13){byte string[charNum][5] = {FF,R,E,E,SP,H,U,G,S,SP,Z,I,J,N,SP,O,P};
}
  else { if (valll<14){byte string[charNum][5] = {D,E,L,U,X,E,SP,H,U,G,S,SP,FF,O,R,SP,T,W,O,SP,E,U,R,O,S,SP,A,S,K,SP,M,U,P,P,E,T};
}
  else {if (valll<15){byte string[charNum][5] = {P,R,E,P,R,O,G,R,A,M,M,E,D,SP,L,E,D,SP,S,E,N,T,E,N,C,E,SP,N,U,M,B,E,R,SP,FF,I,FF,T,E,E,N};
}
  else { if (valll<16){byte string[charNum][5] = {T,H,E,SP,S,E,N,T,E,N,C,E,S,SP,A,R,E,SP,O,V,E,R,SP,W,E,SP,A,R,E,SP,L,A,Z,Y};
} else {  Serial.println(valll);
byte string[charNum][5] = {C,A,S,H,SP,R,U,L,E,S,SP,E,V,E,R,Y,T,H,I,N,G,SP,A,R,O,U,N,D,SP,M,E,SP,C,ST,R,ST,E,ST,A,ST,M,ST,SP,G,E,T,SP,T,H,E,SP,M,O,N,E,Y,SP,D,O,L,L,A,SP,D,O,L,L,A,SP,B,I,L,L,SP,Y,A,L,L,EX,EX};
}}}}}}}}}}}}}}}}

    for (int ltr =0; ltr < charNum; ltr++){// For each letter in string array
    for (int y = 0; y < 6; y++){        // For each columin in letter + one space
    if (y < 5){
        display[ltr*6+y+260]= string[ltr][y];           // shifts display columns left
    }
    else { display[ltr*6+260+y]= B00000000; }        // or empty space between
    }
}

      Serial.begin(9600);
      pinMode(cloc,OUTPUT);
      pinMode(data,OUTPUT);
      pinMode(sync,OUTPUT);
}

void initText()
{
for (int ltr = 0; ltr < 260; ltr++){// For each letter in string array
        // For each columin in letter + one space
 display[ltr]= B00000000;        // or empty space between
  }
 valll=random(16);
 Serial.println(valll);
  if (valll<1){byte string[charNum][5] = {C,A,S,H,SP,R,U,L,E,S,SP,E,V,E,R,Y,T,H,I,N,G,SP,A,R,O,U,N,D,SP,M,E,SP,C,ST,R,ST,E,ST,A,ST,M,ST,SP,G,E,T,SP,T,H,E,SP,M,O,N,E,Y,SP,D,O,L,L,A,SP,D,O,L,L,A,SP,B,I,L,L,SP,Y,A,L,L,EX,EX};
}
  else {if (valll<2){byte string[charNum][5] = {W,E,SP,S,H,A,P,E,SP,O,U,R,SP,T,O,O,L,S,SP,A,N,D,SP,T,H,E,N,SP,O,U,R,SP,T,O,O,L,S,SP,S,T,E,A,L,SP,Y,O,U,R,SP,M,O,N,E,Y};
}
  else { if (valll<3){byte string[charNum][5] = {P,R,E,S,S,SP,I,P,SP,T,O,SP,S,T,A,R,T};
}
  else {if (valll<4){byte string[charNum][5] = {K,A,P,S,A,L,O,N,SP,L,A,H,M,A,C,U,N,SP,D,O,N,E,R,SP,K,E,B,A,B,SP,B,O,R,E,K};
}
  else {if (valll<5){byte string[charNum][5] = {E,R,R,O,R,EX,SP,I,N,S,E,R,T,SP,A,N,O,T,H,E,R,SP,C,O,I,N};
}
  else {if (valll<6){byte string[charNum][5] = {I,N,S,E,R,T,SP,A,SP,B,I,T,C,O,I,N,SP,T,O,SP,S,T,A,R,T};
}
  else {if (valll<7){byte string[charNum][5] = {T,H,A,N,K,S,SP,N,O,W,SP,W,E,SP,C,A,N,SP,G,O,SP,T,O,SP,T,H,E,SP,C,O,FF,FF,E,E,S,H,O,P};
}
  else {if (valll<8){byte string[charNum][5] = {T,H,E,SP,C,R,I,S,I,S,SP,O,FF,SP,T,O,D,A,Y,SP,I,S,SP,T,H,E,SP,J,O,K,E,SP,O,FF,SP,T,O,M,O,R,R,O,W};
}
  else {if (valll<9){byte string[charNum][5] = {S,N,A,I,L,S,SP,C,A,N,SP,S,L,E,E,P,SP,FF,O,R,SP,U,P,SP,T,O,SP,T,H,R,E,E,SP,Y,E,A,R,S};
}
  else {if (valll<10){byte string[charNum][5] = {T,R,Y,SP,A,G,A,I,N};
}
  else {if (valll<11){byte string[charNum][5] = {W,O,W,SP,T,H,A,T,S,SP,N,E,A,R,L,Y,SP,A,SP,E,U,R,O,S,H,O,P,P,E,R,SP,B,I,E,R};
}
  else {if (valll<12){byte string[charNum][5] = {L,E,D,SP,S,I,G,N,S,SP,S,U,C,K};
}
  else {if (valll<13){byte string[charNum][5] = {FF,R,E,E,SP,H,U,G,S,SP,Z,I,J,N,SP,O,P};
}
  else { if (valll<14){byte string[charNum][5] = {D,E,L,U,X,E,SP,H,U,G,S,SP,FF,O,R,SP,T,W,O,SP,E,U,R,O,S,SP,A,S,K,SP,M,U,P,P,E,T};
}
  else {if (valll<15){byte string[charNum][5] = {P,R,E,P,R,O,G,R,A,M,M,E,D,SP,L,E,D,SP,S,E,N,T,E,N,C,E,SP,N,U,M,B,E,R,SP,FF,I,FF,T,E,E,N};
}
  else { if (valll<16){byte string[charNum][5] = {T,H,E,SP,S,E,N,T,E,N,C,E,S,SP,A,R,E,SP,O,V,E,R,SP,W,E,SP,A,R,E,SP,L,A,Z,Y};
} else {  Serial.println(valll);
byte string[charNum][5] = {C,A,S,H,SP,R,U,L,E,S,SP,E,V,E,R,Y,T,H,I,N,G,SP,A,R,O,U,N,D,SP,M,E,SP,C,ST,R,ST,E,ST,A,ST,M,ST,SP,G,E,T,SP,T,H,E,SP,M,O,N,E,Y,SP,D,O,L,L,A,SP,D,O,L,L,A,SP,B,I,L,L,SP,Y,A,L,L,EX,EX};
}}}}}}}}}}}}}}}}

    for (int ltr =0; ltr < charNum; ltr++){// For each letter in string array
    for (int y = 0; y < 6; y++){        // For each columin in letter + one space
    if (y < 5){
        display[ltr*6+y+260]= string[ltr][y];           // shifts display columns left
    }
    else { display[ltr*6+260+y]= B00000000; }        // or empty space between
    }
}
}

void coinInserted()
{
//The function that is called every time it recieves a pulse
  coinsval = coinsval + 0.10;
//As we set the Pulse to represent 5p or 5c we add this to the coinsValue
  coinsChange = 1;
//Flag that there has been a coin inserted
}

void loop()
{

PORTB &= B11101011;

    for (l=1;l<8;l++) {
        for (zmk=0;zmk<270;zmk++){
             if (display[zmk] & (1 << l-1)  ){
PORTB |= B00001000;
                      }
              else {
PORTB &= B11110111;
}
clock(1);
        }
        for (c=0;c<8;c++) {
                   if ( line[l] & (1 << c)  ){
PORTB |= B00001000;
                      }
              else {
PORTB &= B11110111;
}
                 clock(1);
    }

PORTB |= B00010000;
delayMicroseconds(150);
PORTB &= B11101111;
delayMicroseconds(250);
}

time++;
if (time > spid){

shiftLeft();

time=0;
}

  times=millis();
  if(coinsChange == 1){
//Check if a coin has been Inserted
  if(waitMillis == 0){
    elapsed=times;
    waitMillis=1;
    }
  coinsChange = 0;
  }
  if((waitMillis == 1) && ((times-elapsed)>2500)){
//unflag that a coin has been inserted

    coinstot=coinstot+coinsval;
    coinsval=0;
   waitMillis = 0;
   initText();

//Print the Value of coins inserted
  }



}

void shiftLeft(){
for (zmk=0;zmk<charNum*6+260;zmk++){
  display[zmk]=display[zmk+1];
}
}

void clock(int kkss){
    for (int ksks=0;ksks<kkss;ksks++){
PORTB |= B00000100;
PORTB &= B11111011;
    }
}