/* @(#) ImageViewer2D.java 1.1 99/11/18
 * Copyright (c) 1999 Lawrence Rodrigues
 */

package app;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.jar.*;
import java.awt.print.*;
import com.vistech.util.*;
import com.vistech.imageloader.*;
import com.vistech.events.*;
import com.vistech.imageviewer.*;
import com.vistech.imageviewer.DisplayMode;

/** An image viewer application that can load, display, and print images.
  * It can load images only from a local directory.
  *
  * This application uses the ImageCanvas class as a component for drawing images.
  *  @version 1.0  18 Nov 1999
  * @author Lawrence Rodrigues
  **/
public class ImageViewer2D extends ApplicationFrame{
    protected ImageCanvas viewerPane;
    protected int dispMode = DisplayMode.SCALED;
    protected int flipMode = FlipMode.NORMAL;
    protected JTextArea messageBar;
    protected String filterString;
    protected MultiImageLoader imageLoader;
    protected JFrame ilFrame;
    public static void  main(String[] args){
       ImageViewer2D iv = new ImageViewer2D();
    }
    public ImageViewer2D() {
       addWindowListener(
          new WindowAdapter() {
             public void windowClosing(WindowEvent w){
                ImageViewer2D.this.dispose();
                System.exit(0);
            }
          });
    }

    public void quit(){
       this.dispose();
    }

    protected void setAboutStrings() {
        setAboutString(" Image Viewer \n Version 1.0 \n"+
                        "Author: Lawrence Rodrigues\n");
        setAboutTitle(" Image Viewer");
    }

    protected void createGUI(){
       setAboutStrings();
       createImageLoader();
       ViewerMenuBar viewerMenuBar = new ViewerMenuBar();
       setJMenuBar((JMenuBar)viewerMenuBar);
       Dimension ssize= Toolkit.getDefaultToolkit().getScreenSize();
       int vwid = (int)(ssize.width*3/4.0);
       int vht = (int)(ssize.height*3/4.0);
       this.setLocation((ssize.width/4),
                         (ssize.height/4));
       this.setSize((int)(ssize.width*3/4.0), (int)(ssize.height*3/4.0));

       viewerPane = new ImageCanvas();
       messageBar = new JTextArea();
       messageBar.setBorder(BorderFactory.createTitledBorder("Messages"));
       messageBar.setBackground(Color.black);
       messageBar.setForeground(Color.green);
       this.updateMessageBar();

       GridBagLayout gb = new GridBagLayout() ;
       GridBagConstraints c = new GridBagConstraints();
       this.getContentPane().setLayout(gb);
       c.fill = GridBagConstraints.BOTH;
       c.weighty = 1.0; c.weightx = 1.0;
       c.gridheight =1;
       c.gridwidth = 1;
       c.gridwidth = GridBagConstraints.REMAINDER;

       gb.setConstraints(viewerPane, c);
       this.getContentPane().add(viewerPane);
       c.fill = GridBagConstraints.BOTH;
       c.weighty = 0.05; c.weightx = 1.0;
       gb.setConstraints(messageBar, c);
       this.getContentPane().add(messageBar);
       this.setPrinterObj(viewerPane);
       this.show();
       this.repaint();
   }

   public void createImageLoader(){
      imageLoader = new MultiImageLoader();
      imageLoader.setLoadButtonLabel("Launch Image(s)");
      imageLoader.addImageLoadedListener(
      new ImageLoadedListener() {
        public void imageLoaded(ImageLoadedEvent e) {
           Image[] imset = e.getImages();
           viewerPane.setAWTImage(imset[0]);
        }
      });
      ilFrame = new JFrame();
      ilFrame.getContentPane().add(imageLoader);
      ilFrame.addWindowListener(
      new WindowAdapter() {
        public void windowClosing(WindowEvent e){
           hideImageLoader();
        }
      });
      ilFrame.setSize(imageLoader.getPreferredSize());
      ilFrame.pack();
   }

   public void showImageLoader() {
     ilFrame.show();
   }

   public void hideImageLoader() {
     ilFrame.hide();
   }

   protected void save() {
      if(saveFileName == null) saveAs();
      BufferedImage bi = viewerPane.getDisplayedImage();
      if(bi != null) JpegUtil.saveImageAsJPEG(bi, saveFileName);
   }

   protected void saveAs() {
      String filename = JpegUtil.launchFileDialog();
      if(filename != null){
         saveFileName = filename;
         save();
      }
   }

   protected void printContents() {
       if(printerObj == null) return;
       PrinterJob pj = PrinterJob.getPrinterJob();
       pj.setPrintable(printerObj);
       pj.printDialog();
       try{
          pj.print();
       }catch(Exception e){System.out.println(e);}
   }

