package test.imaging;

import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.rmi.*;
import rmiFilter.*;

/**
 * @author Shrideep Pallickara, NPAC- Syracuse University
 */
public class ImagingClient extends Applet implements java.awt.event.ActionListener {
  private Button cancelButton = null;
  private Panel ContentsPane = null;
  private Button fetchImageButton = null;
  private Button filter = null;
  private ScrollPane imageScrollPane = null;
  private Button okButton = null;
  private TextField URLTextField = null;
  private Image img;
  public int imgw;
  public int imgh;
  private MediaTracker tracker;
  public int[] pixel;
  private Dialog URLDialog = null;
  public ImageCanvas imageCanvas;

  /**
   * Method to handle events for the ActionListener interface.
   * @param e java.awt.event.ActionEvent
   */
  public void actionPerformed(java.awt.event.ActionEvent e) {
    if ((e.getSource() == getfetchImage()) ) {
      displayFileDialog(e);
    }
    if (e.getSource() == getfilter()) {
	performFiltering();
    }
    if ((e.getSource() == getokButton()) ) {
      connEtoM2(e);
    }
    if ((e.getSource() == getcancelButton()) ) {
      connEtoM3(e);
    }
  }
  /**
   * connEtoM2:  (okButton.action.actionPerformed(java.awt.event.ActionEvent) --> URLTextField.getText()Ljava.lang.String;)
   * @return java.lang.String
   * @param arg1 java.awt.event.ActionEvent
   */
  private String connEtoM2(java.awt.event.ActionEvent arg1) {
    String connEtoM2Result = null;
    try {
      connEtoM2Result = getURLTextField().getText();
      connEtoM4(connEtoM2Result);
    } catch (java.lang.Throwable Exc) {
      handleException(Exc);
    }
    return connEtoM2Result;
  }
  /**
   * connEtoM3:  (cancelButton.action.actionPerformed(java.awt.event.ActionEvent) --> Dialog1.dispose()V)
   * @param arg1 java.awt.event.ActionEvent
   */
  private void connEtoM3(java.awt.event.ActionEvent arg1) {
    try {
      getURLDialog().dispose();
    } catch (java.lang.Throwable Exc) {
      handleException(Exc);
    }
  }

  /**
   * connEtoM4:  ( (okButton,action.actionPerformed(java.awt.event.ActionEvent) --> URLTextField,getText()Ljava.lang.String;).normalResult --> Dialog1.dispose()V)
   * @param result java.lang.String
   */
  private void connEtoM4(String result) {
    try {
      getURLDialog().dispose();
      imageToPixels(fetchImage(result));
    } catch (java.lang.Throwable Exc) {
      handleException(Exc);
    }
  }
  /**
   * connEtoM1:  (fetchImage.action.actionPerformed(java.awt.event.ActionEvent) --> Dialog1.show()V)
   * @param arg1 java.awt.event.ActionEvent
   */
  private void displayFileDialog(java.awt.event.ActionEvent arg1) {
    try {
      getURLDialog().show();
    } catch (java.lang.Throwable Exc) {
      handleException(Exc);
    }
  }
  /**
   * @return java.awt.Image
   * @param _imageLocation java.lang.String
   */
  public Image fetchImage(String _imageLocation) {
    System.out.println("Trying for an Image");
    img = getImage(getCodeBase(),_imageLocation);
    getTracker().addImage(img,0);
    try { 
      getTracker().waitForID(0);
    } catch (InterruptedException e) {
      System.out.println("Problem tracking the image with Media Tracker");
    }
    updateCanvas();
    return img;
  }

  private void updateCanvas() {
    imageCanvas.setImage(img);
    imageCanvas.repaint();
  }

