package yi.iu.ui;
/*
	This simple extension of the java.awt.Frame class
	contains all the elements necessary to act as the
	main window of an application.
 */

import java.beans.*;
import java.io.*;

import java.awt.*;
import java.awt.image.*;

import Acme.JPM.Decoders.*;
import symantec.itools.multimedia.*;
import yi.iu.processor.*;
import yi.util.config.*;
import yi.util.io.*;


public class IUDemoFrame extends Frame
{
	private Image origImage;
	private Image processedImage;
	private int origPixels[];
	private int processedPixels[]=null;
	private int width, height;
	private int processedWidth, processedHeight;

        /**
         * Define whether open a new window to display the result
         */
        protected boolean open_new_window = false;

	//read file methods.ini to initialize the available method
	public String[] getMethodNames() {
          return new String[] {
              "yi.app.eye.EllipseDetect",
              "yi.iu.processor.ort.Fex",
              "yi.iu.processor.ort.ChainPixel",
              "yi.iu.processor.canny.CannyGray",
              "yi.or.OR_boat"
          };

//          try {
//            return ReadArgu.readStrings("methods.ini");
//          }catch (IOException e) {
//            e.printStackTrace();
//            return null;
//          }

        }
	// read file images.ini to initialize the available image
	public String[] getImageNames() {
          return new String[] {
              "eye/CP1.ppm",
              "eye/CP2.ppm",
              "eye/CP3.ppm",
              "eye/CP4.ppm",
              "eye/SCI1.ppm",
              "eye/SCI2.ppm",
              "eye/SCI3.ppm",
              "eye/SCI4.ppm",
              "eye/SCI5.ppm",
              "eye/AL1.ppm",
              "eye/AL2.ppm",
              "eye/AL3.ppm",
              "eye/AL4.ppm",
              "images/Q7180260.jpg",
              "h:/images/VACE/nima1/087.jpg",
              "h:/images/VACE/nima1/104.jpg",
              "h:/images/VACE/nima1/105.jpg"

          };

//          try {
//            return ReadArgu.readStrings("images.ini");
//
//          } catch (IOException e) {
//            e.printStackTrace();
//            return null;
//          }
        }

        public String[] getPackageNames() {
            String[] ss={"yi.iu.processor"};
            return ss;
        }

