#include <SPI.h>    
#include <PT6955.h>
  // display setup

PT6955::PT6955(){ 
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(13, OUTPUT);
  clearMatrix();
  clearMatrix2();
}

void PT6955::init(int new_mode)
{
  SPI.begin();                             //  Initialize SPI parameters
  SPI.setBitOrder(LSBFIRST);               //  Least significant byte to be sent first
  SPI.setDataMode(SPI_MODE3);              //  Set for clock rising edge
  SPI.setClockDivider(SPI_CLOCK_DIV64);    //  Set clock divider (optional)
  delay(200);
  
  digitalWrite(10,LOW);                
  SPI.transfer(B01000000);             //COMMAND 2: DATA SETTING COMMANDS
  digitalWrite(10,HIGH); 
  
  digitalWrite(10,LOW);                
  SPI.transfer(B11000000);             //COMMAND 3: ADDRESS SETTING COMMANDS
  digitalWrite(10,HIGH);
 
  digitalWrite(10,LOW);                
  SPI.transfer(B00000001);             //COMMAND 1: DISPLAY MODE SETTING COMMANDS  - 00: 4 digits, 12 segments
  digitalWrite(10,HIGH);                
  
  digitalWrite(10,LOW);                
  Pulse_w(new_mode);            //COMMAND 4: DISPLAY CONTROL COMMANDS
  digitalWrite(10,HIGH); 
}

void PT6955::Pulse_w(int new_mode){
  digitalWrite(10,LOW); 
  pulse_mode = new_mode;
  switch(pulse_mode) {
    case 0:
      SPI.transfer(B10001000); // 1/16
      break;
    case 1:
      SPI.transfer(B10001001); // 2/16
      break;
    case 2:
      SPI.transfer(B10001010); // 4/16
      break;
    case 3:
      SPI.transfer(B10001011); // 10/16
      break;
    case 4:
      SPI.transfer(B10001100); // 11/16
      break;
    case 5:
      SPI.transfer(B10001101); // 12/16
      break;
    case 6:
      SPI.transfer(B10001110); // 13/16
      break;
    case 7:
      SPI.transfer(B10001111); // 14/16
      break;
  }
  digitalWrite(10,HIGH);
}

void PT6955::writedigit1_0(){
 LEDMatrix[7] = LEDMatrix[7] | 1; 
 LEDMatrix[6] = LEDMatrix[6] | 8; 
 LEDMatrix[6] = LEDMatrix[6] | 128; 
 LEDMatrix[6] = LEDMatrix[6] | 16; 
 LEDMatrix[6] = LEDMatrix[6] | 64; 
 LEDMatrix[6] = LEDMatrix[6] | 32; 
}

void PT6955::writedigit1_1(){
 LEDMatrix[6] = LEDMatrix[6] | 128; 
 LEDMatrix[6] = LEDMatrix[6] | 64;
}

void PT6955::writedigit1_2(){
 LEDMatrix[7] = LEDMatrix[7] | 1; 
 LEDMatrix[6] = LEDMatrix[6] | 128; 
 LEDMatrix[6] = LEDMatrix[6] | 4; 
 LEDMatrix[6] = LEDMatrix[6] | 16; 
 LEDMatrix[6] = LEDMatrix[6] | 32; 
}

void PT6955::writedigit1_3(){
 LEDMatrix[7] = LEDMatrix[7] | 1; 
 LEDMatrix[6] = LEDMatrix[6] | 128; 
 LEDMatrix[6] = LEDMatrix[6] | 4; 
 LEDMatrix[6] = LEDMatrix[6] | 64; 
 LEDMatrix[6] = LEDMatrix[6] | 32; 
}

void PT6955::writedigit1_4(){
 LEDMatrix[6] = LEDMatrix[6] | 8; 
 LEDMatrix[6] = LEDMatrix[6] | 128; 
 LEDMatrix[6] = LEDMatrix[6] | 4; 
 LEDMatrix[6] = LEDMatrix[6] | 64; 
}

