package visual.statik.sampled;

import java.awt.*;
import java.awt.event.*;
import java.awt.color.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;
import javax.imageio.*;
import javax.swing.*;

import app.*;
import io.*;


/**
 * An example that illustrates the processing of
 * sampled static visual content
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class      SurveillanceApp
       extends    AbstractMultimediaApp
       implements ActionListener
{

    private BeforeAndAfterCanvas                 canvas;       
    private BufferedImage                        after, before;    
    private Hashtable<String, BufferedImageOp>   ops;
    private IdentityOp                           identityOp;
    private Image                                original;    
    private ImageFactory                         imageFactory;       
    private JTextField                           angleField;    

    private static final Font DEFAULT_FONT = 
                              new Font("Sans Serif", Font.PLAIN, 11);
    


    /**
     * Default Constructor
     *
     */
    public SurveillanceApp()
    {
       super();    
       BufferedImageOpFactory   opFactory;
       
       opFactory       = BufferedImageOpFactory.createFactory();       
       imageFactory    = new ImageFactory();
       this.identityOp = new IdentityOp();

       
       ops = new Hashtable<String, BufferedImageOp>();

       ops.put("Sharpen",
               opFactory.createSharpenOp(3));

       ops.put("Zoom",
               opFactory.createScaleOp(2.0, 2.0));
    }


    /**
     * Handle actionPerformed messages
     * (required by ActionListener)
     *
     * @param evt   The ActionEvent that generated the message
     */
    public void actionPerformed(ActionEvent evt)
    {
       BufferedImageOp        op;
       String                 command;
       
       command = evt.getActionCommand();       

       if (command.startsWith("Crop"))
       {
          before = after;
          canvas.setBeforeImage(before);       
          after = crop(command, before);             
          canvas.setAfterImage(after);             
       }
       else if (command.startsWith("Reset"))
       {
          reset();
          canvas.setBeforeImage(before);       
          canvas.setAfterImage(after);             
       }
       else
       {
          op = ops.get(command);
          if (op == null) op = identityOp;
          
          before = after;
          canvas.setBeforeImage(before);       
          after = op.filter(before, null);
          canvas.setAfterImage(after);
       }
    }


    /**
     * Add a JButton
     *
     * @param p     The JPanel to add it to
     * @param text  The text of the JButton
     * @param x     The x-position
     * @param y     The y-position
     * @param width The width
     */
    private void addButton(JPanel p, String text, 
                           int x, int y, int width)
    {
       JButton      button;
       
       button = new JButton(text);
       button.addActionListener(this);       
       button.setBounds(x, y, width, 30);
       button.setFont(DEFAULT_FONT);       
       p.add(button);       
    }
    

    /**
     * Crop an image (to one of four quadrants)
     *
     * @param quadrant   The quadrant
     * @param before     The image to crop
     */
    private BufferedImage crop(String       quadrant,
                               BufferedImage before)
    {
       BufferedImage   cropped;       
       int             height, x, y, width;


       x      = 0;
       y      = 0;       
       width  = before.getWidth(); 
       height = before.getHeight();

       if         (quadrant.endsWith("NW"))
       {
          x      = 0; 
          y      = 0; 
          width  = width/2; 
          height = height/2;
       } 
       else if (quadrant.endsWith("NE"))
       {
          x      = width/2;
          y      = 0;
          width  = width/2;
          height = height/2;
       } 
       else if (quadrant.endsWith("SE"))
       {
          x      = width/2; 
          y      = height/2; 
          width  = width/2;
          height = height/2;
       }
       else if (quadrant.endsWith("SW"))
       {
          x      = 0; 
          y      = height/2;
          width  = width/2; 
          height = height/2;
       }

       //[crop.

       cropped = before.getSubimage(x, y, width, height);

       //]crop.

       return cropped;
    }


    /**
     * This method is called just before the main window
     * is first made visible
     */
    public void init()
    {
       Dimension                 size;       
       InputStream               is;       
       int                       x, y;       
       JPanel                    contentPane;       
       ResourceFinder            finder;
       String                    name;
       
       

       // Read the image
       original  = null;       
       finder    = ResourceFinder.createInstance();          
       name      = rootPaneContainer.getParameter("0");
       if (name == null) name = "/visual/statik/sampled/wilson-hall.gif";

       try
       {
          is = finder.findInputStream(name);
          if (is != null)
          {
             original = ImageIO.read(is);
             is.close();
          }
          reset();          
       }
       catch (IOException io)
       {
          // original will be null
       }

       // Create the component that will render the image
       canvas = new BeforeAndAfterCanvas();
       canvas.setBeforeImage(before);
       canvas.setAfterImage(after);       
       size   = canvas.getSize();       
       canvas.setBounds(0,0,(int)size.getWidth(),(int)size.getHeight());

       // Add the ImageCanvas to the main window
       contentPane = (JPanel)rootPaneContainer.getContentPane();
       contentPane.add(canvas);

       // Add the buttons to the content pane
       y = (int)size.getHeight() + 10;       
       addButton(contentPane, "CropNW",       0, y, 75);       
       addButton(contentPane, "CropNE",      80, y, 75);       
       addButton(contentPane, "CropSE",     160, y, 75);       
       addButton(contentPane, "CropSW",     240, y, 75);       
       addButton(contentPane, "Sharpen",    320, y, 75);       
       addButton(contentPane, "Zoom",       400, y, 75);       

       addButton(contentPane, "Reset",      560, y, 75);       
    }


    /**
     * Reset both the before and after image to
     * the original
     */
    private void reset()
    {
       before       = imageFactory.createBufferedImage(original);          
       after        = before;          
    }
}

