//@width 640
//@height 560

import javax.swing.*;
import objectdraw.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;

import cs134lib.*;


public class Clip 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 minSlider;
  private JLabel minLabel;
  public JSlider maxSlider;
  private JLabel maxLabel;
  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);

    minSlider = new JSlider(0, 255, 0);
    minLabel = new JLabel("Min (" + minSlider.getMinimum() + "-"
      + minSlider.getMaximum() + "): " + minSlider.getValue(), JLabel.LEFT);
    maxSlider = new JSlider(0, 255, 255);
    maxLabel = new JLabel("Max (" + maxSlider.getMinimum() + "-"
      + maxSlider.getMaximum() + "): " + maxSlider.getValue(), JLabel.LEFT);
    camera = new JButton("Take Snapshot");
    video = new JButton("Action!");

    minSlider.addChangeListener(this);
    maxSlider.addChangeListener(this);
    camera.addActionListener(this);
    video.addActionListener(this);

    JPanel p = new JPanel(new GridLayout(1,2));
    Container contentPane = this.getContentPane();
    p.add(minSlider);
    p.add(minLabel);
    p.add(maxSlider);
    p.add(maxLabel);

    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) {
    minLabel.setText("Min (" + minSlider.getMinimum() + "-"
      + minSlider.getMaximum() + "): " + minSlider.getValue());
    maxLabel.setText("Max (" + maxSlider.getMinimum() + "-"
      + maxSlider.getMaximum() + "): " + maxSlider.getValue());
    this.adjustImage();
  }

  private void adjustImage() {
    int[][] pixels = Images.imageToPixelArray(original);    
    int[][] newPixels = this.adjustPixelArray(pixels);
    Image newImage = Images.pixelArrayToImage(pixels);
    display.setImage(newImage);
  }

  private int [][] adjustPixelArray(int [][] pixels) {
    int min = minSlider.getValue();
    int max = maxSlider.getValue();

    for (int x = 0; x < pixels.length; x++) {
      for (int y = 0; y < pixels[0].length; y++) {
        if (pixels[x][y] < min) {
          pixels[x][y] = 0;
        } else if (pixels[x][y] > max) {
          pixels[x][y] = 255;
        } else {
          pixels[x][y] = (pixels[x][y] - min) * 255 / (max - min);
        }
      }
    }
    return pixels;
  }

}
