/* program to follow a dark line on light paper

   original version by Sara Marku, Marija Ivica, Thu Nguyen, Ruth Wu
 */

/* establish constants for clarity
 */

/* identify sensors */
#define left  0
#define right 1

/* identify sensor results */
#define light 0
#define dark  1

/* names of display windows */
char * window_names [12] = {   "zero",  "one", "two",  "three",
			       "four", "five", "six",  "seven",
			      "eight", "nine", "ten", "eleven"};

/* intensity array */
char * intensities [7] = {"very dark", "dark", "moderatly dark", "moderate light",
                          "moderately bright", "bright", "very bright"};

/* turning parameters */
double turning_rate = 0.4;
double turning_time = 0.8;
int number_turns = 18;

/* tempo gives seconds per beat */
/*const double tempo = 1.0/2.0; */ // a beat is 1/2 second 
/* C does not allow a constant identifier to be used in defining other 
   constants, so use #define to define tempo as a computable number */
#define tempo 0.5

/* variable beatm_n indicates m.n beats,
 *   so beat1_5 is 1 1/2 beats */
const double beat_5   = tempo / 2.0;
const double beat1    = tempo;
const double beat1_5  = tempo * 1.5;
const double beat2    = tempo * 2;
const double beat2_5  = tempo * 2.5;
const double beat3    = tempo * 3;
const double beat3_5  = tempo * 3.5;
const double beat4    = tempo * 4;
const double beat5    = tempo * 5;
const double beat6    = tempo * 6;
const double beat7    = tempo * 7;
    
/* some notes */
/* pitches in treble clef, with octave 1 just above middle C
 *   all pitches are tuned to concert A = 440
 *   for variable names, s or f means sharp or flat
 *   number at end of variable name gives octave above middle C
 *   the following frequencies are from the Piano_key_frequencies article 
 in Wikipedia */
const int silence  = 0;
const int pitchB3  = 246;
const int pitchC4  = 261;
const int pitchDf4 = 277;
const int pitchCs4 = 277; /* = pitchDf4; */
const int pitchD4  = 293;
const int pitchEf4 = 311;
const int pitchDs4 = 311; /* = pitchEf4; */
const int pitchE4  = 329;
const int pitchF4  = 349;
const int pitchGf4 = 369;
const int pitchFs4 = 369; /* = pitchGf4; */
const int pitchG4  = 391;
const int pitchAf4 = 415;
const int pitchGs4 = 415; /* = pitchAf1; */
const int pitchA4  = 440;
const int pitchBf4 = 466;
const int pitchAs4 = 466; /* = pitchBf4; */
const int pitchB4  = 493;
const int pitchC5  = 523;
const int pitchDf5 = 554;
const int pitchCs5 = 554; 
const int pitchD5  = 587;
const int pitchEf5 = 622;
const int pitchDs5 = 622;
const int pitchE5  = 659;
const int pitchF5  = 698;
const int pitchGf5 = 739;
const int pitchFs5 = 739; 
const int pitchG5  = 783;
const int pitchAf5 = 830;
const int pitchGs5 = 830;
const int pitchA5  = 880;
const int pitchBf5 = 932;
const int pitchAs5 = 932;
const int pitchB5  = 987;
const int pitchC6 = 1046;

#include <stdio.h>
#include <string.h>
#include <unistd.h>  // needed for sleep
#include "MyroC.h"
#include <eSpeakPackage.h>