void PT6955::writedigit1_5(){
 LEDMatrix[7] = LEDMatrix[7] | 1; 
 LEDMatrix[6] = LEDMatrix[6] | 8; 
 LEDMatrix[6] = LEDMatrix[6] | 4; 
 LEDMatrix[6] = LEDMatrix[6] | 64; 
 LEDMatrix[6] = LEDMatrix[6] | 32; 
}

void PT6955::writedigit1_6(){
 LEDMatrix[7] = LEDMatrix[7] | 1; 
 LEDMatrix[6] = LEDMatrix[6] | 16; 
 LEDMatrix[6] = LEDMatrix[6] | 8; 
 LEDMatrix[6] = LEDMatrix[6] | 4; 
 LEDMatrix[6] = LEDMatrix[6] | 64; 
 LEDMatrix[6] = LEDMatrix[6] | 32; 
}

void PT6955::writedigit1_7(){
 LEDMatrix[7] = LEDMatrix[7] | 1; 
 LEDMatrix[6] = LEDMatrix[6] | 128; 
 LEDMatrix[6] = LEDMatrix[6] | 64; 
 }

void PT6955::writedigit1_8(){
 LEDMatrix[7] = LEDMatrix[7] | 1; 
 LEDMatrix[6] = LEDMatrix[6] | 16; 
 LEDMatrix[6] = LEDMatrix[6] | 8; 
 LEDMatrix[6] = LEDMatrix[6] | 4; 
 LEDMatrix[6] = LEDMatrix[6] | 64; 
 LEDMatrix[6] = LEDMatrix[6] | 32; 
 LEDMatrix[6] = LEDMatrix[6] | 128; 
}

void PT6955::writedigit1_9(){
 LEDMatrix[7] = LEDMatrix[7] | 1; 
 LEDMatrix[6] = LEDMatrix[6] | 128; 
 LEDMatrix[6] = LEDMatrix[6] | 8; 
 LEDMatrix[6] = LEDMatrix[6] | 4; 
 LEDMatrix[6] = LEDMatrix[6] | 64; 
 LEDMatrix[6] = LEDMatrix[6] | 32; 
}

void PT6955::writedigit1(int newNum){
   switch ( newNum ) {
    case 0:
    writedigit1_0();   
    break; 
    case 1:
    writedigit1_1();   
    break;     
    case 2:
    writedigit1_2();   
    break;     
    case 3:
    writedigit1_3();   
    break;     
    case 4:
    writedigit1_4();   
    break;     
    case 5:
    writedigit1_5();   
    break;
    case 6:
    writedigit1_6();   
    break; 
    case 7:
    writedigit1_7();   
    break; 
    case 8:
    writedigit1_8();   
    break; 
    case 9:
    writedigit1_9();   
    break;     
  }
 
}

void PT6955::writedigit2_0(){
 LEDMatrix[5] = LEDMatrix[5] | 1; 
 LEDMatrix[4] = LEDMatrix[4] | 8; 
 LEDMatrix[4] = LEDMatrix[4] | 128; 
 LEDMatrix[4] = LEDMatrix[4] | 16; 
 LEDMatrix[4] = LEDMatrix[4] | 64; 
 LEDMatrix[4] = LEDMatrix[4] | 32; 
}

void PT6955::writedigit2_1(){
 LEDMatrix[4] = LEDMatrix[4] | 128; 
 LEDMatrix[4] = LEDMatrix[4] | 64;
}

void PT6955::writedigit2_2(){
 LEDMatrix[5] = LEDMatrix[5] | 1; 
 LEDMatrix[4] = LEDMatrix[4] | 128; 
 LEDMatrix[4] = LEDMatrix[4] | 4; 
 LEDMatrix[4] = LEDMatrix[4] | 16; 
 LEDMatrix[4] = LEDMatrix[4] | 32; 
}

void PT6955::writedigit2_3(){
 LEDMatrix[5] = LEDMatrix[5] | 1; 
 LEDMatrix[4] = LEDMatrix[4] | 128; 
 LEDMatrix[4] = LEDMatrix[4] | 4; 
 LEDMatrix[4] = LEDMatrix[4] | 64; 
 LEDMatrix[4] = LEDMatrix[4] | 32; 
}

