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

import cs134lib.*;

/*
 * An Edge detection transformation.  See Threshold.java for details
 * of the class structure.
 */
public class Edges extends WindowController implements ActionListener, ChangeListener, VideoCameraListener {

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

  private VisibleImage display;
  private Image original;

  public JSlider slider;
  private JLabel label;
  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 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!");
      }
    }
  }

  public void setImage(Image theDisplay) {
    original = theDisplay;
    this.adjustImage();
  }

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

  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) {
    int threshold = slider.getValue();
    for (int x = 0; x < pixels.length -1; x++) {
      for (int y = 0; y < pixels[0].length -1; y++) {
        if ( Math.abs(pixels[x][y] - pixels[x+1][y]) > threshold ||
             Math.abs(pixels[x][y] - pixels[x][y+1]) > threshold ) {
          pixels[x][y] = 0;
        } else {
          pixels[x][y] = 255;
        }
      }
    }
    return pixels;
  }

}