	public IUDemoFrame()
	{
		// This code is automatically generated by Visual Cafe when you add
		// components to the visual environment. It instantiates and initializes
		// the components. To modify the code, only use code syntax that matches
		// what Visual Cafe can generate, or Visual Cafe may be unable to back
		// parse your Java file into its visual environment.

		//{{INIT_CONTROLS
		setLayout(null);
		setSize(959,364);
		setVisible(false);
		openFileDialog1.setMode(FileDialog.LOAD);
		openFileDialog1.setTitle("Open");
		//$$ openFileDialog1.move(24,312);
		leftImagePanel.setLayout(null);
		add(leftImagePanel);
		leftImagePanel.setBounds(12,48,378,252);
		leftImagePanel.add(origImageViewer);
		origImageViewer.setBounds(0,0,378,252);
		processButton.setLabel("process>>");
		add(processButton);
		processButton.setBackground(java.awt.Color.lightGray);
                processButton.setBounds(816,12,80,24);
		rightImagePanel.setLayout(null);
		add(rightImagePanel);
		rightImagePanel.setBounds(564,48,378,252);
		rightImagePanel.add(procImageViewer);
		procImageViewer.setBounds(0,0,378,252);
		add(methodChoice);
                methodChoice.setBounds(552,12,192,25);
		label1.setText("2. Select a processor:");
		add(label1);
		label1.setFont(new Font("Dialog", Font.BOLD, 12));
                label1.setBounds(420,12,125,24);
		add(imageChoice);
                imageChoice.setBounds(128,12,280,24);

		label2.setText("1. Select an image:");
		add(label2);
		label2.setFont(new Font("Dialog", Font.BOLD, 12));
                label2.setBounds(12,12,110,24);
		statusLabel.setText("Welcome to Yi\'s world !");
		statusLabel.setAlignment(java.awt.Label.CENTER);
		add(statusLabel);
		statusLabel.setBounds(336,312,273,24);
		add(informationLabel);
		informationLabel.setBounds(12,312,84,24);
		add(ldetailLabel);
		ldetailLabel.setBounds(120,312,180,24);
		add(rdetailLabel);
		rdetailLabel.setBounds(732,312,180,24);
		label3.setText("3. Click");
		add(label3);
		label3.setFont(new Font("Dialog", Font.BOLD, 12));
                label3.setBounds(756,12,48,24);
		argumentPanel.setLayout(null);
		add(argumentPanel);
		argumentPanel.setBounds(396,48,162,252);
		label4.setText("Options:");
		argumentPanel.add(label4);
		label4.setBounds(48,0,72,24);
		setTitle("AWT Application");
		//}}

		//{{INIT_MENUS
		menu1.setLabel("File");
		menu1.add(newMenuItem);
		newMenuItem.setEnabled(false);
		newMenuItem.setLabel("New");
		newMenuItem.setShortcut(new MenuShortcut(java.awt.event.KeyEvent.VK_N,false));
		menu1.add(openMenuItem);
		openMenuItem.setLabel("Open...");
		openMenuItem.setShortcut(new MenuShortcut(java.awt.event.KeyEvent.VK_O,false));
		menu1.add(saveMenuItem);
		saveMenuItem.setEnabled(false);
		saveMenuItem.setLabel("Save");
		saveMenuItem.setShortcut(new MenuShortcut(java.awt.event.KeyEvent.VK_S,false));
		menu1.add(saveAsMenuItem);
		saveAsMenuItem.setEnabled(false);
		saveAsMenuItem.setLabel("Save As...");
		menu1.add(separatorMenuItem);
		separatorMenuItem.setLabel("-");
		menu1.add(exitMenuItem);
		exitMenuItem.setLabel("Exit");
		mainMenuBar.add(menu1);
		menu2.setLabel("Edit");
		menu2.add(cutMenuItem);
		cutMenuItem.setEnabled(false);
		cutMenuItem.setLabel("Cut");
		cutMenuItem.setShortcut(new MenuShortcut(java.awt.event.KeyEvent.VK_X,false));
		menu2.add(copyMenuItem);
		copyMenuItem.setEnabled(false);
		copyMenuItem.setLabel("Copy");
		copyMenuItem.setShortcut(new MenuShortcut(java.awt.event.KeyEvent.VK_C,false));
		menu2.add(pasteMenuItem);
		pasteMenuItem.setEnabled(false);
		pasteMenuItem.setLabel("Paste");
		pasteMenuItem.setShortcut(new MenuShortcut(java.awt.event.KeyEvent.VK_V,false));
		mainMenuBar.add(menu2);
		menu3.setLabel("Help");
		menu3.add(aboutMenuItem);
		aboutMenuItem.setLabel("About...");
		mainMenuBar.add(menu3);
		//$$ mainMenuBar.move(0,312);
		setMenuBar(mainMenuBar);
		//}}

		// read file methods.ini to initialize the available method
		setMethodChoice();
		// read file images.ini to initialize the available image
		setImageChoice();


		//{{REGISTER_LISTENERS
		SymWindow aSymWindow = new SymWindow();
		this.addWindowListener(aSymWindow);
		SymAction lSymAction = new SymAction();
		openMenuItem.addActionListener(lSymAction);
		exitMenuItem.addActionListener(lSymAction);
		aboutMenuItem.addActionListener(lSymAction);
		SymMouse aSymMouse = new SymMouse();
		processButton.addMouseListener(aSymMouse);
		SymItem lSymItem = new SymItem();
		imageChoice.addItemListener(lSymItem);
		methodChoice.addItemListener(lSymItem);
		SymMouseMotion aSymMouseMotion = new SymMouseMotion();
		origImageViewer.addMouseMotionListener(aSymMouseMotion);
		procImageViewer.addMouseMotionListener(aSymMouseMotion);
		//}}

		// set the correct argument information
		java.awt.event.ItemEvent event=null;
	    methodChoice_ItemStateChanged(event);
        imageChoice_ItemStateChanged(event);

	}

