/**  RenderedImageManipulator1 Class
   * @version 1.0  18 apr 2000
   * @author Lawrence Rodrigues
   **/
package app;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.geom.*;
import com.vistech.util.*;
import com.vistech.jai.imageio.*;
import com.vistech.jai.render.*;

import java.awt.image.RenderedImage;
import java.beans.*;
import javax.media.jai.*;
import com.sun.media.jai.codec.*;
import java.awt.image.renderable.*;
import com.vistech.imageviewer.*;

/** An application that allows interactive image manipulation and image cropping.
  * @version 1.0 18 Apr 2000
  * @author Lawrence Rodrigues
  **/
public class RenderedImageManipulator1 extends TiledImageViewer{
   protected PanZoom panzoom;
   protected JButton resetb;
   protected ManipUI manippan;
   protected GeomManip manip;
   protected Crop crop;

   public void createUI() {
      int width, height;
      Dimension sd= Toolkit.getDefaultToolkit().getScreenSize();
      width = (int)(sd.width *3/4.0);
      height = (int)(sd.height*3/4.0);

      setTitle("JAI Image Manipulator");
      viewer = new CompositeCanvasJAI();
      Dimension d = new Dimension(width, height);//getViewerSize(width/(double)height);
      viewer.setPreferredSize(new Dimension(d.width, d.height));
      createImageLoaderAndSaver();
      loader.addPlanarImageLoadedListener(
          new PlanarImageLoadedListener() {
             public void imageLoaded(PlanarImageLoadedEvent e) {
                PlanarImage image = e.getImage();
                if(image == null) return;
                SwingUtilities.invokeLater(new ImagePaint(image));
             }
         }
      );

      twidth = new JTextField(10);
      theight = new JTextField(10);

      renderGrid = new RenderGrid();
      theight.setText(Integer.toString(viewer.getTileHeight()));
      twidth.setText(Integer.toString(viewer.getTileWidth()));

      manip =  new GeomManip((ImageManipulator)viewer);
      manippan = new ManipUI(manip);
      crop = new Crop((CompositeCanvasJAI)viewer);
      CropPanel croppan = new CropPanel(crop);
      //viewer.addMouseListener(crop);
      viewer.addMouseMotionListener(crop);
      MouseListener ml = AWTEventMulticaster.add(
                              (MouseListener)crop,
                              (MouseListener)croppan);

      viewer.addMouseListener(ml);
      JPanel gridpan = new JPanel();
      JPanel tilesetpan = createTileSetPanel();
      DisplayModePanel dispmodepan = new DisplayModePanel((ImageManipulator)viewer);
      FlipModePanel flipmodepan = new FlipModePanel(manip);
      InterpModePanel intermodepan = new InterpModePanel((ImageManipulator)viewer);


      JTabbedPane jtab = new JTabbedPane();
      jtab.add("Tile Size",tilesetpan);
      jtab.add("Interp Mode", intermodepan);

      jtab.add("Flip Mode",flipmodepan);
      jtab.add("Manip",manippan);
      jtab.add("Crop ",croppan);
      changeEventHandler(jtab);

      GridBagLayout gb = new GridBagLayout() ;
      GridBagConstraints c = new GridBagConstraints();
      gridpan.setLayout(gb);
      c.fill = GridBagConstraints.BOTH;
      c.gridwidth = GridBagConstraints.REMAINDER;
      c.weighty = 1.0; c.weightx = 1.0;
      gb.setConstraints(jtab, c);
      gridpan.add(jtab);
      resetb = new JButton("Reset");
      resetEventHandler();
      c.weighty = 0.1; c.weightx = 1.0;
      gb.setConstraints(resetb, c);
      gridpan.add(resetb);

      saver = new ImageSaverPanel();
      JTabbedPane jtp = new JTabbedPane();
      jtp.add("Load", flBrowser);
      jtp.add("Save",  saver);
      JSplitPane hsp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, jtp,gridpan);
      JSplitPane vsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, hsp,viewer);
      getContentPane().setLayout(new GridLayout(1,1));
      getContentPane().add(vsp);
      pack();
      setSize(new Dimension(d.width+170, d.height));
      show();
      addEventAdapters();
      panzoom = new PanZoom((ImageManipulator)viewer);
      hsp.setDividerLocation(0.6);
      vsp.setDividerLocation(0.35);
      hsp.setDividerSize(5);
      vsp.setDividerSize(6);
      viewer.repaint();
   }

   protected void resetEventHandler(){
      resetb.addActionListener(
         new ActionListener(){
            public void actionPerformed(ActionEvent e) {
               ((ImageManipulator)viewer).resetManipulation();
               manippan.resetManipulation();
             }
          }
       );
   }

   protected void changeEventHandler(JTabbedPane jt) {
      final JTabbedPane jtp = jt;
      jtp.addChangeListener(
         new ChangeListener() {
               public void stateChanged(ChangeEvent e) {
                  Component cmp = jtp.getSelectedComponent();
                  if(cmp == null) { return;}
                  if(cmp instanceof TabPanel) {
                     TabPanel tp = (TabPanel)cmp;
                     tp.openPanel();
                  }
                  int ind = jtp.getSelectedIndex();
                  String tabname = jtp.getTitleAt(ind);
                  if(tabname.equals("Manip")) {
                     panzoom.setPanZoomOn(true);
                     crop.setCropOn(false);
                  }
               }
         }
      );
   }

   public static void  main(String[] args){
      RenderedImageManipulator1 ip = new RenderedImageManipulator1();
      if(args.length <1) {
         ip.createUI();
      }else ip.loadAndDisplay(args[0]);
  }

