// Allsky meteor capture for DMK camera

// - AGW - 20130426  Processig.org v2.0b8

// modified from

/**

 * Getting Started with Capture.

 *

 * Reading and displaying an image from an attached Capture device.

 */

import processing.opengl.*;

import processing.video.*;

Capture cam;

int x;

int y;

int gx = 0;

int gy = 50;

float outerRad;

float innerRad;

int cx, cy;

float timestep = 200.0 ;

int theta = 0;

int scl = 1;

float sscl = 0.01;

int msens = 128 ;

int gridstatus = 0;

int maskstatus = 1 ;

int compassstatus = 1 ;

int zoomstatus = 0 ;

int saveimgstatus = 0;

int btrackstatus = 1;

//

int brightestX = 0; // X-coordinate of the brightest video pixel

int lstbrightestX = 0; // X-coordinate of the brightest video pixel

int brightestY = 0; // Y-coordinate of the brightest video pixel

int lstbrightestY = 0; // Y-coordinate of the brightest video pixel

float brightestValue = 0; // Brightness of the brightest video pixel

float lastbrightestValue = 0; // Brightness of the brightest video pixel

int pixelValue = 0 ;

int lastpixelValue = 0 ;

float pixelBrightness = 0.0;

float lastpixelBrightness = 0.0;

float pixeldiff = 0.0;

int ftime = millis() ;

int difftrig = 0 ;

float diffval =0.0;

//

int numPixels;

float[] lstpixvl = new float[150*150];

// time stuff here

String YYYY = "2012" ;

String DMM = "12" ;

String DD = "31" ;

String LHH = "00" ;

String UHH = "00" ;

int TMZ = 10 ; // set time zone here for UTC

int DSV = 0 ; // set daylight saving offset

String TMM = "00" ;

String SS = "00" ;

String YYYYMMDD = "20121022" ;

String LHHMMSS = "00:00:00" ;

String UHHMMSS = "00:00:00" ;

String Fname = "20121021_000000" ;

//

PFont fontA = createFont("SanSerif", 12);

PFont fontB = createFont("SanSerif", 16);

//

void setup() {

  size(640*3/2,480*3/2, OPENGL);

  //frameRate(30);

  String[] cameras = Capture.list();

 

  if (cameras.length == 0) {

    println("There are no cameras available for capture.");

    exit();

  } else {

    println("Available cameras:");

    for (int i = 0; i < cameras.length; i++) {

      println(i+" "+cameras[i]);

    }

   

    // The camera can be initialized directly using an element

    // from the array returned by list():

    cam = new Capture(this, cameras[29]);

    //29 name=The Imaging Source Europe GmbH DMK 51AU02.AS,size=1600x1200,fps=12

    // set gamma = 255 set exposure = 1/6 sec set gain = 255

    cam.start();    

  }

 

  //trialgestrip

  x = width/2;

  y = height/2-15;

  outerRad = min(width, height) * 0.9;

 // innerRad = outerRad * 0.50+sscl;

   cx = width/2-10;

   cy = height/2-10;

  //

   currentDT(); // get time now

}