	void setMethodChoice()
	{
	    String methods[]= getMethodNames();
	    if (methods==null) return;
	    if (methods.length==0) return;
		for (int i=0;i<methods.length;i++)
		    methodChoice.addItem(methods[i]);
	}

	void setImageChoice()
	{
	    String images[]= getImageNames();
		if (images==null) return;
	    if (images.length==0) return;
		for (int i=0;i<images.length;i++)
		    imageChoice.addItem(images[i]);
	}


	public IUDemoFrame(String title)
	{
		this();
		setTitle(title);
	}

    /**
     * Shows or hides the component depending on the boolean flag b.
     * @param b  if true, show the component; otherwise, hide the component.
     * @see java.awt.Component#isVisible
     */
    public void setVisible(boolean b)
	{
		if(b)
		{
			setLocation(50, 50);
		}
		super.setVisible(b);
	}

	static public void main(String args[])
	{
		try
		{
			//Create a new instance of our application's frame, and make it visible.
    		(new IUDemoFrame()).setVisible(true);
		}
		catch (Throwable t)
		{
			System.err.println(t);
			t.printStackTrace();
			//Ensure the application exits with an error condition.
			System.exit(1);
		}
	}

	public void addNotify()
	{
		// Record the size of the window prior to calling parents addNotify.
		Dimension d = getSize();

		super.addNotify();

		if (fComponentsAdjusted)
			return;

		// Adjust components according to the insets
		setSize(getInsets().left + getInsets().right + d.width, getInsets().top + getInsets().bottom + d.height);
		Component components[] = getComponents();
		for (int i = 0; i < components.length; i++)
		{
			Point p = components[i].getLocation();
			p.translate(getInsets().left, getInsets().top);
			components[i].setLocation(p);
		}
		fComponentsAdjusted = true;
	}

	// Used for addNotify check.
	boolean fComponentsAdjusted = false;

	//{{DECLARE_CONTROLS
	java.awt.FileDialog openFileDialog1 = new java.awt.FileDialog(this);
	java.awt.Panel leftImagePanel = new java.awt.Panel();
	symantec.itools.multimedia.ImageViewer origImageViewer = new symantec.itools.multimedia.ImageViewer();
	java.awt.Button processButton = new java.awt.Button();
	java.awt.Panel rightImagePanel = new java.awt.Panel();
	symantec.itools.multimedia.ImageViewer procImageViewer = new symantec.itools.multimedia.ImageViewer();
	java.awt.Choice methodChoice = new java.awt.Choice();
	java.awt.Label label1 = new java.awt.Label();
	java.awt.Choice imageChoice = new java.awt.Choice();
	java.awt.Label label2 = new java.awt.Label();
	java.awt.Label statusLabel = new java.awt.Label();
	java.awt.Label informationLabel = new java.awt.Label();
	java.awt.Label ldetailLabel = new java.awt.Label();
	java.awt.Label rdetailLabel = new java.awt.Label();
	java.awt.Label label3 = new java.awt.Label();
	java.awt.Panel argumentPanel = new java.awt.Panel();
	java.awt.Label label4 = new java.awt.Label();
	//}}
	java.awt.TextField arguTextFields[] = null;
	java.awt.Label arguLabels[] = null;

	//{{DECLARE_MENUS
	java.awt.MenuBar mainMenuBar = new java.awt.MenuBar();
	java.awt.Menu menu1 = new java.awt.Menu();
	java.awt.MenuItem newMenuItem = new java.awt.MenuItem();
	java.awt.MenuItem openMenuItem = new java.awt.MenuItem();
	java.awt.MenuItem saveMenuItem = new java.awt.MenuItem();
	java.awt.MenuItem saveAsMenuItem = new java.awt.MenuItem();
	java.awt.MenuItem separatorMenuItem = new java.awt.MenuItem();
	java.awt.MenuItem exitMenuItem = new java.awt.MenuItem();
	java.awt.Menu menu2 = new java.awt.Menu();
	java.awt.MenuItem cutMenuItem = new java.awt.MenuItem();
	java.awt.MenuItem copyMenuItem = new java.awt.MenuItem();
	java.awt.MenuItem pasteMenuItem = new java.awt.MenuItem();
	java.awt.Menu menu3 = new java.awt.Menu();
	java.awt.MenuItem aboutMenuItem = new java.awt.MenuItem();
	//}}