int main () {

  printf ("Scribbler 2 demonstration program\n");

  printf ("identify robot to be used:\n");
  printf ("   1 - rfcomm0\n");
  printf ("   2 - curry\n");
  printf ("   3 - wilkes\n");
  printf ("   4 - perlis\n");
  printf ("enter option: ");
  int option;
  scanf ("%d", &option);

  char * connection_string;
  if (option == 1)
    connection_string = "/dev/rfcomm0";
  else if (option == 2)
    connection_string = "/dev/tty.IPRE6-365897-DevB";
  else if (option == 3)
    connection_string = "/dev/tty.IPRE6-365877-DevB";
  else if (option == 4)
    connection_string = "/dev/tty.Fluke2-0958-Fluke2";
  else
    {
      printf ("please try again with robot 1, 2, 3, or 4\n");
      return 1;
    }

  printf ("establishing Bluetooth connection\n");
  rConnect (connection_string);
  //rConnect("/dev/rfcomm0");             // connection on Linux
  //rConnect ("/dev/tty.IPRE6-365897-DevB");   // curry
  //rConnect ("/dev/tty.IPRE6-365877-DevB");   // wilkes
  //rConnect ("/dev/tty.Fluke2-0958-Fluke2");  // perlis
  
  printf ("Bluetooth connection made\n");
  eSpeakConnect();
  //int sensors[2];

  /* opening remark */
  char speech_line[200];
  strcpy (speech_line, "Hi everyone, I am ");
  strcat (speech_line, rGetName());
  eSpeakTalk(speech_line);
  
  /* looking round the room */
  eSpeakTalk ("I am going to look around the room");
  sleep (5);
  eSpeakTalk ("I will display pictures and provide some commentary");

  sleep (6);
  int i;
  Picture pic [number_turns];

  for (i = 0; i < number_turns; i++)
    {
      printf ("iteration %d\n", i);
      int brightness;
      int brightl, brightr;
      pic[i] = rTakePicture ();
      rDisplayPicture (&(pic[i]), 0.0, window_names [i%8]);
      switch (i%6)
	{
        case 0:
	  brightness = rGetBrightTxt ("left", 3);
	  printf ("brightness:  %d;  description %s\n", 
		  brightness, intensities [brightness/60000]);
          sprintf (speech_line, "left side of the picture is %s",
                   intensities [brightness/60000]);
	  eSpeakTalk (speech_line);
	break;

        case 1:
	  brightl = rGetBrightTxt ("left", 3);
	  brightr = rGetBrightTxt ("right", 3);
	  printf ("case 1:  l/r bright:  %d/%d\n", brightl, brightr);
	  //eSpeakSetGender("female");
          if ((brightl > brightr - 1000) && (brightl < brightr + 1000))
	    {
	      eSpeakTalk ("left and right sides have about the same intensities");
	    }
	  else if (brightl > brightr)
	    {
	      eSpeakTalk ("left of picture brigher than right");
	    }
	  else
	    {
	      eSpeakTalk ("right of picture brigher than left");
	    }
	  printf ("end case 1\n");
	break;

        case 2:
	  brightness = rGetBrightTxt ("center", 3);
          sprintf (speech_line, "total intensities in middle of picture  is %d",
                   brightness);
	  eSpeakTalk (speech_line);
	break;

        case 3:
	  eSpeakTalk ("turning on the Fluke's L E D");
          rSetLEDBack (1);
	break;

        case 4:
	  eSpeakTalk ("play notes for a change of pace");
	  rBeep (1.0, 1046);
          rBeep (1.0, 1319);
          rBeep (1.0, 1568);
          rBeep (2.0, 2093);
	break;

        case 5:
	  //eSpeakSetGender("male");
	  eSpeakTalk ("turning off the Fluke's L E D");
          rSetLEDBack (0);
	
	break;

	default:
	  printf ("case not found\n");
	}
      sleep(4);
      rTurnRight (0.3, 0.5);
    }

  /* phase 2:  beeps and movement */
  eSpeakTalk ("in phase 2, some notes and movement");

  rSetForwardness ("fluke-forward");

  /* tune from spirit song */
  // first phrase
  rTurnRight (3.0, -1.0);
  rBeep (beat1  , pitchE5);
  rBeep (beat1  , pitchF5);
  rBeep (beat1  , pitchG5);
  rBeep (beat1_5, pitchA5);
  rBeep (beat_5 , pitchA5);
  rBeep (beat1_5, pitchA5);
  rBeep (beat_5 , pitchA5);
  rBeep (beat1  , pitchA5);
  rBeep (beat1  , pitchD5);
  rBeep (beat1  , silence);
    
  // second phrase
  rForward (1.0, -4.0);
  rBeep (beat_5 , pitchE5);
  rBeep (beat_5 , pitchF5);
  rBeep (beat1_5, pitchG5);
  rBeep (beat_5 , pitchG5);
  rBeep (beat1_5, pitchG5);
  rBeep (beat_5 , pitchA5);
  rBeep (beat2  , pitchC5);
  rBeep (beat1  , silence);
    
  // third phrase 
  rTurnRight (0.5, -2.0);
  rBeep (beat_5 , pitchD5);
  rBeep (beat_5 , pitchE5);
  rBeep (beat1_5, pitchF5);
  rBeep (beat_5 , pitchF5);
  rBeep (beat1_5, pitchF5);
  rBeep (beat_5 , pitchF5);
  rBeep (beat1  , pitchF5);
  rBeep (beat1  , pitchB4);
  rBeep (beat1_5, pitchC5);
  rBeep (beat_5 , pitchD5);
  rBeep (beat4  , pitchE5);
  rBeep (beat1  , silence);
    
  // fourth phrase = first phrase
  rTurnLeft (0.5, -2.0);
  rBeep (beat1  , pitchE5);
  rBeep (beat1  , pitchF5);
  rBeep (beat1  , pitchG5);
  rBeep (beat1_5, pitchA5);
  rBeep (beat_5 , pitchA5);
  rBeep (beat1_5, pitchA5);
  rBeep (beat_5 , pitchA5);
  rBeep (beat1  , pitchA5);
  rBeep (beat1  , pitchD5);
  rBeep (beat1  , silence);
    
  // fifth phrase = second phrase
  rBackward (1.0, -4.0);
  rBeep (beat_5 , pitchE5);
  rBeep (beat_5 , pitchF5);
  rBeep (beat1_5, pitchG5);
  rBeep (beat_5 , pitchG5);
  rBeep (beat1_5, pitchG5);
  rBeep (beat_5 , pitchA5);
  rBeep (beat2  , pitchC5);
  rBeep (beat1  , silence);
    
  // sixth phrase = third phrase with different ending 
  rTurnLeft (1.0, 1.5);
  rBeep (beat_5 , pitchD5);
  rBeep (beat_5 , pitchE5);
  rBeep (beat1_5, pitchF5);
  rBeep (beat_5 , pitchF5);
  rBeep (beat1  , pitchF5);
  rBeep (beat1  , pitchE5);
  rBeep (beat1_5, pitchD5);
  rBeep (beat_5 , pitchD5);
  rBeep (beat1  , pitchC5);
  rBeep (beat1  , pitchB4);
  rBeep (beat7  , pitchC5);
  rBeep (beat1  , silence);
    
  // Chorus
  rForward (1.0, -4.0);
  rBeep (beat4  , pitchA5);
  rBeep (beat3  , pitchB5);
  rBeep (beat1  , pitchA5);
  rBeep (beat4  , pitchG5);
  rBeep (beat3  , pitchE5);
  rBeep (beat1  , silence);
    
  rTurnRight (0.5, -2.0);
  rBeep (beat3  , pitchF5);
  rBeep (beat1  , pitchA5);
  rBeep (beat3  , pitchG5);
  rBeep (beat1  , pitchF5);
  rBeep (beat5  , pitchE5);
  rBeep (beat3  , silence);
  
  rTurnLeft (0.5, -2.0);
  rBeep (beat4  , pitchA5);
  rBeep (beat3  , pitchB5);
  rBeep (beat1  , pitchA5);
  rBeep (beat4  , pitchG5);
  rBeep (beat3  , pitchE5);
  rBeep (beat1  , silence);
    
  rBackward (1.0, -4.0);
  rBeep (beat3  , pitchF5);
  rBeep (beat1  , pitchE5);
  rBeep (beat3  , pitchD5);
  rBeep (beat1  , pitchC5);
  rBeep (beat5  , pitchC5);
  rBeep (beat1  , silence);

  eSpeakTalk ("end of demonstration");
  eSpeakDisconnect();
  rDisconnect();
  
  return 0;
}