void PT6955::writedigit2_4(){
 LEDMatrix[4] = LEDMatrix[4] | 8; 
 LEDMatrix[4] = LEDMatrix[4] | 128; 
 LEDMatrix[4] = LEDMatrix[4] | 4; 
 LEDMatrix[4] = LEDMatrix[4] | 64; 
}

void PT6955::writedigit2_5(){
 LEDMatrix[5] = LEDMatrix[5] | 1; 
 LEDMatrix[4] = LEDMatrix[4] | 8; 
 LEDMatrix[4] = LEDMatrix[4] | 4; 
 LEDMatrix[4] = LEDMatrix[4] | 64; 
 LEDMatrix[4] = LEDMatrix[4] | 32; 
}

void PT6955::writedigit2_6(){
 LEDMatrix[5] = LEDMatrix[5] | 1; 
 LEDMatrix[4] = LEDMatrix[4] | 16; 
 LEDMatrix[4] = LEDMatrix[4] | 8; 
 LEDMatrix[4] = LEDMatrix[4] | 4; 
 LEDMatrix[4] = LEDMatrix[4] | 64; 
 LEDMatrix[4] = LEDMatrix[4] | 32; 
}

void PT6955::writedigit2_7(){
 LEDMatrix[5] = LEDMatrix[5] | 1; 
 LEDMatrix[4] = LEDMatrix[4] | 128; 
 LEDMatrix[4] = LEDMatrix[4] | 64; 
 }

void PT6955::writedigit2_8(){
 LEDMatrix[5] = LEDMatrix[5] | 1; 
 LEDMatrix[4] = LEDMatrix[4] | 16; 
 LEDMatrix[4] = LEDMatrix[4] | 8; 
 LEDMatrix[4] = LEDMatrix[4] | 4; 
 LEDMatrix[4] = LEDMatrix[4] | 64; 
 LEDMatrix[4] = LEDMatrix[4] | 32; 
 LEDMatrix[4] = LEDMatrix[4] | 128; 
}

void PT6955::writedigit2_9(){
 LEDMatrix[5] = LEDMatrix[5] | 1; 
 LEDMatrix[4] = LEDMatrix[4] | 128; 
 LEDMatrix[4] = LEDMatrix[4] | 8; 
 LEDMatrix[4] = LEDMatrix[4] | 4; 
 LEDMatrix[4] = LEDMatrix[4] | 64; 
 LEDMatrix[4] = LEDMatrix[4] | 32; 
}

void PT6955::writedigit2(int newNum){
   switch ( newNum ) {
    case 0:
    writedigit2_0();   
    break; 
    case 1:
    writedigit2_1();   
    break;     
    case 2:
    writedigit2_2();   
    break;     
    case 3:
    writedigit2_3();   
    break;     
    case 4:
    writedigit2_4();   
    break;     
    case 5:
    writedigit2_5();   
    break;
    case 6:
    writedigit2_6();   
    break; 
    case 7:
    writedigit2_7();   
    break; 
    case 8:
    writedigit2_8();   
    break; 
    case 9:
    writedigit2_9();   
    break;     
  }
 
}

void PT6955::writedigit3_0(){
 LEDMatrix[3] = LEDMatrix[3] | 1;
 LEDMatrix[2] = LEDMatrix[2] | 8;
 LEDMatrix[2] = LEDMatrix[2] | 16;
 LEDMatrix[2] = LEDMatrix[2] | 32;
 LEDMatrix[2] = LEDMatrix[2] | 128;
 LEDMatrix[2] = LEDMatrix[2] | 64;
}

void PT6955::writedigit3_1(){
 LEDMatrix[2] = LEDMatrix[2] | 64;
 LEDMatrix[2] = LEDMatrix[2] | 128;
}

void PT6955::writedigit3_2(){
 LEDMatrix[3] = LEDMatrix[3] | 1;
 LEDMatrix[2] = LEDMatrix[2] | 128; 
 LEDMatrix[2] = LEDMatrix[2] | 4; 
 LEDMatrix[2] = LEDMatrix[2] | 16;
 LEDMatrix[2] = LEDMatrix[2] | 32; 
}