	class SymWindow extends java.awt.event.WindowAdapter
	{
		public void windowClosing(java.awt.event.WindowEvent event)
		{
			Object object = event.getSource();
			if (object == IUDemoFrame.this)
				IUDemoFrame_WindowClosing(event);
		}
	}

	void IUDemoFrame_WindowClosing(java.awt.event.WindowEvent event)
	{
		// to do: code goes here.

		IUDemoFrame_WindowClosing_Interaction1(event);
	}


	void IUDemoFrame_WindowClosing_Interaction1(java.awt.event.WindowEvent event)
	{
		try {
			// QuitDialog Create and show as modal
			(new QuitDialog(this, true)).setVisible(true);
		} catch (Exception e) {
		}
	}


	class SymAction implements java.awt.event.ActionListener
	{
		public void actionPerformed(java.awt.event.ActionEvent event)
		{
			Object object = event.getSource();
			if (object == openMenuItem)
				openMenuItem_ActionPerformed(event);
			else if (object == aboutMenuItem)
				aboutMenuItem_ActionPerformed(event);
			else if (object == exitMenuItem)
				exitMenuItem_ActionPerformed(event);
		}
	}

	void openMenuItem_ActionPerformed(java.awt.event.ActionEvent event)
	{
		// to do: code goes here.

		openMenuItem_ActionPerformed_Interaction1(event);
	}


	void openMenuItem_ActionPerformed_Interaction1(java.awt.event.ActionEvent event)
	{
		try {
			// OpenFileDialog Create and show as modal
		    int		defMode         = openFileDialog1.getMode();
		    String	defTitle        = openFileDialog1.getTitle();
		    String defDirectory     = openFileDialog1.getDirectory();
		    String defFile          = openFileDialog1.getFile();

		    openFileDialog1 = new java.awt.FileDialog(this, defTitle, defMode);
		    openFileDialog1.setDirectory(defDirectory);
		    openFileDialog1.setFile(defFile);
		    openFileDialog1.setVisible(true);
		} catch (Exception e) {
		}
	}


	void aboutMenuItem_ActionPerformed(java.awt.event.ActionEvent event)
	{
		// to do: code goes here.

		aboutMenuItem_ActionPerformed_Interaction1(event);
	}


	void aboutMenuItem_ActionPerformed_Interaction1(java.awt.event.ActionEvent event)
	{
		try {
			// AboutDialog Create and show as modal
			(new AboutDialog(this, true)).setVisible(true);
		} catch (Exception e) {
		}
	}


	void exitMenuItem_ActionPerformed(java.awt.event.ActionEvent event)
	{
		// to do: code goes here.

		exitMenuItem_ActionPerformed_Interaction1(event);
	}


	void exitMenuItem_ActionPerformed_Interaction1(java.awt.event.ActionEvent event)
	{
		try {
			// QuitDialog Create and show as modal
		    (new QuitDialog(this, true)).setVisible(true);
		} catch (Exception e) {
		}
	}


	// read file methods.ini to initialize the available method
	void readMethodChoice()
	{
	    String[] methods= null;
            try {
              ReadArgu.readStrings("methods.ini");
            } catch (IOException e) {
              e.printStackTrace();
              return;
            }
	    if (methods==null) return;
	    if (methods.length==0) return;
		for (int i=0;i<methods.length;i++)
		    methodChoice.addItem(methods[i]);
	}

	// read file images.ini to initialize the available image
	void readImageChoice()
	{
          String[] images = null;
          try {

            images = ReadArgu.readStrings("images.ini");
          }catch (IOException e) {
            e.printStackTrace();
            return;
          }

	if (images==null) return;
	    if (images.length==0) return;
		for (int i=0;i<images.length;i++)
		    imageChoice.addItem(images[i]);
	}

