import hypermedia.video.*;
import java.awt.Rectangle;

OpenCV opencv;

// Have to enter info manually because OpenCV can't access it.
// TODO try this with the new video library.

// MANUAL MOVIE INFO
//String movieLocation = "/Users/Mika/Documents/Code/openFrameworks 0.05/apps/mika/wii_mix_2/data/videos/Abe.mov";
//int movieWidth = 320;
//int movieHeight = 240;
//float fps = 29.97;
//float duration = 82; // in seconds

//String movieLocation = "/Users/Mika/Desktop/Yellow Submarine.avi";
//int movieWidth = 448;
//int movieHeight = 336;
//float fps = 23.98;
//float duration = 5151; // in seconds

String movieLocation = "/Users/Mika/Desktop/Titicut_Follies.avi";
int movieWidth = 478;
int movieHeight = 353;
float fps = 29.97;
float duration = 5111; // in seconds

// keep track of the reading process
int framesRead = 0;
int faceFramesAccumulated = 0;
int[] frameAccumulator = new int[movieWidth * movieHeight * 4];

PImage scratch;
PImage sceneHolder;
PImage faceHolder; // TODO put all the faces together at same scale
String[] parts = split(movieLocation, '/');
String filename = parts[parts.length - 1]; // a nice filename prefix for screenshots

void setup() {
  size( movieWidth, movieHeight );

  // zero the accumulator
  for(int i = 0; i < frameAccumulator.length; i++) {
    frameAccumulator[i] = 0;
  }

  opencv = new OpenCV(this);
  opencv.movie(movieLocation, movieWidth, movieHeight);    // load movie file 
  opencv.cascade( OpenCV.CASCADE_FRONTALFACE_ALT );    // load the FRONTALFACE description file  
  frameRate(60);
}

void draw() {
  opencv.read(); // read a new frame
  // image( opencv.image(), 0, 0 );  // and display image

  Rectangle[] faces = opencv.detect();

  if(faces.length > 0) {
    scratch = opencv.image();

    for( int i=0; i<faces.length; i++ ) {
      sceneHolder = createImage(movieWidth, movieHeight, ARGB);
      sceneHolder.copy(scratch, faces[i].x, faces[i].y, faces[i].width, faces[i].height, faces[i].x, faces[i].y, faces[i].width, faces[i].height);

      // add the face holder pixels to the accumulator
      sceneHolder.loadPixels();
      for(int j = 0; j < sceneHolder.pixels.length; j++) {

        
        
          frameAccumulator[j * 4] += 255; // make alpha solid

        frameAccumulator[j * 4 + 1] += red(sceneHolder.pixels[j]);
        frameAccumulator[j * 4 + 2] += green(sceneHolder.pixels[j]);
        frameAccumulator[j * 4 + 3] += blue(sceneHolder.pixels[j]);
      }

      image(sceneHolder, 0, 0);

      faceFramesAccumulated++;
    }
  }

  if(framesRead % 100 == 0) spitStats();

  framesRead++;

  // quit
  if(framesRead > (duration * fps)) {
    saveAverage();
    exit();
  }
}

void spitStats() {
  // spit some stats
  println("time: " + (framesRead / fps) + " / " + duration + "seconds");  
  println("frame: " + framesRead + " / " + (duration * fps) + " frames");
  println("faces captured: " + faceFramesAccumulated);
  println();
}

void saveAverage() {
  spitStats();


  PImage average = createImage(movieWidth, movieHeight, ARGB);
  average.loadPixels();

  for(int i = 0; i < sceneHolder.pixels.length; i++) {
    average.pixels[i] = color(
    (frameAccumulator[i * 4 + 1] / faceFramesAccumulated),
    (frameAccumulator[i * 4 + 2] / faceFramesAccumulated),
    (frameAccumulator[i * 4 + 3] / faceFramesAccumulated),
    255);
  }

  average.updatePixels();
  //image(average, 0, 0); 

  println("saving average");

//  PGraphics bigImage = createGraphics(movieWidth, movieHeight, JAVA2D);
//  bigImage.beginDraw();
//  bigImage.image(average, 0, 0);
//  bigImage.endDraw();
  average.save(filename +" frame " + framesRead + ".png");
}

void keyPressed() {
  if (key == ' ') {
    saveAverage();
  }

  else if (key == 'j') {
    float time = mouseX/float(width);
    opencv.jump( time );            // jump to a specified frame
    framesRead = round((time * duration) * fps);
    println("jumped to : " + framesRead + " / " + (duration * fps) + " frames");
  }
}