void draw() {

 // background(0);

  strokeWeight(0);

  fill(0);stroke(0);

  //PImage lastgc = get(0,0,150,150);

  if (cam.available() == true) {

    cam.read();

        }

  image(cam, 0, 0, width, height);

  innerRad = outerRad * (0.50+sscl);

   //

       if ( maskstatus == 1 ) { drawmask(); }

       if ( compassstatus == 1) { compass(); }

       if (gridstatus == 1) { gridon(); }  // square grid switch

       if ( zoomstatus == 1 ) {  mzoom(); }

  //

 brightestValue = 0;

 userinfo();

 //

 blend(170,40,600,600,0,0,150,150,BLEND);

 PImage gc = get(0,0,150,150);

//

 if ( btrackstatus == 1 ) {

 //lastgc.loadPixels();

 gc.loadPixels(); // small search image at top left

 

   // Search for the brightest pixel: For each row of pixels in the video image and

   // for each pixel in the yth row, compute each pixel's index in the video

   //

    int index = 0;

    for (int y = 0; y < gc.height; y++) {

      for (int x = 0; x < gc.width; x++) {

        // Get the color stored in the pixel

        pixelValue = gc.pixels[index];

     // Determine the brightness of the pixel

        pixelBrightness = brightness(pixelValue);

       //

       // check for frametoframe brightness diff for low level meteors

       if ( ( pixelBrightness-lstpixvl[index]) > msens ) {

         difftrig = 1 ; diffval = pixelBrightness-lstpixvl[index];

         lstbrightestX = x;

         lstbrightestY = y;

           }

        // If that value is brighter than any previous, then store the

        // brightness of that pixel, as well as its (x,y) location

        if (pixelBrightness > brightestValue) {

          brightestValue = pixelBrightness;

          brightestY = y;

          brightestX = x;

          }

         //

         strokeWeight(1);stroke(brightestValue);

         fill(255, 204, 0, 64);

         line(0,160+x,scl+pixelBrightness/2,160+x);

         strokeWeight(0);stroke(0);  

         lstpixvl[index] = pixelBrightness;

         

        index++;

      }

     

     }

     

    // Draw a large, yellow circle at the brightest pixel

    fill(255, 204, 0, 128);

    ellipse(brightestX, brightestY, 10, 10);

    text("Difftrg: "+diffval+"\nMsns:"+msens+"\nBv: "+brightestValue+"\nX: "+brightestX+"\nY: "+brightestY+"\nA: "+theta, 190, 30);

    rectMode(CENTER);

    strokeWeight(1);

    fill(255, 204, 0, 64);

   // rect(170+(brightestX*4), 40+(brightestY*4), 20, 20);

    rect(170+(lstbrightestX*4), 40+(lstbrightestY*4), 10, 10);

    rectMode(CORNER);

    updatePixels();

   //

   // check if brightest location moves

    /*  if (brightestY != lstbrightestY ) {

      saveimg();

      brightestValue = 0;

       lstbrightestY = brightestY;

      //lstbrightestX = brightestX;

     

    }   */

   if ( difftrig >0 ) {

       saveimg();

       difftrig = 0 ;

       print("\nDIFF-TRIG "+lstbrightestX+" "+lstbrightestY+" "+diffval);

     }

 }

   // save one frame evey 55th second

    if ( second() == 55 ){ saveimg(); }

   ftime = 0 ;

   }

 

void keyPressed() {

  //

  if (key =='x') { exit(); }

  if (key =='c') { background(0); }

  if (key =='[') { scl-=1 ;  print(scl+"\n");if (scl <= 0) {scl = 1;}}

  if (key ==']') { scl+=1 ; print(scl+"\n"); if (scl >= 150) { scl = 150;}}

  if (key =='-') { timestep-=100 ; if (timestep <= -1000) {timestep = -1000;}}

  if (key =='=') { timestep+=100 ; if (timestep >= 1000) { timestep = 1000;}}

  if (key ==',') { theta-=1 ; if (theta <= -360) {theta = -360;}}

  if (key =='.') { theta+=1 ; if (theta >= 360) { theta = 360;}}

  if (key =='l') { sscl-=0.01 ;  print(sscl+"\n");if (sscl <= -1.00) {sscl = -1.00;}}

  if (key =='k') { sscl+=0.01 ; print(sscl+"\n"); if (sscl >= 1.00) { sscl = 1.00;}}

  if (key =='q') { msens-=1 ;  print(msens+"\n");if (msens <= 1) {msens = 1;}}

  if (key =='w') { msens+=1 ; print(msens+"\n"); if (msens >= 255) { msens = 255;}}

 

  //

  if (key =='i') {saveimg(); }

  if (key =='g') {if (gridstatus == 1) { gridstatus =0;} else {gridstatus =1;} }

  if (key =='c') {if (compassstatus == 1) {compassstatus =0;} else {compassstatus =1;} }

  if (key =='m') {if (maskstatus == 1) { maskstatus =0;} else {maskstatus =1;} }

  if (key =='z') {if (zoomstatus == 1) { zoomstatus =0;} else {zoomstatus =1;} }

  if (key =='s') {if (saveimgstatus == 1) { saveimgstatus =0;} else {saveimgstatus =1;} }

  if (key =='b') {if (btrackstatus == 1) { btrackstatus =0;} else {btrackstatus =1;} }

}

