import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;

import vxp.PixelSource;
import vxp.QTLivePixelSource;
import vxp.VideoListener;

/**
 * @author Dan O'Sullivan
 * Modified by Rich Hauck
 * A Simple Example for tracking Color.  Looking for the brightest, closest to white color and makes black. Perlin Noise changes background.
 */
public class MidtermFinal extends JFrame implements MouseListener, VideoListener, KeyListener { 
    static int kHeight = 240;
    static int kWidth = 320;
    int threshold = 15;
    static JFrame frame;
    PixelSource ps;
    BufferedImage videoImage;
    Graphics g;
    //variables grabbed from newFrame();
    int[] rgb;
    int[] prgb;
    int[] scratchPad;
    //from processing
    int noiseVal;
    float noiseScale=0.02f;
    int i;

    public static void main(String[] args) {
        frame = new MidtermFinal();
        //extension from JFrame
        frame.setTitle(frame.getClass().getName());
        frame.setSize(kWidth, kHeight);
        frame.setLocation(100,100);
        frame.setVisible(true);
    }

    MidtermFinal() { //constructor
        ps = new QTLivePixelSource(kWidth, kHeight, 120); //30 frames/second, make it bigger if you are getting lag
        //	ps.videoSettings();  //in case you want to pick the camera etc...
        ps.addVideoListener(this);
        addMouseListener(this);
        addKeyListener(this);
    }

    public void newFrame() { //called for me by pixel source
        ps.grabFrame();
        //int[] rgb;
        //int[] prgb;

        int actualWidth = ps.getVideoWidth();  //sometimes the width you get is slightly different than the width you asked for
        /*int[]*/ scratchPad = (int[]) ps.getPixelArray().clone();  
       //need a scratchPad because we are setting pixels and then testing
        for (int row = 1; row < kHeight; row++) {
            //REPEAT FOR EACH ROW OF PIXELS
            for (int column = 1; column < actualWidth; column++) {
                //REPEAT FOR EACH PIXEL IN THE ROW
                rgb = ps.getPixel(scratchPad,column, row);
                prgb = ps.getPixel(scratchPad,column-1,row);
                int diff = Math.abs(rgb[1] - prgb[1]) ;//+ Math.abs(rgb[2] - prgb[2]) + Math.abs(rgb[3] - prgb[3]) ;
                if (diff > threshold) {
                    ps.setPixel(column,row,0,0,0,255);

                }else{
                    ps.setPixel(column,row,255,255,255,255);
                }
            }//END FOR EACH PIXEL IN A ROW
        }//END FOR EACH ROW OF PIXELS
        videoImage = ps.getImage();
        repaint();
    }

    public void update(Graphics g) { //overide java's clean up of the screenbecaus you are fill the screen anyway, faster, less flicker
        i++;
        paint(g);
    }

    public void paint (Graphics g){
        g.setColor(Color.black);
        g.fillRect(0,0,320,240);
       for (int row = 1; row < 240; row+=20) {
            for (int column = 1; column < 320; column+=20) {
                int noiseVal = (int) Math.round(PerlinNoise.noise((i+row)*noiseScale,(i+column)*noiseScale)*15);
                rgb = ps.getPixel(scratchPad,column, row);
                int R = rgb[1];
                int G = rgb[2];
                int B = rgb[3];
                Color pixelColor = new Color (R, G, B); 
                drawRect(g, column, row, pixelColor, noiseVal);
            }
            }
    }
    public void drawRect(Graphics g, int _y, int _x, Color c, int _s) {
         g.setColor(c);
    		g.fillRect(_y,_x,10-_s,10-_s);
    }
    public void shutDown() {
        ps.killSession();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
    }
  
    /////All of these are methods that I promised to put in when I said I was a mouselister, as you can see most of them are empty promises
    //actually "WindowListener" would be better, save mouseClicked for something else
    public void mouseClicked(MouseEvent mEvent) {}
    public void mouseEntered(MouseEvent arg0) {}
    public void mouseExited(MouseEvent arg0) {}
    public void mousePressed(MouseEvent arg0) {}
    public void mouseReleased(MouseEvent arg0) {}

    /* (non-Javadoc)
     * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
     */
    public void keyPressed(KeyEvent keyEvent) {
        String keyString = KeyEvent.getKeyText(keyEvent.getKeyCode());  //change the key code (a number) into regular text
        if (keyString.equals("Escape")|| keyString.toLowerCase().equals("q")){
            shutDown();
        }else if(keyString.equals("Up")){ //use arrow keys to adjust a variable
            threshold++;	
            put("Threshold:"+ threshold);
        }else if(keyString.equals("Down")){
            threshold--;
            put("Threshold:"+ threshold);
        }
    }
    public void put(String s){  //convenience because I hate typing that "System.out.println"  
        System.out.println(s);
    }
    public void keyReleased(KeyEvent arg0) {}
    public void keyTyped(KeyEvent arg0) {}

    /*code for not having all these empty stubs hanging around
    addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent e) {
                   shutDown();
            }
    });
    */



}