	void readOrigPixels()
	{
	    PixelGrabber pg = new PixelGrabber(origImage,0,0,-1,-1,true);
	    boolean result=false;
	    try {
	        result = pg.grabPixels();
	    }
	    catch (InterruptedException e) {
	        System.err.println("Interrupted pixel grabbing!");
	        e.printStackTrace();
	    }

	    if (result==false) {
	        System.err.println("Couldn't Grab the Pixels!");
	        System.exit(0);
	    }

	    origPixels= (int[]) pg.getPixels();
	    width = pg.getWidth();
	    height = pg.getHeight();
	    pg = null;
	    System.gc();
	}

	void paintProcessedImage()
	{
	    try {
		    procImageViewer.setStyle(ImageViewer.IMAGE_SCALED_TO_FIT);
		    procImageViewer.setImage(processedImage);
		}
		catch (PropertyVetoException e) {
		    System.err.println("can't set image to viewer!");
		}
		procImageViewer.repaint();

	}

	ImageProcessor getProcessor()
	{
          String methodName= methodChoice.getSelectedItem();
          //find the first part of the name (seperated by space)
          int space= methodName.indexOf(" ");
          if (space!=-1) methodName= methodName.substring(0,space);

          // try to find the method according to it's name in the current directory
          ImageProcessor ip=null;
      try {
          Class ipc= Class.forName(methodName);
          ip= (ImageProcessor)ipc.newInstance();
      } catch (Exception e) {
      }
      if (ip!=null) return ip;

      String[] package_names=getPackageNames();
      for (int i=0;i<package_names.length;i++) {
          // try to find the method according to it's name in the lib directory
          try {
              Class ipc= Class.forName(package_names[i]+"."+methodName);
              ip= (ImageProcessor)ipc.newInstance();
              return ip;

          } catch (Exception e) {
              //System.err.println("not found the procssor in "+package_names[i]);
          }
      }

      System.err.println("Can't find that image processor!");
      return null;
	}




	class SymMouse extends java.awt.event.MouseAdapter
	{
		public void mousePressed(java.awt.event.MouseEvent event)
		{
			Object object = event.getSource();
			if (object == processButton)
				processButton_MousePressed(event);
		}
	}

	//set the arguments of the image processor according to the set of user
	void setArguments(ImageProcessor ip) {
	    int arguNum= ip.getArguNum();
	    if (arguNum==0) return;
	    for (int i=0;i<arguNum;i++) {
	        String value= arguTextFields[i].getText();
            ip.setArgument(i,value);
	    }

	}

	//get the default argument settings, and display them on the screen
	void getArguments(ImageProcessor ip) {
        int arguNum= ip.getArguNum();
        argumentPanel.removeAll();
        argumentPanel.add(label4);
        if (arguNum<=0) {argumentPanel.repaint(); return;}

        arguTextFields= new java.awt.TextField[arguNum];
	    arguLabels = new java.awt.Label[arguNum];

        for (int i=0;i<arguNum;i++) {
	        arguLabels[i]= new java.awt.Label(ip.getArguName(i));
	        arguLabels[i].setBounds(12,36+30*i,80,24);
	        arguLabels[i].setAlignment(java.awt.Label.RIGHT);
	        argumentPanel.add(arguLabels[i]);

	        arguTextFields[i]= new TextField(ip.getArgument(i));
	        arguTextFields[i].setBounds(100,36+30*i,60,24);
	        argumentPanel.add(arguTextFields[i]);
	    }
	    argumentPanel.repaint();
	}

	void processButton_MousePressed(java.awt.event.MouseEvent event)
	{
		ImageProcessor ip= getProcessor();
		if (ip==null) {
		    statusLabel.setText("Can't find that image processor!");
		    return;
		}
		setArguments(ip);
		String methodName= methodChoice.getSelectedItem();
		statusLabel.setText(methodName+ " is running ...");

	    Dimension d= new Dimension(width,height);
	    processedPixels= ip.getProcessedPseudoColor(origPixels, d);
	    processedWidth= d.width;
	    processedHeight= d.height;
            if (open_new_window) {
              DisplayFrame f = new DisplayFrame("final result", processedPixels,
                                                d.width, d.height);
              f.show();

            }

	    processedImage = createImage(
	        new MemoryImageSource(processedWidth,processedHeight,
	            processedPixels, 0, processedWidth));
	    paintProcessedImage();
	    statusLabel.setText("Process done !");
	    System.gc();
	}