void PT6955::writedigit3_3(){
 LEDMatrix[3] = LEDMatrix[3] | 1;
 LEDMatrix[2] = LEDMatrix[2] | 128; 
 LEDMatrix[2] = LEDMatrix[2] | 4; 
 LEDMatrix[2] = LEDMatrix[2] | 64;
 LEDMatrix[2] = LEDMatrix[2] | 32; 
}

void PT6955::writedigit3_4(){
 LEDMatrix[2] = LEDMatrix[2] | 8;
 LEDMatrix[2] = LEDMatrix[2] | 128; 
 LEDMatrix[2] = LEDMatrix[2] | 4; 
 LEDMatrix[2] = LEDMatrix[2] | 64;
}

void PT6955::writedigit3_5(){
 LEDMatrix[3] = LEDMatrix[3] | 1;
 LEDMatrix[2] = LEDMatrix[2] | 8; 
 LEDMatrix[2] = LEDMatrix[2] | 4; 
 LEDMatrix[2] = LEDMatrix[2] | 64;
 LEDMatrix[2] = LEDMatrix[2] | 32; 
}

void PT6955::writedigit3_6(){
 LEDMatrix[3] = LEDMatrix[3] | 1;
 LEDMatrix[2] = LEDMatrix[2] | 8; 
 LEDMatrix[2] = LEDMatrix[2] | 4; 
 LEDMatrix[2] = LEDMatrix[2] | 16;
 LEDMatrix[2] = LEDMatrix[2] | 32; 
 LEDMatrix[2] = LEDMatrix[2] | 64; 
}

void PT6955::writedigit3_7(){
 LEDMatrix[3] = LEDMatrix[3] | 1; 
 LEDMatrix[2] = LEDMatrix[2] | 128; 
 LEDMatrix[2] = LEDMatrix[2] | 64; 
}

void PT6955::writedigit3_8(){
 LEDMatrix[3] = LEDMatrix[3] | 1;
 LEDMatrix[2] = LEDMatrix[2] | 8; 
 LEDMatrix[2] = LEDMatrix[2] | 128; 
 LEDMatrix[2] = LEDMatrix[2] | 4;
 LEDMatrix[2] = LEDMatrix[2] | 16; 
 LEDMatrix[2] = LEDMatrix[2] | 64; 
 LEDMatrix[2] = LEDMatrix[2] | 32; 
}

void PT6955::writedigit3_9(){
 LEDMatrix[3] = LEDMatrix[3] | 1;
 LEDMatrix[2] = LEDMatrix[2] | 8; 
 LEDMatrix[2] = LEDMatrix[2] | 128; 
 LEDMatrix[2] = LEDMatrix[2] | 4;
 LEDMatrix[2] = LEDMatrix[2] | 64; 
 LEDMatrix[2] = LEDMatrix[2] | 32; 
}

void PT6955::writedigit3(int newNum){
   switch ( newNum ) {
    case 0:
    writedigit3_0();   
    break; 
    case 1:
    writedigit3_1();   
    break;     
    case 2:
    writedigit3_2();   
    break;     
    case 3:
    writedigit3_3();   
    break;     
    case 4:
    writedigit3_4();   
    break;     
    case 5:
    writedigit3_5();   
    break;
    case 6:
    writedigit3_6();   
    break; 
    case 7:
    writedigit3_7();   
    break; 
    case 8:
    writedigit3_8();   
    break; 
    case 9:
    writedigit3_9();   
    break;     
  }
 
}



void PT6955::writedigit4_0(){
 LEDMatrix[1] = LEDMatrix[1] | 1; 
 LEDMatrix[0] = LEDMatrix[0] | 8; 
 LEDMatrix[0] = LEDMatrix[0] | 128; 
 LEDMatrix[0] = LEDMatrix[0] | 16; 
 LEDMatrix[0] = LEDMatrix[0] | 64; 
 LEDMatrix[0] = LEDMatrix[0] | 32; 
}

void PT6955::writedigit4_1(){
 LEDMatrix[0] = LEDMatrix[0] | 128; 
 LEDMatrix[0] = LEDMatrix[0] | 64;
}

void PT6955::writedigit4_2(){
 LEDMatrix[1] = LEDMatrix[1] | 1; 
 LEDMatrix[0] = LEDMatrix[0] | 128; 
 LEDMatrix[0] = LEDMatrix[0] | 4; 
 LEDMatrix[0] = LEDMatrix[0] | 16; 
 LEDMatrix[0] = LEDMatrix[0] | 32; 
}