void drawmask() {

 

int pts = int(map(width, 0, width, 6, 60));

  float rot = 180.0/pts;

  float angle = 0.0;

 ///*

  beginShape(TRIANGLE_STRIP);

  fill(0);

  for (int i = 0; i <= pts; i++) {

    float px = x + cos(radians(angle)) * outerRad;

    float py = y + sin(radians(angle)) * outerRad;

    angle += rot;

    vertex(px, py);

    px = x + cos(radians(angle)) * innerRad;

    py = y + sin(radians(angle)) * innerRad;

    vertex(px, py);

    angle += rot;

  }

  endShape();

   endShape();

  strokeWeight(0);

  fill(0);stroke(0);

  //

}

 

void compass(){

   // Draw the minute ticks

  strokeWeight(2);

  fill(255, 204, 0, 128);

  beginShape(POINTS);

  for (int a = 0; a < 360 ; a+=6) {

    float tangle = radians(90-a+theta);

    float x = cx + cos(tangle) * innerRad*1.03;

    float y = cy + sin(tangle) * innerRad*1.03;

    vertex(x, y);

    text(a,x,y);

    if (a == 0) { textFont(fontB,16); text("\n\bN",x,y); }

    if (a == 90) {textFont(fontB,16); text("\n\bE",x,y); }

    if (a == 180) {textFont(fontB,16); text("\n\bS",x,y); }

    if (a == 270) { textFont(fontB,16);text("\n\bW",x,y); }

    textFont(fontA, 12);

   

  }

  endShape();

  strokeWeight(0);

  fill(0);stroke(0);

}

 

void userinfo() {

  //

  fill(50, 100, 100);

  rect(width-115, 3, 110, 60);

  fill(255, 255, 255);

  textFont(fontB,16);

  currentDT() ;

  text(YYYYMMDD+"\nUTC:"+UHHMMSS+"\nLCL:"+LHHMMSS, width-110, 20 );

  //

 

  // control menu

  text("e[x]it "+"\n"+saveimgstatus+"[s]aveImg on/off"+"\n"+maskstatus+"[m]ask on/off\n[k]close/open[l]"+"\n"+compassstatus+"[c]ompass on/off"+"\n"+gridstatus+"[g]rid on/off"+"\n[<]North[>]",width-120,80);

  textFont(fontA, 12);

}

void currentDT() {

  // current date here

  DD = nf(day(), 2);     // Values from 1 - 31

  DMM = nf(month(), 2);  // Values from 1 - 12

  YYYY = nf(year(), 2);  // 2003, 2004, 2005, etc.

  // current time here

  UHH = nf((hour()-TMZ-DSV), 2) ;    // Values from 0 - 23

  LHH = nf((hour()), 2) ;    // Values from 0 - 23

  TMM = nf(minute(), 2) ; // Values from 0 - 59

  SS = nf(second(), 2) ;  // Values from 0 - 59

  //

 

  //

  YYYYMMDD = YYYY+DMM+DD ; // "20121022" ;

  UHHMMSS = UHH+":"+TMM+":"+SS ; // UTC time "00:00:00" ;

  LHHMMSS = LHH+":"+TMM+":"+SS ; // Local system tiem "00:00:00" ;

  Fname = YYYY+DMM+DD+"_"+UHH+TMM+SS ; // file name UTCtime stamp

  //

   

}

void saveimg() {  

      // save image to \data\meteor as filename_Fptfreq_Mdate_UTC.jpg

      // remove the // from next line to save an image of trigger event

       if ( saveimgstatus == 1 ) {  

      ftime = millis() ;

      saveFrame("\\data\\meteor\\"+Fname+"_"+ftime+".png");

      saveFrame("\\data\\LastSave.jpg");

      print("\nSaved image "+Fname+"_"+ftime)  ;

      text("Saved Image ...."+Fname+"_"+ftime , width/2, height-20);  

      ftime = 0 ;

   }

}

   

void gridon() {

  //

   noFill();strokeWeight(1);stroke(75);

 for ( int grd =0 ; grd < 620; grd+=(20)) {

  rect(x-300,y-300, grd, grd);

  rect(x+300,y+300, -grd, -grd);

  //point(x-300+grd,y-300+grd);

 }

  strokeWeight(0);

  fill(0);stroke(0);

}

void mzoom() {

  copy(mouseX-75, mouseY-75,150,150, 0,height-150, 150, 150);

  noFill(); stroke(255);strokeWeight(1);

  rect(1,height-150,150,150);

  rect(1,height-150,85,85,0,0,10,0);

  rect(150,height,-85,-85,10,0,0,0);

  fill(255);

  text("X: "+mouseX+"\nY: "+mouseY+"\nA:" +theta, 155, height-150);

}