//@width 640
//@height 560
import javax.swing.*;
import objectdraw.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;

import cs134lib.*;

/*
 * A program to apply a Threshold transformation to an image.
 * See the adjustPixelArray method for the actual
 * transformation code.
 */
public class Threshold extends WindowController implements ActionListener, ChangeListener, VideoCameraListener {

  private static final int WINDOW_WIDTH = 640;
  private static final int WINDOW_HEIGHT = 560;

  // the image loaded from the harddrive, as well
  // as the visible image where we are showing it.
  private VisibleImage display;
  private Image original;

  // an adjustment slider and label to show the current
  // setting
  public JSlider slider;
  private JLabel label;
  
  // controls for the video camera
  private JButton camera;
  private JButton video;
  private VideoCamera videoCamera;

  public void begin() {
    original = getImage("gray-1.jpg");
    display = new VisibleImage(original, 0, 0, canvas);

    this.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);

    slider = new JSlider(0, 255, 255);
    label = new JLabel("Value (" + slider.getMinimum() + "-"
                                + slider.getMaximum() + "): " + slider.getValue(), JLabel.LEFT);
    camera = new JButton("Take Snapshot");
    video = new JButton("Action!");

    slider.addChangeListener(this);
    camera.addActionListener(this);
    video.addActionListener(this);

    JPanel p = new JPanel(new GridLayout(1,2));
    Container contentPane = this.getContentPane();
    p.add(slider);
    p.add(label);

    JPanel buttons = new JPanel();
    buttons.add(camera);
    buttons.add(video);

    contentPane.add(p, BorderLayout.SOUTH);
    contentPane.add(buttons, BorderLayout.NORTH);

    contentPane.validate();

    this.setImage(original);
  }

  public void stateChanged(ChangeEvent e) {
    label.setText("Value (" + slider.getMinimum() + "-"
                                + slider.getMaximum() + "): " + slider.getValue());
    this.adjustImage();
  }

  /*
   * Convert original Image to array, adjust it, and
   * then convert it back to an Image.
   */
  private void adjustImage() {
    int[][] pixels = Images.imageToPixelArray(original);    
    int[][] newPixels = this.adjustPixelArray(pixels);
    Image newImage = Images.pixelArrayToImage(newPixels);
    display.setImage(newImage);
  }

  private int [][] adjustPixelArray(int [][] pixels) {
    for (int x = 0; x < pixels.length; x++) {
      for (int y = 0; y < pixels[0].length; y++) {
        if (pixels[x][y] < slider.getValue()) {
          pixels[x][y] = 0;
        } else {
          pixels[x][y] = 255;
        }
      }
    }
    return pixels;
  }
  
  
  
  /*
   * Snap a picture or start/stop the video camera
   */
  public void actionPerformed(ActionEvent e) {
    if (e.getSource() == camera) {
      Camera c = new Camera();
      this.setImage(c.getImage());
    } else if (e.getSource() == video) {
      if (videoCamera == null) {
        videoCamera = new VideoCamera(this);
        video.setText("Cut!");
      } else {
        videoCamera.cut();
        videoCamera = null;
        video.setText("Action!");
      }
    }
  }

  /*
   *  Used by the video camera to give us a new image
   *  to display.
   */
  public void setImage(Image theDisplay) {
    original = theDisplay;
    this.adjustImage();
  }


}
