/*------------------------------------------------------------------------------------
   Program:     port_select

   Description: Allows a serial port to be selected and connected to graphically.
                Has the following buttons:
                Up         - scrolls up through the serial port list 
                Down       - scrolls down through the serial port list
                Connect    - connects to the selected serial port
                Disconnect - disconnects from the serial port allowing a new serial
                             port to be connected to
                Refresh    - refreshes the list of serial ports. Useful if a new
                             serial device is connected to the PC after this app-
                             lication is started
                
   Purpose:     Allows the serial port to be selected within an application instead
                of hard-coding the port number
                
   Hardware:    Can be used to connect to Arduino or other serial devices
   
   Software:    Developed using Processing 2.2.1 (processing.org)
                Uses the Button class from:
                http://blog.startingelectronics.com/a-simple-button-for-processing-language-code/
                
   Date:        21 July 2015   Author:   W.A. Smith, http://startingelectronics.org
   
------------------------------------------------------------------------------------*/

import processing.serial.*;

Serial serial_port = null;        // the serial port

// serial port buttons
Button btn_serial_up;              // move up through the serial port list
Button btn_serial_dn;              // move down through the serial port list
Button btn_serial_connect;         // connect to the selected serial port
Button btn_serial_disconnect;      // disconnect from the serial port
Button btn_serial_list_refresh;    // refresh the serial port list
Button btn_serial_S;
Button btn_serial_IZ;

String serial_list;                // list of serial ports
int serial_list_index = 0;         // currently selected serial port 
int num_serial_ports = 0;          // number of serial ports in the list

void setup() {
  // set the window size
  size (640, 480);
  
  // create the buttons
  btn_serial_up = new Button("^", 340, 10, 40, 20);
  btn_serial_dn = new Button("v", 340, 50, 40, 20);
  btn_serial_connect = new Button("Connect", 500, 10, 100, 25);
  btn_serial_disconnect = new Button("Disconnect", 500, 45, 100, 25);
  btn_serial_list_refresh = new Button("Refresh", 500, 80, 100, 25);
  btn_serial_S = new Button("S", 20,200, 100, 25);
  btn_serial_IZ = new Button("IZ", 20,230, 100, 25);
  
  // get the list of serial ports on the computer
  serial_list = Serial.list()[serial_list_index];
  
  //println(Serial.list());
  //println(Serial.list().length);
  
  // get the number of serial ports in the list
  num_serial_ports = Serial.list().length;
}

void mousePressed() {
  // up button clicked
  if (btn_serial_up.MouseIsOver()) {
    if (serial_list_index > 0) {
      // move one position up in the list of serial ports
      serial_list_index--;
      serial_list = Serial.list()[serial_list_index];
    }
  }
  // down button clicked
  if (btn_serial_dn.MouseIsOver()) {
    if (serial_list_index < (num_serial_ports - 1)) {
      // move one position down in the list of serial ports
      serial_list_index++;
      serial_list = Serial.list()[serial_list_index];
    }
  }
  // Connect button clicked
  if (btn_serial_connect.MouseIsOver()) {
    if (serial_port == null) {
      // connect to the selected serial port
      serial_port = new Serial(this, Serial.list()[serial_list_index], 115200);
      println("connected");
    }
  }
  // Disconnect button clicked
  if (btn_serial_disconnect.MouseIsOver()) {
    if (serial_port != null) {
      // disconnect from the serial port
      serial_port.stop();
      serial_port = null;
    }
  }
  // Refresh button clicked
  if (btn_serial_list_refresh.MouseIsOver()) {
    // get the serial port list and length of the list
    serial_list = Serial.list()[serial_list_index];
    num_serial_ports = Serial.list().length;
  }
  // S button clicked
     if (serial_port != null) {
         if (btn_serial_S.MouseIsOver()) {
            serial_port.write("S\n");
            println("message S");
         }
  }
    // IZ button clicked
     if (serial_port != null) {
       if (btn_serial_IZ.MouseIsOver()) {
          serial_port.write("IZ\n");
          println("message IZ");
       }  
  }
}

void draw() {
  // draw the buttons in the application window
  btn_serial_up.Draw();
  btn_serial_dn.Draw();
  btn_serial_connect.Draw();
  btn_serial_disconnect.Draw();
  btn_serial_list_refresh.Draw();
  btn_serial_S.Draw();
  btn_serial_IZ.Draw();
  // draw the text box containing the selected serial port
  DrawTextBox("Select Port", serial_list, 10, 10, 320, 60);
}

// function for drawing a text box with title and contents
void DrawTextBox(String title, String str, int x, int y, int w, int h)
{
  fill(255);
  rect(x, y, w, h);
  fill(0);
  textAlign(LEFT);
  textSize(14);
  text(title, x + 10, y + 10, w - 20, 20);
  textSize(12);  
  text(str, x + 10, y + 40, w - 20, h - 10);
}

// button class used for all buttons
class Button {
  String label;
  float x;    // top left corner x position
  float y;    // top left corner y position
  float w;    // width of button
  float h;    // height of button
  
  // constructor
  Button(String labelB, float xpos, float ypos, float widthB, float heightB) {
    label = labelB;
    x = xpos;
    y = ypos;
    w = widthB;
    h = heightB;
  }
  
  // draw the button in the window
  void Draw() {
    fill(218);
    stroke(141);
    rect(x, y, w, h, 10);
    textAlign(CENTER, CENTER);
    fill(0);
    text(label, x + (w / 2), y + (h / 2));
  }
  
  // returns true if the mouse cursor is over the button
  boolean MouseIsOver() {
    if (mouseX > x && mouseX < (x + w) && mouseY > y && mouseY < (y + h)) {
      return true;
    }
    return false;
  }
}