// David Chamulak
// 3/3/03
// Simple program to show the Use of the a WebCam in Java

// Adapted by Nathaniel Brown and Chris Mordue for CSE477
// 6/10/04
// Displays the webcam, a grayscale versin and a rescaled version

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import jmfdemo.*;

public class Test extends Frame {
	private BufferedImage image1;
	private BufferedImage image2;
	private BufferedImage image3;
	private FrameGrabber vision1;
	
	private static String newline = System.getProperty("line.separator");

	public void paint(Graphics g) {
		if (image1 != null)
			g.drawImage(image1, 10, 30, this);
		if (image2 != null)
			g.drawImage(image2, 10, 500, this);
		if (image3 != null)
			g.drawImage(image3, 670, 500, this);
	}

	public void update(Graphics g) {
		paint(g);
	}

	class WindowListener extends WindowAdapter {
		public void windowClosing(WindowEvent e) {
			System.exit(0);
		}
	}

	public Test() {
		addWindowListener(new WindowListener());
		setTitle("JMF Camera Test");
		try {
			vision1 = new FrameGrabber();
			vision1.start();
		}
		catch(FrameGrabberException fge) {
			System.out.println(fge.getMessage());
		}
		image1 = vision1.getBufferedImage();
		image2 = proces(image1);
		image3 = ResizeImage(image2, image2.getWidth()/3, image2.getHeight()/3);
		
		setSize(image1.getWidth(this) + image3.getWidth(this)+ 50, image1.getHeight(this) + image2.getHeight(this)+ 70);
		setVisible(true);
		setBackground(Color.black);
	
		//write image to text file as hex values to then be sent to FPGA for resizeing
		try {
			FileWriter fileout = new FileWriter("imageTest.txt");
			for(int loop1 = 0; loop1 < image2.getHeight(this); loop1++) {
				for(int loop2 = 0; loop2 < image2.getWidth(this); loop2++) {
					Color pixel = new Color(image2.getRGB(loop2,loop1));
					int gray = (pixel.getRed() + pixel.getBlue() + pixel.getGreen())/3;
					String s = Integer.toHexString(gray);
					if(s.length() == 1) {
						s = "0"+s;
					}
					s = s +" "+ s;
					fileout.write(s+" ");
					fileout.write(newline);
				}
		
			}
			fileout.flush();
		}catch (IOException ioe) {
					System.out.println(ioe.getMessage());
		}

		while(true) {
			image1 = vision1.getBufferedImage();
			image2 = proces(image1);
			image3 = ResizeImage(image2, image2.getWidth()/2, image2.getHeight()/2);
			repaint();
			try {
				Thread.sleep(1);
			} catch(Exception e) {
				System.out.println("Doh");
			}
		}
	}

	//Function To create the grayscale Image
	private BufferedImage proces(BufferedImage x) {
		BufferedImage temp = new BufferedImage(x.getWidth(this), x.getHeight(this), BufferedImage.TYPE_BYTE_GRAY);
		ColorConvertOp op =  new ColorConvertOp(x.getColorModel().getColorSpace(), temp.getColorModel().getColorSpace(), null);
		return op.filter(x, temp);//temp;
	}
	
	//Resizes the image
 	private BufferedImage ResizeImage(BufferedImage x, int newWidth, int newHeight) {

		 int old_numRows = x.getHeight();
		 int old_numCols = x.getWidth();
		 int new_numRows = newHeight;
		 int new_numCols = newWidth;
		
		 int s_old_numRows = old_numRows << 5;
		 int s_old_numCols = old_numCols << 5;
	
		 int s_oldtonew_Rows = s_old_numRows / new_numRows;
		 int s_oldtonew_Cols = s_old_numCols / new_numCols;
	
		 int s_cur_oldRow;
		 int s_cur_oldCol;
		 
		 BufferedImage temp = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);

		 int r, c, i, addr;
	
		 s_cur_oldRow = s_oldtonew_Rows >> 1;
	
		 i = 0;
	
		 for (r = 0; r < new_numRows; r++) {
	
			 s_cur_oldCol = s_oldtonew_Cols >> 1;
	
			 for (c = 0; c < new_numCols; c++) {
	
				 addr = (s_cur_oldCol >> 5) + old_numCols*(s_cur_oldRow >> 5);
				 Color pixel = new Color(x.getRGB((s_cur_oldCol >> 5),(s_cur_oldRow >> 5)));
				 int gray = (pixel.getRed() + pixel.getBlue() + pixel.getGreen())/3;
				 int [] pix = {gray, gray, gray};
				 temp.getRaster().setPixel(c, r, pix);
				 s_cur_oldCol += s_oldtonew_Cols;
				 i ++;
			 }
			
			 s_cur_oldRow += s_oldtonew_Rows;
		 }
		 return temp;
 	}

	public static void main(String[] args) {
		new Test();
	}
}