/*------------------------------

Accelerometer monitoring program 

ORF ver.

Ohgi labo.

-------------------------------*/


import processing.video.*; //library for video

import controlP5.*;       //library for controlP5

import processing.serial.*;//library for sirial communication

import processing.net.*;   //library for sirial communication


/*-------set variables--------*/


static int ON = 1;

static int OFF = 0;


//Set Window Size

int Width = screen.width - 100;

int Height = screen.height - 100;


//Set Font

PFont Data_Font;


//Set Color

color black = color(0);


//Set BackGround Image

PImage BackGround;

PImage BackGroundHeader;

PImage BackGroundFooter;


//Set Button

ControlP5 Button;


//Set CSV Writer

PrintWriter CSV;

int Saving_Flag = OFF;

int pre_Saving_Flag = Saving_Flag;

int Saving_Flag_Counter = 0;

String File_Title;


//Set MovieWriter

MovieMaker MovieFile;


//Set CSV Reader

BufferedReader reader;

String line;


//Set Movies

Capture Capture_Video;

Capture Capture_Video_2;

Movie Import_Movie;

int Frame_Number = 0;


//Set Sirial Communication

Serial port;

String Sirial_Data;

String[] Data_List;

int Data_Counter;

int raw_AccX;

int raw_AccY;

int raw_AccZ;


//Set Graph Status

PGraphics Graph;


int GraphPosition = 0;


int Frame_PositionX = 50; 

int Frame_PositionY = 330;


//Graph data from Accelerometer Sensor

float AccX = 0.;

float AccY = 0.;

float AccZ = 0.;


//previous Graph data from Accelerometer Sensor

float pre_AccX = 0.;

float pre_AccY = 0.;

float pre_AccZ = 0.;


//Graph Data from CSV file

float AccX_csv = 0.;

float AccY_csv = 0.;

float AccZ_csv = 0.;


//precious Graph Data from CSV file

float pre_AccX_csv = 0.;

float pre_AccY_csv = 0.;

float pre_AccZ_csv = 0.;


//Difference between Accelerometer Sensor data and CSV data 

float Diff_AccX =0.;

float Diff_AccY =0.;

float Diff_AccZ =0.;




int Drawing_Flag = ON;


//Set Drawing Data(omit the third decimals from raw data)

float ACCX = 0.;

float ACCY = 0.;

float ACCZ = 0.;


/*--------Set up----------*/

void setup(){

  //Set Fram Rate

  frameRate(25);

  

  //Set Size

  size(Width,Height);

  

  //Set Background

  BackGround = loadImage("background.png");//(1180*700)

  BackGroundHeader = loadImage("background_header.png");//(1180*648)

  BackGroundFooter = loadImage("background_footer.png");//(1180*52)

  background(BackGround);

  

  //Set Font

  Data_Font = loadFont("HoeflerText-Black-48.vlw");

  

  //Set Graph image

  Graph = createGraphics(1160,308,P2D);

  

  //evade error

  CSV = createWriter("NULL");

  

  /*--------Initial Setting (CSV Reader)----------*/

  reader = createReader("17-10-41.csv");

  

  /*--------Initial Setting (Sirial Communication)----------*/

  port =  new Serial(this,"/dev/tty.usbserial-A9007S0S",9600);

  port.clear();

  port.bufferUntil(10);

  

  /*--------Initial Setting (movie)----------*/

  //capture movie

  Capture_Video = new Capture(this,320,240,Capture_Video.list()[2]);

//  Capture_Video_2 = new Capture(this,320,240,Capture_Video.list()[1]);;

 

  //import movie

  Import_Movie = new Movie(this,"17-10-41.mov");

  Import_Movie.loop();



/*--------Initial Setting (button)-----------*/

  Button = new ControlP5(this);

  Button.addButton("Movie_Start",0,10,100,80,19);

  Button.addButton("Movie_Stop",1,10,120,80,19);

  Button.addButton("Start_Saving",2,10,140,80,19);

  Button.addButton("Stop_Saving",3,10,160,80,19);

}  


/*--------Reaction Setting (button)-----------*/

public void controlEvent(ControlEvent theEvent) { 

}