  /**
   * Gets the applet information.
   * @return java.lang.String
   */
  public String getAppletInfo() {
    return "test.imaging.ImagingClient class .....";
  }
  /**
   * Return the cancelButton property value.
   * @return java.awt.Button
   */
  private Button getcancelButton() {
    if (cancelButton == null) {
      try {
	cancelButton = new java.awt.Button();
	cancelButton.setName("cancelButton");
	cancelButton.setBounds(164, 51, 56, 23);
	cancelButton.setActionCommand("Cancel");
	cancelButton.setLabel("Cancel");
      } catch (java.lang.Throwable Exc) {
	handleException(Exc);
      }
    };
    return cancelButton;
  }
  /**
   * Return the ContentsPane property value.
   * @return java.awt.Panel
   */
  private Panel getContentsPane() {
    if (ContentsPane == null) {
      try {
	ContentsPane = new java.awt.Panel();
	ContentsPane.setName("ContentsPane");
	ContentsPane.setLayout(null);
	getContentsPane().add(getURLTextField(), getURLTextField().getName());
	getContentsPane().add(getokButton(), getokButton().getName());
	getContentsPane().add(getcancelButton(), getcancelButton().getName());
      } catch (java.lang.Throwable Exc) {
	handleException(Exc);
      }
    };
    return ContentsPane;
  }
  /**
   * Return the fetchImage property value.
   * @return java.awt.Button
   */
  private Button getfetchImage() {
    if (fetchImageButton == null) {
      try {
	fetchImageButton = new java.awt.Button();
	fetchImageButton.setName("fetchImage");
	fetchImageButton.setBounds(231, 48, 80, 23);
	fetchImageButton.setActionCommand("fetchImage");
	fetchImageButton.setLabel("fetchImage");
      } catch (java.lang.Throwable Exc) {
	handleException(Exc);
      }
    };
    return fetchImageButton;
  }
  /**
   * Return the filter property value.
   * @return java.awt.Button
   */
  private Button getfilter() {
    if (filter == null) {
      try {
	filter = new java.awt.Button();
	filter.setName("filter");
	filter.setBounds(336, 48, 56, 23);
	filter.setActionCommand("filter");
	filter.setLabel("filter");
      } catch (java.lang.Throwable Exc) {
	handleException(Exc);
      }
    };
    return filter;
  }
  /**
   * @return test.imaging.ImageCanvas
   */
  public ImageCanvas getImageCanvas() {
    return imageCanvas;
  }
  /**
   * Return the imageScrollPane property value.
   * @return java.awt.ScrollPane
   */
  private ScrollPane getimageScrollPane() {
    if (imageScrollPane == null) {
      try {
	imageScrollPane = new java.awt.ScrollPane(1);
	imageScrollPane.setName("imageScrollPane");
	imageScrollPane.setBounds(31, 28, 166, 118);
      } catch (java.lang.Throwable Exc) {
	handleException(Exc);
      }
    };
    return imageScrollPane;
  }
  /**
   * @return java.awt.Image
   */
  public Image getImg() {
    return img;
  }
  /**
   * @return int
   */
  public int getImgh() {
    return imgh;
  }
  /**
   * @return int
   */
  public int getImgw() {
    return imgw;
  }
  /**
   * Return the okButton property value.
   * @return java.awt.Button
   */
  private Button getokButton() {
    if (okButton == null) {
      try {
	okButton = new java.awt.Button();
	okButton.setName("okButton");
	okButton.setBounds(74, 51, 56, 23);
	okButton.setActionCommand("OK");
	okButton.setLabel("OK");
      } catch (java.lang.Throwable Exc) {
	handleException(Exc);
      }
    };
    return okButton;
  }
  /**
   * @return int[]
   */
  public int[] getPixel() {
    return pixel;
  }
  /**
   * @return java.awt.MediaTracker
   */
  public MediaTracker getTracker() {
    if (tracker ==null)
      tracker = new MediaTracker(this);
    return tracker;
  }
  /**
   * Return the Dialog1 property value.
   * @return java.awt.Dialog
   */
  private Dialog getURLDialog() {
    if (URLDialog == null) {
      try {
	URLDialog = new java.awt.Dialog(new java.awt.Frame());
	URLDialog.setName("URLDialog");
	URLDialog.setLayout(new java.awt.BorderLayout());
	URLDialog.setBounds(49, 301, 369, 88);
	getURLDialog().add(getContentsPane(), "Center");
      } catch (java.lang.Throwable Exc) {
	handleException(Exc);
      }
    };
    return URLDialog;
  }
  /**
   * Return the URLTextField property value.
   * @return java.awt.TextField
   */
  private TextField getURLTextField() {
    if (URLTextField == null) {
      try {
	URLTextField = new java.awt.TextField();
	URLTextField.setName("URLTextField");
	URLTextField.setBackground(java.awt.SystemColor.controlLtHighlight);
	URLTextField.setBounds(29, 17, 301, 23);
      } catch (java.lang.Throwable Exc) {
	handleException(Exc);
      }
    };
    return URLTextField;
  }
  /**
   * Called whenever the part throws an exception.
   * @param exception java.lang.Throwable
   */
  private void handleException(Throwable exception) {
    
    /* Uncomment the following lines to print uncaught exceptions to stdout */
    // System.out.println("--------- UNCAUGHT EXCEPTION ---------");
    // exception.printStackTrace(System.out);
  }
  /**
   * @param I java.awt.Image
   */
  private void imageToPixels(Image I) {
    imgw = I.getWidth(null); imgh = I.getHeight(null);
    pixel = new int[imgw*imgh]; 
    PixelGrabber pg = new PixelGrabber(img,0,0,imgw,imgh,pixel,0,imgw);
    try {
      pg.grabPixels();
    } catch (InterruptedException e) {};
  }
  /**
   * Handle the Applet init method.
   */
  public void init() {
    super.init();
    try {
      setName("ImagingClient");
      setLayout(null);
      setSize(426, 240);
      add(getimageScrollPane(), getimageScrollPane().getName());
      add(getfetchImage(), getfetchImage().getName());
      add(getfilter(), getfilter().getName());
      initConnections();
      imageCanvas = new ImageCanvas();
      imageToPixels( fetchImage("blckrino.jpg") );
      getimageScrollPane().add(imageCanvas, "image Canvas");
    } catch (java.lang.Throwable Exc) {
      handleException(Exc);
    }
  }
  /**
   * Initializes connections
   */
  private void initConnections() {
      getfilter(). addActionListener(this);
    getfetchImage().addActionListener(this);
    getokButton().addActionListener(this);
    getcancelButton().addActionListener(this);
  }
  /**
   * main entrypoint - starts the part when it is run as an application
   * @param args java.lang.String[]
   */
  public static void main(java.lang.String[] args) {
    try {
      Frame frame;
      frame = new Frame();

      ImagingClient aImagingClient;
      Class iiCls = Class.forName("test.imaging.ImagingClient");
      ClassLoader iiClsLoader = iiCls.getClassLoader();
      aImagingClient = (ImagingClient)java.beans.Beans.instantiate(iiClsLoader,"test.imaging.ImagingClient");
      frame.add("Center", aImagingClient);
      frame.setSize(aImagingClient.getSize());
      frame.setVisible(true);
    } catch (Throwable exception) {
      System.err.println("Exception occurred in main() of java.applet.Applet");
		exception.printStackTrace(System.out);
    }
}
/**
 * This method performs the actual filtering operation.
 */
  public void performFiltering() {
      System.out.println("Filter operation begins");
      try {

	long startTime = System.currentTimeMillis();
	Remote remoteObject = 
	  Naming.lookup("rmi://128.230.21.135:8000/rmiFilter");
	long stopTime = System.currentTimeMillis();
	System.out.println("Avg Ping to bind to the RMI Filter Object= "
			  + ((stopTime - startTime)/1000f) + " secs");
	/*** Narrow the Object reference to a specific one */
	RMIFilter f;
	f = (RMIFilter) remoteObject;
	
	/** Make the invocation */
	try {
	  startTime = System.currentTimeMillis();
	  pixel = f.filter(pixel, imgw, imgh);
	  stopTime = System.currentTimeMillis();
	  System.out.println("Avg Ping to complete Remote operation = "
			     + ((stopTime - startTime)/1000f) + " secs");
	  System.out.println("Filter Operation Complete");
	  img = pixelsToI(pixel, imgw, imgh);
	  System.out.println("Image Calculated from Pixels");
	  updateCanvas();
	}
	catch (java.rmi.RemoteException exc) {
	  System.out.println("Error in Invocation " + exc.toString());
	}
      }
      catch (Exception exc) {
	System.out.println("Error in lookup");
      }
  }


  /**
   * @return java.awt.Image
   * @param pix int[]
   * @param iw int
   * @param ih int
   */
  private Image pixelsToI(int[] pix, int iw, int ih) {
    return createImage(new java.awt.image.MemoryImageSource(iw,ih,pix,0,iw));
  }
  /**
   * @param newValue test.imaging.ImageCanvas
   */
  public void setImageCanvas(ImageCanvas newValue) {
    this.imageCanvas = newValue;
  }
  /**
   * @param newValue int
   */
  public void setImgh(int newValue) {
    this.imgh = newValue;
  }
  /**
   * @param newValue int
   */
  public void setImgw(int newValue) {
    this.imgw = newValue;
  }
  /**
   * @param newValue int[]
   */
  public void setPixel(int[] newValue) {
    this.pixel = newValue;
  }
  /**
   * @param newValue java.awt.MediaTracker
   */
  public void setTracker(MediaTracker newValue) {
    this.tracker = newValue;
  }
}