//Code for controlling display of a video using a Micromag3 magnetometer
//by Daniel Soltis

import processing.video.*; 
import processing.serial.*;
Serial port;
Movie myMovie; 

boolean firstContact = false;  
int x;
int y;
int z;
float offset;

void setup() { 
  size(640, 480); 
  frameRate(30); 
  myMovie = new Movie(this, "cp2.mov"); 
  myMovie.loop(); 
  port = new Serial(this, Serial.list()[0], 9600);
  port.write(65);
  println("OK let's go!");
} 

void draw(){

  //if you can't get the serial port to respond, try again
  if (firstContact == false) {
    delay(300);
    port.write(65);
  }

  //if the movie is available, read it
  if(myMovie.available()) { 
    myMovie.read(); 
  }

  //translate the x and y data from the magnetometer
  //into a single orientation reading
  float heading = 0;
  if (x == 0 && y < 0){
    heading = PI/2;
  }
  if (x == 0 && y > 0){
    heading = 3*PI/2; 
  }
  if (x < 0){
    heading = PI - atan(float(y)/float(x));
  }
  if (x > 0 && y < 0){
    heading = -atan(float(y)/float(x)); 
  }
  if (x > 0 && y > 0) {
    heading = 2*PI - atan(float(y)/float(x));
  }

  //show the movie, with the offset changing depending on the orientation of the magnetometer
  //the three images are for wraparound
  image(myMovie, offset, 0, 3*myMovie.width, 3*myMovie.height); 
  image(myMovie, offset + myMovie.width, 0, 3*myMovie.width, 3*myMovie.height); 
  image(myMovie, offset - 3*myMovie.width, 0, 3*myMovie.width, 3*myMovie.height); 

  //this shows a line in the middle that shows orientation. for debugging, not display
  strokeWeight(4);
  stroke(255);
  line(width/2, height/2, width/2 + 100*cos(heading), height/2 + 100*sin(heading));
  offset = 3*myMovie.width - 3*myMovie.width*heading/(2*PI);

}

//get data from the magnetometer
void serialEvent(Serial port) {

  if (firstContact == false) {
    firstContact = true; 
  }
  //read the data as a string, split it into parts, ad turn them into numbers
  String input = port.readStringUntil(13);
  if (input != null){
    String[] parts = input.split(",");
    x= int(parts[0]);
    y= int(parts[1]);
    z =int(parts[2]);
  }
  port.write(65);
}