   public void updateMessageBar(){
      if(viewerPane == null)return;
        messageBar.setBackground(Color.black);
        messageBar.setText("Display Mode : "+
                            getDisplayModeString(viewerPane.getDisplayMode())+"\n"+
                           "Flip Mode : " +
                            getFlipModeString(viewerPane.getFlipMode()));
        messageBar.repaint();
        repaint();
    }

    public String getFlipModeString(int mode) {
       switch (mode) {
          case FlipMode.NORMAL: return "Normal";
          case FlipMode.LEFT_RIGHT: return "Left to right";
          case FlipMode.TOP_BOTTOM: return "Top to bottom";
          case FlipMode.TOP_BOTTOM_LEFT_RIGHT: return "Top to bottom and left to right";
          default: return null;
       }
    }

    public String getDisplayModeString(int mode) {
       switch (mode) {
          case DisplayMode.ORIG_SIZE: return "Original size";
          case DisplayMode.TO_FIT: return "Fit the viewport";
          case DisplayMode.SCALED: return "Scaled to fit the viewport";
          default: return null;
       }
    }

    /** The ViewerMenuBar class creates a menu bar with three menus: Image Selection
      * View mode, and help.
      *
      */
     public class ViewerMenuBar extends ApplicationFrame.AppMenuBar {
       public ViewerMenuBar(){
          createImageSelectionMenu();
          createViewModeMenu();
          createHelpMenu();
       }

       public JMenu createImageSelectionMenu(){
          JMenu selMenu = new JMenu("Load");
          JMenuItem ls = new JMenuItem("List/Select");
          ls.addActionListener(
              new ActionListener() {
                public void actionPerformed(ActionEvent e){
                   showImageLoader();
                }
              }
           );
           selMenu.add(ls);
           add(selMenu);
           return selMenu;
       }

       public JMenu createViewModeMenu(){
          JMenu viewModeMenu = new JMenu("Modes");
          JMenu dispMode = new JMenu("Display Mode");
          JMenu flipMode = new JMenu("Flip Mode");
          viewModeMenu.add(dispMode);
          viewModeMenu.add(flipMode);
          JMenuItem orig = new JMenuItem("Original Size");
          JMenuItem tofit = new JMenuItem("To Fit");
          JMenuItem scaled= new JMenuItem("Scaled");
          orig.addActionListener(new DisplayModeAdapter(DisplayMode.ORIG_SIZE));
          tofit.addActionListener(new DisplayModeAdapter(DisplayMode.TO_FIT));
          scaled.addActionListener(new DisplayModeAdapter(DisplayMode.SCALED));

          dispMode.add(orig);
          dispMode.add(tofit);
          dispMode.add(scaled);

          JMenuItem normal = new JMenuItem("Normal");
          JMenuItem leftright = new JMenuItem("Left to Right");
          JMenuItem topbottom = new JMenuItem("Top to Bottom");
          JMenuItem topbotlefrig = new JMenuItem("Top to Bottom and left to right");

          flipMode.add(normal);
          flipMode.add(leftright);
          flipMode.add(topbottom);
          flipMode.add(topbotlefrig);
          normal.addActionListener(new FlipModeAdapter(FlipMode.NORMAL));
          leftright.addActionListener(new FlipModeAdapter(FlipMode.LEFT_RIGHT));
          topbottom.addActionListener(new FlipModeAdapter(FlipMode.TOP_BOTTOM));
          topbotlefrig.addActionListener(new FlipModeAdapter(FlipMode.TOP_BOTTOM_LEFT_RIGHT));

          JCheckBoxMenuItem invertOn = new JCheckBoxMenuItem("Invert");
          invertOn.addChangeListener(
              new ChangeListener() {
                 public void stateChanged(ChangeEvent e){
                    JCheckBoxMenuItem jce = (JCheckBoxMenuItem)e.getSource();
                    if(viewerPane != null) viewerPane.setInvert(jce.getState());
                 }
              }
          );
          viewModeMenu.add(invertOn);
          add(viewModeMenu);
          return viewModeMenu;
      }
    }

    protected class DisplayModeAdapter implements ActionListener{
       int dispmode;
       public DisplayModeAdapter(int mode){
          dispmode = mode;
       }
       public void actionPerformed(ActionEvent e){
          if(viewerPane != null) viewerPane.setDisplayMode(dispmode);
          updateMessageBar();
       }
    }

    protected class FlipModeAdapter implements ActionListener{
       int flipmode;
       public FlipModeAdapter(int mode){
          flipmode = mode;
       }
       public void actionPerformed(ActionEvent e){
          if(viewerPane != null) viewerPane.setFlipMode(flipmode);
          updateMessageBar();
       }
    }
}