void PT6955::writedigit4_3(){
 LEDMatrix[1] = LEDMatrix[1] | 1; 
 LEDMatrix[0] = LEDMatrix[0] | 128; 
 LEDMatrix[0] = LEDMatrix[0] | 4; 
 LEDMatrix[0] = LEDMatrix[0] | 64; 
 LEDMatrix[0] = LEDMatrix[0] | 32; 
}

void PT6955::writedigit4_4(){
 LEDMatrix[0] = LEDMatrix[0] | 8; 
 LEDMatrix[0] = LEDMatrix[0] | 128; 
 LEDMatrix[0] = LEDMatrix[0] | 4; 
 LEDMatrix[0] = LEDMatrix[0] | 64; 
}

void PT6955::writedigit4_5(){
 LEDMatrix[1] = LEDMatrix[1] | 1; 
 LEDMatrix[0] = LEDMatrix[0] | 8; 
 LEDMatrix[0] = LEDMatrix[0] | 4; 
 LEDMatrix[0] = LEDMatrix[0] | 64; 
 LEDMatrix[0] = LEDMatrix[0] | 32; 
}

void PT6955::writedigit4_6(){
 LEDMatrix[1] = LEDMatrix[1] | 1; 
 LEDMatrix[0] = LEDMatrix[0] | 16; 
 LEDMatrix[0] = LEDMatrix[0] | 8; 
 LEDMatrix[0] = LEDMatrix[0] | 4; 
 LEDMatrix[0] = LEDMatrix[0] | 64; 
 LEDMatrix[0] = LEDMatrix[0] | 32; 
}

void PT6955::writedigit4_7(){
 LEDMatrix[1] = LEDMatrix[1] | 1; 
 LEDMatrix[0] = LEDMatrix[0] | 128; 
 LEDMatrix[0] = LEDMatrix[0] | 64; 
 }

void PT6955::writedigit4_8(){
 LEDMatrix[1] = LEDMatrix[1] | 1; 
 LEDMatrix[0] = LEDMatrix[0] | 16; 
 LEDMatrix[0] = LEDMatrix[0] | 8; 
 LEDMatrix[0] = LEDMatrix[0] | 4; 
 LEDMatrix[0] = LEDMatrix[0] | 64; 
 LEDMatrix[0] = LEDMatrix[0] | 32; 
 LEDMatrix[0] = LEDMatrix[0] | 128; 
}

void PT6955::writedigit4_9(){
 LEDMatrix[1] = LEDMatrix[1] | 1; 
 LEDMatrix[0] = LEDMatrix[0] | 128; 
 LEDMatrix[0] = LEDMatrix[0] | 8; 
 LEDMatrix[0] = LEDMatrix[0] | 4; 
 LEDMatrix[0] = LEDMatrix[0] | 64; 
 LEDMatrix[0] = LEDMatrix[0] | 32; 
}

void PT6955::writedigit4(int newNum){
   switch ( newNum ) {
    case 0:
    writedigit4_0();   
    break; 
    case 1:
    writedigit4_1();   
    break;     
    case 2:
    writedigit4_2();   
    break;     
    case 3:
    writedigit4_3();   
    break;     
    case 4:
    writedigit4_4();   
    break;     
    case 5:
    writedigit4_5();   
    break;
    case 6:
    writedigit4_6();   
    break; 
    case 7:
    writedigit4_7();   
    break; 
    case 8:
    writedigit4_8();   
    break; 
    case 9:
    writedigit4_9();   
    break;     
  }
 
}

void PT6955::updateLED(){

  digitalWrite(10,LOW);                
  SPI.transfer(B01000000);             //COMMAND 2: DATA SETTING COMMANDS
  digitalWrite(10,HIGH);
  //delay(10);

  digitalWrite(10,LOW);                //  Drop SPI chip-select to 0 (Arduino pin 10)
  SPI.transfer(B11000000);             //COMMAND 3: ADDRESS SETTING COMMANDS
  for (int i = 0; i<8; i++){
    SPI.transfer(LEDMatrix[i]);             //CDATA
  }
  digitalWrite(10,HIGH);
  clearMatrix();

}