public void Start_Saving(int theValue) {

  if(Saving_Flag == OFF){

    Saving_Flag = ON;

    File_Title = month()+"-"+day()+"/"+hour()+"-"+minute()+"-"+second();

    

    //Make CSV File

    CSV = createWriter(File_Title+".csv");

    CSV.println("AccX,AccY,AccZ,Counter,Frame_Number");

    

    //Make Movie File

    MovieFile = new MovieMaker(this,width,height,File_Title+".mov",10, MovieMaker.VIDEO, MovieMaker.LOSSLESS);

  }

}

public void Stop_Saving(int theValue) {

  if(Saving_Flag == ON){

    Saving_Flag = OFF;

    

    //Close CSV File

    CSV.flush();

    CSV.close();

    

    //Close Movie File

    MovieFile.finish();

    Frame_Number = 0;

  }

}



//csv event(read csv)

void csvEvent(){

  try{

    line = reader.readLine();

  }catch (IOException e){

    e.printStackTrace();

    line = null;

  }

  if (line == null) {

    // Stop reading because of an error or file is empty

    reader = createReader("17-10-41.csv");


  } else {

    String[] pieces = split(line, ",");

    

     AccX_csv = float(pieces[0]);

     AccY_csv = float(pieces[1]);

     AccZ_csv = float(pieces[2]);

     

  }

}



/*--------Take Difference between Acc data and CSV data-----------*/

void Difference(){

  Diff_AccX =abs(AccX - AccX_csv)*50;

  Diff_AccY =abs(AccY - AccY_csv)*50;

  Diff_AccZ =abs(AccZ - AccZ_csv)*50;

}





/*--------Draw Frame-----------*/

void drawFrame(){

  stroke(0);

  strokeWeight(1.5);

  fill(255);

  

  //set font

  fill(black); 

  textFont(Data_Font,23);

  

  //darw text

  text("X",Frame_PositionX-30,Frame_PositionY+60);

  text("Y",Frame_PositionX-30,Frame_PositionY+60+103);

  text("Z",Frame_PositionX-30,Frame_PositionY+60+206);


  //draw left box

  fill(255);

  rect(Frame_PositionX,Frame_PositionY,530,309);

  line(Frame_PositionX,Frame_PositionY+103,580,Frame_PositionY+103);

  line(Frame_PositionX,Frame_PositionY+206,580,Frame_PositionY+206);  

  

  //draw right box

  rect(Frame_PositionX+550,Frame_PositionY,530,309);

  line(Frame_PositionX+550,Frame_PositionY+103,Frame_PositionX+1080,Frame_PositionY+103);

  line(Frame_PositionX+550,Frame_PositionY+206,Frame_PositionX+1080,Frame_PositionY+206);

}


/*--------Draw Graph-----------*/

