// slide_leds.pde
//
// Peter H Anderson, Sept 29, '09, Oct 8, '09

#define DIR_OUT(pin) pinMode(pin, OUTPUT)
#define DIR_IN(pin)   pinMode(pin, INPUT)
#define O_HIGH(pin) digitalWrite(pin, HIGH)
#define O_LOW(pin) digitalWrite(pin, LOW)
#define IN(pin) digitalRead(pin)

#define cbi(byt_v, bit) (byt_v &= (~(0x01 << (bit))))
#define sbi(byt_v, bit) (byt_v |= (0x01 << (bit)))

#define tbi(byt_v, bit)  (byt_v & (0x01 << (bit))) ? (1) : (0)

#define LEFT 0
#define RIGHT 1

typedef struct 
{
    int freq;
    float duration;
} NOTE;                

void play_tune(void);
void tone(int f, float d);

void setup()
{
    cbi(DDRB, 1);  //DIR_IN(9);  // actuate tone
    sbi(DDRB, 0);  // DIR_OUT(8); // to speaker
    sbi(PINB, 1);  // insert pulluo
    
    DDRD = DDRD | B00111100; // don't fool with TX and RX on 0 and 1
    PIND = PIND | B11000000;  // pullup on most sign bit   
    PORTD = PORTD & B11000011; // all LEDs off     
    Serial.begin(9600); 
}

void loop()                    
{    
    while(1)
    {
       
       if (IN(7) == 0)
       {
          slide_leds(LEFT, 150);
       }
       
       else if (IN(6) == 0)
       {
          slide_leds(RIGHT, 150);
       }
       Serial.println(DDRB, DEC);
       delay(100);
       if ((IN(9)) == 0)
       {
           Serial.print("!");
           while(IN(9) == 0)
           {
             Serial.println(PORTB, DEC);
           }     
           play_tune();
       }
    }   
}

void slide_leds(int direction, int dly_time_ms)
{
   const byte left[5] = {0x01, 0x03, 0x07, 0x0f, 0x00};
   const byte right[5] = {0x08, 0x0c, 0x0e, 0xff, 0x00};
   
   for (int n=0; n<5; n++)
   {
       PORTD &= B11000011;
       if (direction == LEFT) 
       {
          PORTD |= (left[n] << 2);
       }
       else
       {
          PORTD |= (right[n] << 2);
       }
       delay(dly_time_ms);
   }
}   
           
void play_tune(void)
{
   NOTE notes[2] = {{220, 1.0}, {440, 2.0}};   
   for (int n=0; n<2; n++)
   {
       tone(notes[n].freq, notes[n].duration);
       delay(100);
   }
}

void tone(int f, float d)
{
    int num, us;
    us = 1000000 / (2*f);
    num = (int) (f * d);
    
    for (int n=0; n<num; n++)
    {
        sbi(PORTB, 0);  //O_HIGH(8);
        delayMicroseconds(us);
        cbi(PORTB, 0);  //O_LOW(8);
        delayMicroseconds(us);
    }
}