class CropPanel extends JPanel implements TabPanel, MouseListener{
   Crop crop;
   PlanarImage origImage;

   public CropPanel(Crop cr){
      crop = cr;
      createUI();
   }
   public void mouseReleased(MouseEvent e) {
      PlanarImage img = viewer.getDisplayImage();
      saver.setDisplayImage(img);
   }
   public void mousePressed(MouseEvent e) {}
   public void mouseClicked(MouseEvent e){}
   public void mouseEntered(MouseEvent e){}
   public void mouseExited(MouseEvent e){}
   public void openPanel() {
      crop.setCropOn(true);
      panzoom.setPanZoomOn(false);
      origImage = viewer.getImage();
   }
   public void closePanel(){
      panzoom.setPanZoomOn(true);
   }

   protected void createUI() {
      JButton uncrop = new JButton("Undo Crop");
      uncrop.addActionListener(
         new ActionListener() {
           public void actionPerformed(ActionEvent e) {
              crop.reset();
              if(origImage != null) viewer.setImage(origImage);
           }
        }
      );
      JToggleButton cropb = new JToggleButton("Crop");
      cropb.addActionListener(
         new ActionListener() {
           public void actionPerformed(ActionEvent e) {
              JToggleButton jt =  (JToggleButton)e.getSource();
              boolean state = jt.isSelected();
              crop.setCropOn(state);
              if(state) {
                 jt.setText("Crop");
                 panzoom.setPanZoomOn(false);

              }
              else {
                 jt.setText("Pan/Zoom");
                 ((CompositeCanvasJAI)viewer).eraseShapes();
                 PlanarImage dispImage = viewer.getDisplayImage();
                 if(dispImage!= null) viewer.setImage(dispImage);
                 panzoom.setPanZoomOn(true);
              }
           }
        }
      );
      cropb.setSelected(true);
      JTextArea textArea = new JTextArea(2, 15);
      textArea.setBackground(Color.black);
      textArea.setForeground(Color.green);
      textArea.setText("To crop the image, drag the mouse over the image \n" +
                       "To pan/zoom the image, toggle the Crop button \n"+
                       "To Save the cropped image, select the Save tab");
      JPanel crpanel = new JPanel(new FlowLayout());
      crpanel.add(cropb);
      crpanel.add(uncrop);
      crpanel.setBorder(BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
      setLayout(new GridLayout(2,1));
      add( crpanel);
      add(textArea);
   }
 }

}

