/** JAITiledImageViewer 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 displays renderable images. 
  * @version 1.0 18 Apr 2000
  * @author Lawrence Rodrigues
  **/

public class TiledRenderableImageViewer extends TiledImageViewer{
   TiledRenderableImageCanvas viewer;
   public void displayImage(PlanarImage img) {
      int width = img.getWidth();
      int height = img.getHeight();
      ParameterBlock pb = new ParameterBlock();
      pb.addSource(image);
      pb.add(null).add(null).add(null).add(null).add(null);
      RenderableOp op = JAI.createRenderable("renderable", pb);
      viewer.setImage(op);
      saver.setImage(img);
   }

   public void createUI() {
      Dimension sd= Toolkit.getDefaultToolkit().getScreenSize();
      int width = (int)(sd.width *4/5.0);
      int height = (int)(sd.height*4/5.0);

      setTitle("Renderable Image Viewer");
      viewer = new TiledRenderableImageCanvas();
      Dimension d = new Dimension(width, height); //getViewerSize(width/(double)height);
      viewer.setPreferredSize(new Dimension(d.width, d.height));
      createImageLoaderAndSaver();
      twidth = new JTextField(10);
      theight = new JTextField(10);
      renderGrid = new RenderGrid();
      theight.setText(Integer.toString(viewer.getTileHeight()));
      twidth.setText(Integer.toString(viewer.getTileWidth()));
      renderGrid.setTileDimension(viewer.getTileWidth(), viewer.getTileHeight());
      updateRenderGrid();
      JPanel gridpan = new JPanel();
      
      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(renderGrid, c);
      gridpan.add(renderGrid);

      JPanel tilesetpan = createTileSetPanel();
      JPanel dispmodepan = createDisplayModePanel();
      JTabbedPane jtab = new JTabbedPane();
      jtab.add("Tile Dimensions",tilesetpan);
      jtab.add("Display Modes",dispmodepan);
      c.weighty = 0.3; c.weightx = 1.0;
      gb.setConstraints(jtab, c);
      gridpan.add(jtab);
      gridpan.setBorder(BorderFactory.createTitledBorder("Tile Grid"));
      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();
      hsp.setDividerLocation(0.5);
      vsp.setDividerLocation(0.32);
      hsp.setDividerSize(5);
      vsp.setDividerSize(6);
      addEventAdapters();
      initializeScroll();
      viewer.repaint();
   }

   protected void addEventAdapters(){
       twidth.addActionListener(
         new ActionListener(){
            public void actionPerformed(ActionEvent e) {
               try {
                  String str = ((JTextField) e.getSource()).getText();
                  int wid = Integer.parseInt(str);
                  viewer.setTileWidth(wid);
                  if(renderGrid != null) updateRenderGrid();
               } catch (Exception e2){}
             }
          }
      );
      theight = new JTextField(10);
      theight.addActionListener(
         new ActionListener(){
            public void actionPerformed(ActionEvent e) {
               try {
                  String str = ((JTextField) e.getSource()).getText();
                  int wid = Integer.parseInt(str);
                  viewer.setTileHeight(wid);
                  if(renderGrid != null) updateRenderGrid();
               } catch (Exception e1){}
             }
          }
       );

      viewer.addPropertyChangeListener(
          new PropertyChangeListener() {
             public void propertyChange(PropertyChangeEvent e) {
                if(e.getPropertyName().equals("viewportPosition")){
                   twidth.setText(Integer.toString(viewer.getTileWidth()));
                   theight.setText(Integer.toString(viewer.getTileHeight()));
                   if(renderGrid != null) updateRenderGrid();
                   Point p =(Point)e.getNewValue();
                   renderGrid.setViewportPosition(p);
                }
            }
         }
      );

      renderGrid.addPropertyChangeListener(
          new PropertyChangeListener() {
             public void propertyChange(PropertyChangeEvent e) {
                if(e.getPropertyName().equals("viewportPosition")){
                   double scaleX, scaleY;
                   int wid = renderGrid.getViewportDimension().width;
                   int ht = renderGrid.getViewportDimension().height;
                   scaleX = viewer.getImageWidth()/wid;
                   scaleY = viewer.getImageHeight()/ht;
                   if(e.getNewValue() instanceof Point){
                      Point p =(Point)e.getNewValue();
                      viewer.pan(-p.x*scaleX, -p.y*scaleY);
                  }
                }
            }
         }
      );

      loader.addPlanarImageLoadedListener(
          new PlanarImageLoadedListener() {
             public void imageLoaded(PlanarImageLoadedEvent e) {
                PlanarImage image = e.getImage();
                if(image == null) return;
                SwingUtilities.invokeLater(new ImagePaint(image));
             }
         }
      );
   }