void PT6955::clearLED(){
  
  digitalWrite(10,LOW);                
  SPI.transfer(B01000000);             //COMMAND 2: DATA SETTING COMMANDS
  digitalWrite(10,HIGH);
  //delay(10);

  digitalWrite(10,LOW);                //  Set SPI chip-select to 0 (Arduino pin 10)
  SPI.transfer(B11000000);             //COMMAND 3: ADDRESS SETTING COMMANDS
  SPI.transfer(B00000000);
  digitalWrite(10,HIGH);

  digitalWrite(10,LOW);                
  SPI.transfer(B01000000);             //COMMAND 2: DATA SETTING COMMANDS
  digitalWrite(10,HIGH);
  //delay(10);

  digitalWrite(10,LOW);                //  Set SPI chip-select to 0 (Arduino pin 10)
  SPI.transfer(B11000010);             //COMMAND 3: ADDRESS SETTING COMMANDS
  SPI.transfer(B00000000);
  digitalWrite(10,HIGH);

}

void PT6955::clearMatrix(){
  for (int i = 0; i<8; i++){
    LEDMatrix[i] = 0;
  }
}

void PT6955::clearMatrix2(){
  for (int i = 0; i<8; i++){
    LEDMatrix2[i] = 0;
  }
}

void PT6955::printdigit(int Num){
	bool min = false;
	  if(Num<0) {
	    Num=Num*-1;
	    min=true;
		writecolmin();
	   }
	  if(Num>=1000) {
	   writedigit1((Num/1000)%10);  // months 10's place
	   }
	  if(Num>=100) {
       writedigit2((Num/100)%10);  // months 1's place
       }
	  if(Num>=10) {
	   writedigit3((Num/10%10));  // days 10's place
	  }
	  writedigit4(Num%10);  // days 1's place

      updateLED();
	  clearMatrix();
}

void PT6955::updateLED2() {
  bool comp = true;
  for (int i = 0; i<8; i++){
    if(LEDMatrix2[i] != LEDMatrix2_old[i])
     comp = false;
  }
  if(comp == false)
  {
  digitalWrite(10,LOW);       
  SPI.transfer(B01000000);             //COMMAND 2: DATA SETTING COMMANDS
  digitalWrite(10,HIGH);
  //delay(10);
  digitalWrite(10,LOW);                //  Drop SPI chip-select to 0 (Arduino pin 10)
  SPI.transfer(B11000010);             //COMMAND 3: ADDRESS SETTING COMMANDS
  
  for (int i = 0; i<8; i++){
    SPI.transfer(LEDMatrix2[i]);             //CDATA
  }
  //SPI.transfer(B11111111);
  digitalWrite(10,HIGH);
  memcpy(LEDMatrix2_old,LEDMatrix2,8);
  }
  clearMatrix2();
}

void PT6955::writecolLED1(){
 LEDMatrix2[6] = LEDMatrix2[6] | 4; 
}

void PT6955::writecolLED2(){
 LEDMatrix2[6] = LEDMatrix2[6] | 8; 
}

void PT6955::writecolLED3(){
 LEDMatrix2[6] = LEDMatrix2[6] | 16; 
}

void PT6955::writecolLED4(){
 LEDMatrix2[6] = LEDMatrix2[6] | 32; 
}

void PT6955::writecolrew(){
 LEDMatrix2[7] = LEDMatrix2[7] | 1; 
}

void PT6955::writecolrec(){ 
 LEDMatrix2[6] = LEDMatrix2[6] | 128; 
}

void PT6955::writecolvcr(){
 LEDMatrix2[6] = LEDMatrix2[6] | 64; 
}

void PT6955::writecolmin(){
  LEDMatrix[6] = LEDMatrix[6] | 1; 
}

void PT6955::writecolon(){
 LEDMatrix[2] = LEDMatrix[2] | 1; 
}

void PT6955::writeam(){
 LEDMatrix[0] = LEDMatrix[0] | 1;
}
void PT6955::writetimer(){
 LEDMatrix[0] = LEDMatrix[0] | 2;
}
