import processing.core.*; 
import processing.data.*; 
import processing.event.*; 
import processing.opengl.*; 

import processing.serial.*; 

import java.util.HashMap; 
import java.util.ArrayList; 
import java.io.File; 
import java.io.BufferedReader; 
import java.io.PrintWriter; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.IOException; 

public class Simple_DLC_Master extends PApplet {



final int BACK_COLOUR = color(192,192,192);
final int CONNECT_COLOUR = color(0,192,0);
final int TEXT_COLOUR = color(0,0,0);
final int BAR_COLOUR = color(128,128,128);
final int SLIDER_COLOUR = color(0,0,0);

//for serial port management
Serial DLC;
int printcode=-1;
int printkey =-1;
int serialIndex=0;
String portName="-no ports-";
String currentPort="";
boolean portConnect=false;
boolean lastkey;

//interface
boolean thismouse, lastmouse;

//graphics
//PImage bGround;

//timing
long mLast;
int v=0;
int[] lamps;

public void setup() {
  int i;
    
  surface.setTitle("Silicon Chip Digital Lighting Controller");
  surface.setResizable(false);          //doesn't prevent maximise
  background(BACK_COLOUR);      //cls
  noStroke();    //transparent stroke
  textSize(32);   //gives 24 pixels high text
  lastkey=keyPressed;
  lastmouse=mousePressed;
  if(Serial.list().length>0){portName=Serial.list()[0];}  
  mLast=millis();
  lamps = new int[64];
  for(i=0;i<64;i++){lamps[i]=0;}  //all off
}

public void draw(){
  boolean thiskey;
  int i;
  background(BACK_COLOUR);      //cls
  if(portConnect){
    fill(CONNECT_COLOUR);
  }else{
    fill(TEXT_COLOUR);
  }
  textSize(32);   //gives 24 pixels high text
  text(portName,200,315);
  fill(TEXT_COLOUR);
  textSize(16);
  text("+/- to change port",320,300);
  text("s to start/stop",320,315);
  textSize(32);   //gives 24 pixels high text
  thiskey=keyPressed;
  if((thiskey==true)&&(lastkey!=true)){
    printcode=keyCode;
    printkey=key;
    if((printkey=='='||printkey=='+')&&portConnect==false){serialIndex++;}
    if((printkey=='-'||printkey=='_')&&portConnect==false){serialIndex--;if(serialIndex<0){serialIndex=0;}}
    if(serialIndex>Serial.list().length-1){serialIndex=Serial.list().length-1;}
    if(Serial.list().length>0){portName=Serial.list()[serialIndex];}
    if(printkey=='s'||printkey=='S'){
      if(portConnect==false){
        try{
          currentPort=portName;      //save so it can't change
          DLC=new Serial(this, currentPort, 38400);
          portConnect=true;      
        } catch(Exception e){
          portConnect=false;              //failed to connect        
        }
      }else{
        DLC.stop();
        portConnect=false;              
      }      
    }
  }
  lastkey=thiskey;
  //check mouse
  thismouse=mousePressed;
  fill(TEXT_COLOUR);    //black
  //text(str(mouseX)+","+str(mouseY)+"     ",160,315);
  textSize(12);   //gives 9 pixels high text
  fill(TEXT_COLOUR);    //black
  for(i=0;i<16;i++){
    if(thismouse){  
      if((mouseX>i*30+2)&&(mouseX<i*30+28)&&(mouseY<266)){
        lamps[i]=260-mouseY;
        if(lamps[i]<0){lamps[i]=0;}
        if(lamps[i]>255){lamps[i]=255;}
      }
    }
    fill(BAR_COLOUR);    //dark grey
    rect(i*30+5,5,20,256);    //x,y,w,h
    fill(SLIDER_COLOUR);    //light grey
    rect(i*30+2,258-lamps[i],26,6);    //x,y,w,h
    fill(TEXT_COLOUR);    //black
    text(("   "+str(lamps[i])).substring(str(lamps[i]).length()),i*30+4,278);
  }
  fill(TEXT_COLOUR);
  if(thismouse){
    if((mouseX>100)&&(mouseX<150)&&(mouseY>290)){    
      fill(CONNECT_COLOUR);
      for(i=0;i<64;i++){lamps[i]=0;}  //all off
    }
  }
  textSize(32);   //gives 24 pixels high text
  text("OFF",100,315);    
  //update lamps if needed (20Hz)
  textSize(32);   //gives 24 pixels high text
  if(millis()-mLast>100){
    mLast=mLast+100;
    sendPacket();
    if(portConnect){
      fill(CONNECT_COLOUR);
    }else{
      fill(TEXT_COLOUR);
    }
    text("TX",10,315);    
  }else{
    fill(TEXT_COLOUR);
    text("TX",10,315);    
  }
}

public void sendPacket(){
  int i;
  if(portConnect){
    try{
       DLC.stop();
       DLC=new Serial(this, currentPort, 9600);
       DLC.write(192);    //MSB set to give MAB
       DLC.stop();
       DLC=new Serial(this, currentPort, 38400);
       DLC.write(0);      //lamp data to follow
       for(i=0;i<64;i++){
         DLC.write(lamps[i]);
       }
       //leave port open between calls so no-one else can grab it
    }catch(Exception e){        } //quietly ignore
  }
}
  public void settings() {  size(480, 320,P3D); }
  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "Simple_DLC_Master" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}