   protected void initializeScroll(){
      scroll = new ScrollGUI(viewer);
      viewer.addMouseListener(scroll);
      viewer.addMouseMotionListener(scroll);
   }

   protected void updateRenderGrid() {
      int tw1 = viewer.getTileWidth();
      int th1 = viewer.getTileHeight();
      int xInd1 = viewer.getMaxTileIndexX();
      int yInd1 = viewer.getMaxTileIndexY();
      renderGrid.setTileDimension(tw1,th1);
      renderGrid.setTileIndices(xInd1, yInd1);
      renderGrid.repaint();
   }
 
   protected JPanel createDisplayModePanel() {
       ButtonGroup bg = new ButtonGroup();
       JRadioButton normal = new JRadioButton("Scaled");
       JRadioButton tofit = new JRadioButton("To Fit");
       JRadioButton orig = new JRadioButton("Orig Size");
       DisplayModeAdapter danormal = new DisplayModeAdapter(RenderableImageCanvas.SCALED);
       DisplayModeAdapter datofit = new DisplayModeAdapter(RenderableImageCanvas.TO_FIT);
       DisplayModeAdapter daorig = new DisplayModeAdapter(RenderableImageCanvas.MAX_SIZE);
       orig.setSelected(true);
       normal.addActionListener(danormal);
       tofit.addActionListener(datofit);
       orig.addActionListener(daorig);
       bg.add(normal);
       bg.add(tofit);
       bg.add(orig);
       JPanel jp = new JPanel();
       jp.add(orig);
       jp.add(normal);
       jp.add(tofit);
       return jp;
   }
   class DisplayModeAdapter implements ActionListener {
        int mode;
        public DisplayModeAdapter( int type) {
           mode = type;
        }
        public void actionPerformed(ActionEvent e) {
           viewer.setDisplayMode(mode);
        }
   }

   protected class ImagePaint implements Runnable {
      PlanarImage image;
      boolean firstTime = true;
      public ImagePaint(PlanarImage image){this.image = image;}
      public void run() {
         if(firstTime) {
            try {
            firstTime = false;
            if(image == null) System.out.println("image = null");
            setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
            ParameterBlock pb = new ParameterBlock();
            pb.addSource(image);
            pb.add(null).add(null).add(null).add(null).add(null);
            RenderableOp op = JAI.createRenderable("renderable", pb);
            viewer.setImage(op);
            viewer.setOrigImageSize(new Dimension(image.getWidth(),image.getHeight()));
            viewer.repaint();
            SwingUtilities.invokeLater(this);
            } catch(Exception e){
            System.out.println(e);
            e.printStackTrace();
            SwingUtilities.invokeLater(this);}
         }
         else {
            if(!viewer.isImageDrawn()) SwingUtilities.invokeLater(this);
            else{
               setCursor(Cursor.getDefaultCursor());
               int tw = viewer.getTileWidth();
               int th = viewer.getTileHeight();
               int xInd = viewer.getMaxTileIndexX();
               int yInd = viewer.getMaxTileIndexY();
               renderGrid.setTileDimension(tw,th);
               renderGrid.setTileIndices(xInd, yInd);
            }
         }
      }
   }

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