	class SymItem implements java.awt.event.ItemListener
	{
		public void itemStateChanged(java.awt.event.ItemEvent event)
		{
			Object object = event.getSource();
			if (object == imageChoice)
				imageChoice_ItemStateChanged(event);
			else if (object == methodChoice)
				methodChoice_ItemStateChanged(event);
		}
	}

	void imageChoice_ItemStateChanged(java.awt.event.ItemEvent event)
	{
		String imageName= imageChoice.getSelectedItem();
                Configuration.setParameter("SOURCE_NAME", imageName);

		if (imageName.endsWith(".ppm")) {
		    try {
		        DataInputStream in= new DataInputStream(new FileInputStream(imageName));
		        PpmDecoder ppmd= new PpmDecoder(in);
		        Toolkit tk= Toolkit.getDefaultToolkit();
		        origImage= tk.createImage(ppmd);

		    }
		    catch (Exception e) {
		        System.err.println("read ppm error!"+e);
		    }
		}
		else {
		    origImage= Toolkit.getDefaultToolkit().getImage(imageName);
		}
		statusLabel.setText("Loading image: "+imageName+ " ...");
		try {
		    origImageViewer.setStyle(ImageViewer.IMAGE_SCALED_TO_FIT);
		    origImageViewer.setImage(origImage);
		}
		catch (PropertyVetoException e) {
		    System.err.println("can't set image to viewer!");
		}
		origImageViewer.repaint();
		readOrigPixels();
		statusLabel.setText("Image Loaded!");
		informationLabel.setText(width+"*"+height );
	}

	void methodChoice_ItemStateChanged(java.awt.event.ItemEvent event)
	{
		ImageProcessor ip= getProcessor();
		if (ip==null) {
		    statusLabel.setText("Can't find that image processor!");
		    return;
		}
		//get the arguments
		getArguments(ip);
	}

	public void paint(Graphics g) {
	    Rectangle r=leftImagePanel.getBounds();
	    g.drawRect(r.x-1,r.y-1,r.width+1,r.height+1);
	    r=rightImagePanel.getBounds();
	    g.drawRect(r.x-1,r.y-1,r.width+1,r.height+1);
	}



	class SymMouseMotion extends java.awt.event.MouseMotionAdapter
	{
		public void mouseMoved(java.awt.event.MouseEvent event)
		{
			Object object = event.getSource();
			if (object == origImageViewer)
				origImageViewer_mouseMoved(event);
			else if (object == procImageViewer)
				procImageViewer_mouseMoved(event);
		}
	}

	void origImageViewer_mouseMoved(java.awt.event.MouseEvent event)
	{
		int x= event.getX(),y=event.getY();
		Dimension d= origImageViewer.getSize();
		int vw= d.width, vh= d.height;
		x= (int)((double)x/vw*width);
		y= (int)((double)y/vh*height);
		if (x>=width) x=width-1;
		if (y>=height) y=height-1;
		int rgb= origPixels[y*width+x];
		int r=rgb>>16&255,g=rgb>>8&255,b=rgb&255;
		ldetailLabel.setText("("+x+","+y+"): "+"RGB("+r+","+g+","+b+")");
	}

	void procImageViewer_mouseMoved(java.awt.event.MouseEvent event)
	{
		if (processedPixels==null) return;
		int x= event.getX(),y=event.getY();
		Dimension d= procImageViewer.getSize();
		int vw= d.width, vh= d.height;
		x= (int)((double)x/vw*processedWidth);
		y= (int)((double)y/vh*processedHeight);
		if (x>=processedWidth) x=processedWidth-1;
		if (y>=processedHeight) y=processedHeight-1;
		int rgb= processedPixels[y*processedWidth+x];
		int r=rgb>>16&255,g=rgb>>8&255,b=rgb&255;
		rdetailLabel.setText("("+x+","+y+"): "+"RGB("+r+","+g+","+b+")");
	}
}