void drawGraph(){

  if(Drawing_Flag == ON){

    //Draw into PGraphics

    Graph.beginDraw();

    //set Line Width

    Graph.strokeWeight(1.5);

    

    //Draw Graph

    if(GraphPosition > 0){

      /*--------Draw Acc Graph-----------*/

      //draw AccX1

      Graph.stroke(255,0,0);

      Graph.line(GraphPosition,51+pre_AccX*30,GraphPosition+3,51+AccX*30);

      pre_AccX = AccX;


      //draw AccY1

      Graph.stroke(255,0,0);

      Graph.line(GraphPosition,51*3+pre_AccY*30,GraphPosition+3,51*3+AccY*30);

      pre_AccY = AccY;


      //draw AccZ1

      Graph.stroke(255,0,0);

      Graph.line(GraphPosition,51*5+pre_AccZ*30,GraphPosition+3,51*5+AccZ*30);

      pre_AccZ = AccZ;

      

      /*--------Draw CSV Graph-----------*/

      //draw AccX_csv

      Graph.stroke(0,0,0);

      Graph.line(GraphPosition,51+pre_AccX_csv*30,GraphPosition+3,51+AccX_csv*30);

      pre_AccX_csv = AccX_csv;


      //draw AccY_csv

      Graph.stroke(0,0,0);

      Graph.line(GraphPosition,51*3+pre_AccY_csv*30,GraphPosition+3,51*3+AccY_csv*30);

      pre_AccY_csv = AccY_csv;


      //draw AccZ_csv

      Graph.stroke(0,0,0);

      Graph.line(GraphPosition,51*5+pre_AccZ_csv*30,GraphPosition+3,51*5+AccZ_csv*30);

      pre_AccZ_csv = AccZ_csv;

      

      /*--------Draw Difference Graph-----------*/

      Difference();

      Graph.strokeWeight(5);

      Graph.stroke(#ff8c00);

      //draw Difference about X

      Graph.line(GraphPosition+550,103,GraphPosition+550,103-Diff_AccX);

      

      //draw Difference about Y

      Graph.line(GraphPosition+550,206,GraphPosition+550,206-Diff_AccY);

      

      //draw Difference about Z

      Graph.line(GraphPosition+550,309,GraphPosition+550,309-Diff_AccZ);

    

    }

    

    //reset graph if it reaches to the end  

    if(GraphPosition >= 530){

      image(BackGround,0,0);

      Graph.endDraw();

      Graph = createGraphics(1160,308,P2D);

      Graph.beginDraw();

      

      GraphPosition = 0;

     

    }

    

    GraphPosition = GraphPosition + 3;

    Graph.endDraw();

  }

}




/*--------Draw Data-----------*/

void drawData(){

  //Set Font

  fill(black); 

  textFont(Data_Font,23);

  

  text("|| couter "+Data_Counter,10,Height-17);

  text("|| AccX(g) -> "+ACCX,175,Height-17);

  text("|| AccY(g) -> "+ACCY,375,Height-17);

  text("|| AccZ(g) -> "+ACCZ,575,Height-17);

  

  if(Saving_Flag == ON){

    text("|| NOW RECORIDING TO "+File_Title,760,Height-17);

  }

  else{

    text("|| NOW WAITING ...",760,Height-17);

  }

}




/*--------Sirial Communication-----------*/

void serialEvent(Serial p){


  //read Sirial Data

  Sirial_Data = port.readStringUntil(10);

  Sirial_Data = trim(Sirial_Data);

  


  /*----transform the raw data----*/

  

  //split the sirial data

  String[] List = split(Sirial_Data,",");


  //convert strings to int

  raw_AccX = int(List[1]);

  raw_AccY = int(List[2]);

  raw_AccZ = int(List[3]);

  Data_Counter = int(List[4]);


  //show the raw data

  println(raw_AccX+","+raw_AccY+","+raw_AccZ+","+Data_Counter);


  //calibration

  AccY = -(raw_AccX-802.5)/189.5;

  AccZ = (raw_AccY-772.5)/211.5;

  AccX = -(raw_AccZ-778.0)/165.0;

  

  //omit the third decimals

  ACCX = float(floor(AccX*100))/100;

  ACCY = float(floor(AccY*100))/100;

  ACCZ = float(floor(AccZ*100))/100;

  

  //save to CSV file

  if(Saving_Flag == ON){

    CSV.println(AccX+","+AccY+","+AccZ+","+Data_Counter+","+Frame_Number);

  }

}



//movie event(read movie)

void movieEvent(Movie m) {

  m.read();

  if(m.duration() == m.time()) reader = createReader("17-10-41.csv");

}

//Capture Event(read capture Video)

void captureEvent(Capture Capture) {

  Capture.read();

}




//Draw All

void draw(){

  /*--------draw Movie and Video---------*/

  //draw Import Movie

  image(Import_Movie,590,80,590,240);

  

  //draw Capture Movie

  image(Capture_Video,0,80,300,240);

//  image(Capture_Video_2,300,80,300,240);

  /*--------draw Graph and Frame---------*/

  drawFrame();

  

  for(int i =0; i<2;i++)csvEvent();

  drawGraph();

  


  image(Graph,Frame_PositionX,Frame_PositionY);

  

  

  /*--------draw Acc Data----------*/

  image(BackGroundFooter,0,648);

  drawData();


  //write frame image to Movie file

  if(Saving_Flag == ON){

    MovieFile.addFrame();

    Frame_Number++;

  }

  


}