import processing.core.*; 
import processing.xml.*; 

import java.applet.*; 
import java.awt.*; 
import java.awt.image.*; 
import java.awt.event.*; 
import java.io.*; 
import java.net.*; 
import java.text.*; 
import java.util.*; 
import java.util.zip.*; 
import java.util.regex.*; 

public class histogram_eq extends PApplet {

PImage b, c;

float x,y; // variables for position
float last_x, last_y;

float r, theta, curr_r; // variables for sacaddic motion
float target_zoom, last_zoom, curr_zoom;

float t;
static float d_t=0.1f;
static float saccade_length = 12.0f;

int win_width;
int win_height;

// variables for auto-constrast
int i_min, i_max;
static float discard = 0.0001f;

PFont fontA;

// Set to 4 for 1/4 size Preview
static int DIV = 3; 

// variables for logging of timing
String outpath="output\\s_ff_blur_02\\";
PrintWriter output;
static boolean writeToFile=false;

public void setup() {
  size(screen.width/DIV, screen.height/DIV);//, 800);
  background(0);
  
  b=loadImage("C:\\Swap\\Photos\\03_washington dc bedroom 2.jpg");

  win_height=PApplet.parseInt(b.height*0.4f/DIV);
  win_width=PApplet.parseInt(b.width*0.4f/DIV);

  x=b.width/2;
  y=PApplet.parseInt(random(b.height-win_height)/2+b.height/2);
  last_x=x;
  last_y=y;
  
  last_zoom=4.0f;
  target_zoom=1.0f;

  frameRate(24);

  // for frameRate display
  fontA = loadFont("CourierNew36.vlw");
  textFont(fontA, 32);

  if(writeToFile) {
    // setup up timing log file
    output = createWriter(outpath+"timing.txt");
  };
}

public void hist_eq(PImage in) {
  
  // equalize histogram to maximize contrast
  in.loadPixels();
  int dimension = (in.width*in.height);

  // create histogram
  int [] hist = new int[256];
  for(int i=0;i<dimension;i++) {
    int argb=in.pixels[i];

    int bin_a = argb & 0xFF000000;
    int r = (argb >> 16) & 0xFF;  // Faster way of getting red(rgb)
    int g = (argb >> 8) & 0xFF;   // Faster way of getting green(rgb)
    int b = argb & 0xFF;          // Faster way of getting blue(rgb)

    int intensity=round((r+g+b)/3.0f);

    hist[intensity]++;
  };
  
  // create cumulative distribution function
  // record min + max
  int [] cdf = new int[256];
  int sum=0;
  int min_cdf=0;
  int max_cdf=0;
  boolean found_min=false;
  boolean found_max=false;
  
  for(int i=0;i<256;i++) {
    sum+=hist[i];
    cdf[i]=sum;
    if((found_min==false) && (sum>0))
    {
      min_cdf=i;
      found_min=true;
    };
    if((found_max==false) && (sum>=dimension))
    {
      max_cdf=i;
      found_max=true;
    };
  };

  // loop over pixels and replace with equalized vals
  for(int i=0;i<dimension;i++) {
    int argb=in.pixels[i];

    int a = (argb >> 24) & 0xFF;
    int r = (argb >> 16) & 0xFF;  // Faster way of getting red(rgb)
    int g = (argb >> 8) & 0xFF;   // Faster way of getting green(rgb)
    int b = argb & 0xFF;          // Faster way of getting blue(rgb)

    // intensity normalization equation from
    // http://en.wikipedia.org/wiki/Histogram_equalization
    a = (a >> 1) << 24;
    r = constrain(PApplet.parseInt(norm(r, min_cdf, max_cdf)*255), 0, 255) << 16;
    g = constrain(PApplet.parseInt(norm(g, min_cdf, max_cdf)*255), 0, 255) << 8;
    b = constrain(PApplet.parseInt(norm(b, min_cdf, max_cdf)*255), 0, 255);
    int new_rgb = a | r | g | b;
    in.pixels[i]= new_rgb;
  };
  in.updatePixels();
};


public void draw() {
 
  if(t > saccade_length) {
    last_zoom=target_zoom;
    target_zoom=random(0.5f, 6.0f);
    last_x=x;
    last_y=y;
    r=win_width/target_zoom+random(0, win_width/target_zoom);
    theta=(TWO_PI+HALF_PI*random(-0.95f, 0.95f))%TWO_PI;
    t=0.0f;
  };

  // update motion
  t=t+d_t;

  curr_r=lerp(0, r, (t/saccade_length));
  curr_zoom=1.0f;//lerp(last_zoom, target_zoom, (t/saccade_length));

  x=last_x+(cos(theta)*curr_r);
  y=last_y+(sin(theta)*curr_r);
   
  //println("t: "+t+" r: "+curr_r+" z: "+curr_zoom);

  y=constrain(y, 0, b.height-win_height);
  // end condition
  if(x+win_width>b.width) {
    if(writeToFile) {
      output.flush(); // Writes the remaining data to the file
      output.close(); // Finishes the file
    };
    exit();
  };
  
  c = b.get(round(x), round(y), round(win_width*curr_zoom), round(win_height*curr_zoom));
  hist_eq(c);

  blend(c, 0, 0, win_width, win_height, 0, 0, width, height, BLEND);

  if(writeToFile) {
    saveFrame(outpath+"03_washington dc bedroom 2-#####.tif");
    output.println(frameCount+" "+millis());
  };
}

  static public void main(String args[]) {
    PApplet.main(new String[] { "--bgcolor=#F0F0F0", "histogram_eq" });
  }
}
