/*
 * Computer Switchboard
 * 
 * Because interfacing with computers should be fun
 * and a keyboard is not enough.
 * 
 * Let's turn a computer into an airplane (interface wise).
 * 
 */

 //todo: debounce, see neotimer

//makes serial slower so it can be read
#define DEBUGMODE 0

#include <avr/io.h>
#include <avr/interrupt.h>

 

/*  SevenSegmentLEDdisplay102a.ino
 *   2017-02-20
 *   Mel Lester Jr.
 *  Simple example of using Shift Register with a
 *  Single Digit Seven Segment LED Display
*/
// Globals
const int dataPin = 4;  // blue wire to 74HC595 pin 14
const int latchPin = 7; // green to 74HC595 pin 12
const int clockPin = 8; // yellow to 74HC595 pin 11

/* uncomment one of the following lines that describes your display
 *  and comment out the line that does not describe your display */
const char common = 'a';    // common anode
//const char common = 'c';    // common cathode

bool decPt = true;  // decimal point display flag


//switch

// digital pin 9 has a pushbutton attached to it. Give it a name:
int pushButton = 9;


//rotary

// -----
// SimplePollRotator.ino - Example for the RotaryEncoder library.
// This class is implemented for use with the Arduino environment.
// Copyright (c) by Matthias Hertel, http://www.mathertel.de
// This work is licensed under a BSD style license. See http://www.mathertel.de/License.aspx
// More information on: http://www.mathertel.de/Arduino
// -----
// 18.01.2014 created by Matthias Hertel
// -----

// This example checks the state of the rotary encoder in the loop() function.
// The current position is printed on output when changed.

// Hardware setup:
// Attach a rotary encoder with output pins to A2 and A3.
// The common contact should be attached to ground.

#include <RotaryEncoder.h>

// Setup a RoraryEncoder for pins A2 and A3:
//RotaryEncoder encoder(A2, A1);
RotaryEncoder encoder(A1, A2);
int difference = 0;



uint8_t segdisp = 0;








// Example showing use of the MD_KeySwitch library
// 
// Momentary switch 
// 
// Prints the switch value on the Serial Monitor
// Allows setting of options to see theior effect (see setup())
//
#include <MD_KeySwitch.h>

// This is just an average debounce -steak
// what i need is a way to actually, not register if I don't pick up the depressed button
// but good enough for now

 
const uint8_t SWITCH_PIN = 9;       // switch connected to this pin
const uint8_t SWITCH_ACTIVE = LOW;  // digital signal when switch is pressed 'on'

MD_KeySwitch S(SWITCH_PIN, SWITCH_ACTIVE);


 
void setup() {
  // initialize I/O pins
  pinMode(dataPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);

  Serial.begin(9600);

  pinMode(pushButton, INPUT_PULLUP);
  
  S.begin();
  //S.enableDoublePress(true);
  S.enableLongPress(true);
  /*S.enableRepeat(true);
  S.enableRepeatResult(true);*/

  
}

void loop() {


  //decPt = !decPt; // display decimal point every other pass through loop

  // generate characters to display for hexidecimal numbers 0 to F
 /* for (int i = 0; i <= 15; i++) {
    byte bits = myfnNumToBits(i) ;
    if (decPt) {
      bits = bits | B00000001;  // add decimal point if needed
    }
    myfnUpdateDisplay(bits);    // display alphanumeric digit
    delay(500);                 // pause for 1/2 second
  }*/

  byte bits = myfnNumToBits(segdisp);
  if (decPt) {
      bits = bits | B00000001;  // add decimal point if switch high
    }
  
  myfnUpdateDisplay(bits);




  //ROTARY

  static uint8_t pos = 0;
  encoder.tick();

  uint8_t newPos = encoder.getPosition();
  if (pos != newPos) {
    difference = pos - newPos;
    
    
    //Serial.print(newPos);
    //Serial.println();
    //Serial.println(difference);
    pos = newPos;

    segdisp = (segdisp + difference);
    segdisp = segdisp & B00000111;//only give me the last three bits
                                  //if there is anything there, so and.
                                  //gives me 0-7  
    
    //Serial.println(segdisp);
   
  } 



//BUTTONS

 /* int resultb = 0;
  resultb = PINB;
  delay(100);
  if (resultb == 0 ){
                      
                       
    decPt = 1;

    Serial.print("User Pressed button: ");
    Serial.println(segdisp);

  }
  else{
    decPt = 0;
  }
  */
  // too fast, print serial when checking switch only
  // Serial.println(resultb,BIN); // noisy, but reads 0 when low.

switch(S.read())
  {
    case MD_KeySwitch::KS_NULL:       /* Serial.println("NULL"); */   break;
    
    case MD_KeySwitch::KS_PRESS:      
      //Serial.println("\nSINGLE PRESS"); 
      Serial.print("User Pressed button: ");
      Serial.println(segdisp);
      break;

    /*
    case MD_KeySwitch::KS_DPRESS:     Serial.print("\nDOUBLE PRESS"); 
    break;*/
   
    //case MD_KeySwitch::KS_LONGPRESS:  Serial.print("\nLONG PRESS");   
    //break; //this doesn't seem to work at all. - steak
   /*
    case MD_KeySwitch::KS_RPTPRESS:   Serial.print("\nREPEAT PRESS");
    break;
    */
    default:                          Serial.print("\nUNKNOWN");      
    break;
  }


  
} 



void myfnUpdateDisplay(byte eightBits) {
  if (common == 'a') {                  // using a common anonde display?
    eightBits = eightBits ^ B11111111;  // then flip all bits using XOR 
  }
  digitalWrite(latchPin, LOW);  // prepare shift register for data
  shiftOut(dataPin, clockPin, LSBFIRST, eightBits); // send data
  digitalWrite(latchPin, HIGH); // update display
}

byte myfnNumToBits(int someNumber) {
  switch (someNumber) {
    case 0:
      return B11111100;
      break;
    case 1:
      return B01100000;
      break;
    case 2:
      return B11011010;
      break;
    case 3:
      return B11110010;
      break;
    case 4:
      return B01100110;
      break;
    case 5:
      return B10110110;
      break;
    case 6:
      return B10111110;
      break;
    case 7:
      return B11100000;
      break;
    case 8:
      return B11111110;
      break;
    case 9:
      return B11110110;
      break;
    case 10:
      return B11101110; // Hexidecimal A
      break;
    case 11:
      return B00111110; // Hexidecimal B
      break;
    case 12:
      return B10011100; // Hexidecimal C or use for Centigrade
      break;
    case 13:
      return B01111010; // Hexidecimal D
      break;
    case 14:
      return B10011110; // Hexidecimal E
      break;
    case 15:
      return B10001110; // Hexidecimal F or use for Fahrenheit
      break;  
    default:
      return B10010010; // Error condition, displays three vertical bars
      break;   
  }




}





