/**  WarpApp 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 javax.media.jai.operator.*;

import java.awt.image.renderable.*;
import com.vistech.imageviewer.*;
import com.vistech.jai.util.*;
import com.vistech.listselect.*;

/** A sample application that demonstrates image warping. 
  * @version 1.0 18 Apr 2000
  * @author Lawrence Rodrigues
  **/

public class WarpApp extends TiledImageViewer{
  
   protected JButton resetb;
   protected ManipUI manippan;
   protected FileSelector  flSelector;
   protected RenderedImageCanvas sourceCanvas,destCanvas;
   protected int loadCount =0;
   protected PlanarImage sourceImage;
   protected JSplitPane vsp, hsp, vp;
   private WarpImageGenerator warpgen;

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

      setTitle("Image Warp");
      viewer = new ImageManipulatorCanvas();
      
      sourceCanvas = new ImageManipulatorCanvas();
      destCanvas = new ImageManipulatorCanvas();

      JSplitPane vp = createImagePanel();
      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, sourceCanvas));
                   sourceImage = image;
             }
         }
      );

      JPanel warpsetpan = createWarpsetPanel();

      warpgen = new WarpImageGenerator();

      MouseListener ml = AWTEventMulticaster.add(
                              (MouseListener)warpgen,
                          new MouseAdapter() {
                             public void mousePressed(MouseEvent e){
                                PlanarImage img = warpgen.getDestImage();
                                if(img != null) destCanvas.setImage(img);

                             }  
                          }
      );

      sourceCanvas.addMouseListener(ml);

      saver = new ImageSaverPanel();
      JTabbedPane jtp = new JTabbedPane();

      jtp.add("Load", flSelector);
      jtp.add("Save",  saver);
      hsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, jtp,warpsetpan);
      vsp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, vp,hsp);
      getContentPane().setLayout(new GridLayout(1,1));
      getContentPane().add(vsp);
      pack();
      setSize(new Dimension(d.width+170, d.height));
      show();
      vsp.setDividerLocation(0.65);
      hsp.setDividerLocation(0.5);
      vp.setDividerLocation(0.5);
      hsp.setDividerSize(5);
      vsp.setDividerSize(6);
      viewer.repaint();
   }

   protected void createNewLayout() {
      Dimension size = this.getSize();
      vp = createImagePanel();
      Dimension vspsize = vsp.getSize();
      vsp.setTopComponent(vp);
      vsp.setSize(vspsize);
      show();
      vsp.setDividerLocation(0.65);
      vp.revalidate();
      vsp.revalidate();
      hsp.setDividerSize(5);
      vsp.setDividerSize(6);
      repaint();
   }

   protected JPanel createWarpsetPanel() {
      JPanel pane = new JPanel();
      JLabel deglab = new JLabel("Polynomial degree");
      JTextField degfield = new JTextField(3);
      degfield.addActionListener(  
        new ActionListener() {
          public void actionPerformed(ActionEvent e){
             try{
                JTextField tf = (JTextField)e.getSource();
                int deg = Integer.parseInt(tf.getText());
                warpgen.setPolyDegree(deg);
             }catch(Exception e1){}
          }
        }
      );
      pane.add(deglab);
      pane.add(degfield);
      return pane;
   }
  
  protected JSplitPane createImagePanel() {
      JScrollPane jsp1 = new JScrollPane(sourceCanvas);
      JScrollPane jsp3 = new JScrollPane(destCanvas);
      jsp3.setBorder(BorderFactory.createTitledBorder("Resulting Image"));
      jsp1.setBorder(BorderFactory.createTitledBorder("Source Image"));
      JSplitPane vp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, jsp1,jsp3);
      return vp;
  }

 
   protected void createImageLoaderAndSaver(){
      loader = new ImageLoaderJAI();//flBrowser.getLoader(
      flSelector = new FileSelector();
      flSelector.addListSelectListener(loader);
      saver = new ImageSaverPanel();
      saver.setBorder(BorderFactory.createTitledBorder("Image Save"));
   }
   
   public static void  main(String[] args){
      WarpApp ip = new WarpApp();
      if(args.length <1) {
         ip.createUI();
      }else ip.loadAndDisplay(args[0]);
  }
   class ImagePaint implements Runnable {
      PlanarImage image;
      boolean firstTime = true;
      RenderedImageCanvas viewer;
      public ImagePaint(PlanarImage image, RenderedImageCanvas viewer){
         this.image = image;
         this.viewer = viewer;
      }
      public void run() {
         if(firstTime) {
            try {
            setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            viewer.setImage(image);
            warpgen.setSourceImage(image);
            saver.setImage(image);
            int wid = (image.getWidth() < 1024) ?image.getWidth(): 1024;
            int ht = (image.getHeight()) < 1024 ? image.getHeight():1024;
            viewer.setPreferredSize(new Dimension(wid,ht));
            viewer.repaint();
            firstTime = false;
            SwingUtilities.invokeLater(this);
            }catch(Exception e) {
             SwingUtilities.invokeLater(this);
            }
         }
         else {
            if(!viewer.isImageDrawn()) SwingUtilities.invokeLater(this);
            else  setCursor(Cursor.getDefaultCursor());
         }
      }
   }

}

