/*
   Tamot --- Task Modelling Editor
   Copyright (C) 2000 Commonwealth Scientific and Industrial Research Organisation
   (CSIRO), Australia. All rights reserved. 

   The Software, owned by CSIRO Australia, has been developed by the CSIRO 
   Intelligent Interactive Technology group. 
   For more information, please see http://www.cmis.csiro.au/iit/.

   Redistribution in source and binary forms, with or without modification, are not permitted.

   The Software is a beta-test version for internal research and evaluation purposes 
   by the Licensee. The Software is still at a development stage. 
   It has not undergone complete testing and may have inherent errors,
   bugs or deficiencies that can affect the operation of the Software. 

   We encourage your feedback and suggestions. Any bugs / suggestions found please email to
   Shijian.Lu@cmis.csiro.au and Thomas.Lo@cmis.csiro.au. 

   After you have signed the Beta-Test Software License Agreement with the CSIRO,
   CSIRO grants you a non-exclusive, non-transferable license to use it only for your 
   personal, non-commercial and lawful end use. Implied licenses are negated. 

   Warranty Disclaimer : 

   CSIRO supplies the Software on an "as is" basis and makes no warranties that use of
   the Software by the Licensee will not infringe any third party’s 
   Intellectual Property Rights nor that the Software will be of merchantable quality,
   or suitable for a particular purpose. CSIRO excludes all terms, conditions and
   warranties implied by custom, the general law or statute in relation to the
   Software.
*/

package taskModellingTool;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.beans.*;
	
import TV.*;

public class GraphicDesktop extends JDesktopPane{

    protected static String currentFrame=null;

    public GraphicDesktop(){
    	
        super();
        
		setDesktopManager(new CustomDesktopManager());

        //Make dragging faster:
        putClientProperty("JDesktopPane.dragMode", "outline");
    }
    
    
    public void reset(){
    	//JInternalFrame [] frames=getAllFrames();
    	//for (int i=0;i<frames.length;i++)
    	    //remove(getIndexOf(frames[i]));//frames[i].dispose();
    	//frames=null;
    	//frames=getAllFrames();
    	removeAll();
	   	repaint();
    	//System.out.println("Reset: "+frames.length+" opened frames");
    }

    /**
     * Returns the frame matching s if it exists, else returns null.
     * <P><A HREF="../source/GraphicDesktop.html#fetchFrame">Source</A>
     */
    ///fetchFrame
    public JInternalFrame fetchFrame(String name) {
        JInternalFrame [] tab = getAllFrames();
        JInternalFrame frameFound = null;
        
        if (tab!=null)
            for (int i=0;i<tab.length;i++) {
                String tmpName = (tab[i].getAccessibleContext()).getAccessibleName();
                if (tmpName.equals(name)) {
                    frameFound = tab[i];
                    break;
                }
            }
                
        return frameFound;
    }
    
    public void selectOnly(String name) {
        JInternalFrame [] tab = getAllFrames();
        
        if (tab == null) return;
        
        for (int i=0;i<tab.length;i++) {
            String tmpName = (tab[i].getAccessibleContext()).getAccessibleName();
            
            if (tmpName.equals(name)) selectFrame(tab[i]);
            else unselectFrame(tab[i]);
        }
    }
    
    private void selectFrame(JInternalFrame frame) {
        try {
            frame.setSelected(true);
        }
        catch (java.beans.PropertyVetoException ex) {
            System.out.println("selectFrame : [ "+ex.getMessage()+" ]");
        };
    }
    
    private void unselectFrame(JInternalFrame frame) {
        try {
            frame.setSelected(false);
        }
        catch (java.beans.PropertyVetoException ex) {
            System.out.println("unselectFrame : [ "+ex.getMessage()+" ]");
        };
    }
    
    public JInternalFrame getSelectedFrame(){
    	JInternalFrame [] tab=getAllFrames();
        JInternalFrame frameFound=null;
        for (int i=0;i<tab.length;i++)
            if (tab[i].isSelected()){
            	frameFound=tab[i];
            	break;
            }
        return frameFound;
    }
    
    /**
     * Open the frame matching name, or if the frame doesn't exit
     * create a new one initialised with gctab.
     * If the frame is found, gctab won't be used.
     * gctab is only used in case name doesn't exist.
     * openFrame(name,null) is possible, if the frame exits it will open it.
     * <P><A HREF="../source/GraphicDesktop.html#openFrame">Source</A>
     */
    ///openFrame
    public void openFrame(String name, GenericComponent [] gctab) {
		ComponentInternalFrame frameFound = (ComponentInternalFrame)fetchFrame(name);
		
        if (frameFound == null) {
            //TMUtility.display("openFrame","frameFound is null.");
            createFrame(name,gctab);
        } else {
        	DesktopManager dm = getDesktopManager();
            
            //########################## Manager access #################
            if (currentFrame!=name) Manager.nodeSelectionVeto=true;
            dm.deiconifyFrame(frameFound);
            try {
            	frameFound.setSelected(true);
            }
            catch (java.beans.PropertyVetoException ex) {
                System.out.println("openFrame : [ "+ex.getMessage()+" ]");
            };    	
            frameFound.updateScrollBar(getFrameDimensionRequired(gctab));
        }
        updateSize();
    }

    // added for text view frames - kvlinden, 22feb00
    public void openTVFrame(String name, String htmlPathName) {
		// This should be smarter about existing TV frames...
		createTVFrame(name,htmlPathName);
        updateSize();
    }
    
    // Added to create text view frames - kvlinden, 22feb00
    private void createTVFrame(String name, String htmlPathName) {
        if (htmlPathName!=null) {
            TVInternalFrame frame = new TVInternalFrame(name,htmlPathName);
            add(frame);
            
            frame.setVisible(true);   // due to incompatibility of Java JDK V.1.3 and V.1.2.2

            try {
                frame.setSelected(true);
            }
            catch (java.beans.PropertyVetoException ex) {
                System.out.println("createTVFrame : [ "+ex.getMessage()+" ]");
            }
        }
        else {
            System.out.println("Can't open the HTML file: " + htmlPathName);
        }
    }
    
    public void openInvisibleFrame(String name,GenericComponent [] gctab) {
		ComponentInternalFrame frameFound=(ComponentInternalFrame)fetchFrame(name);
        if (frameFound==null) createInvisibleFrame(name,gctab);
    }
    
    
    /**
     * Update the frame of a given name with gctab. Do nothing if no frame
     * found.
     * <P><A HREF="../source/GraphicDesktop.html#updateFrame">Source</A>
     */
    ///updateFrame
     public void updateFrame(String name,GenericComponent [] gctab) {
         ComponentInternalFrame frame = (ComponentInternalFrame)fetchFrame(name);
         if (frame!=null) frame.updateGraphicPanel(gctab);
     }
     
    
    /**
     * Create a new frame, even if a frame of the same name already exits
     * If gctab is null, the frame will be empty.
     * <P><A HREF="../source/GraphicDesktop.html#createFrame">Source</A>
     */
    ///createFrame
    private void createFrame(String name,GenericComponent [] gctab) {
    	if (gctab != null) {
    		GenericComponent [] gctab2;
	    	LinkedList l = new LinkedList();
	    	
    		for (int i=0;i<gctab.length;i++)
    		    if (!(gctab[i] instanceof Link)) l.add(gctab[i]);
    		    
	    	gctab2 = new GenericComponent[l.size()];
    		int length = l.size();
    		
    		for (int i=0;i<length;i++)
    			gctab2[i]=(GenericComponent)l.removeFirst();
    	
	        ComponentInternalFrame frame = new ComponentInternalFrame(name,gctab2);
    	    add(frame);
            
            frame.setVisible(true);   // due to incompatibility of Java JDK V.1.3 and V.1.2.2
        	
    	    try {
            	frame.setSelected(true);
	        }
	        catch (java.beans.PropertyVetoException ex) {
                System.out.println("createFrame : [ "+ex.getMessage()+" ]");
            }                
	        
	        frame.updateScrollBar(getFrameDimensionRequired(gctab2));
        
    	    if (gctab2.length != gctab.length) updateFrame(name,gctab);
        }
        else {
            //setVisible(true);
            //boolean bb = isShowing();
            //System.out.println("bb = "+bb);
            
	        ComponentInternalFrame frame = new ComponentInternalFrame(name,gctab);

            frame.setVisible(true);   // due to incompatibility of Java JDK V.1.3 and V.1.2.2
            
            add(frame);

        	try {
            	frame.setSelected(true);
                //System.out.println("frame selected1 : "+frame.isSelected());
        	}
        	catch (java.beans.PropertyVetoException ex) {
                System.out.println("createFrame : [ "+ex.getMessage()+" ]");
            }
            
            //System.out.println("frame selected2 : "+frame.isSelected());
        	
        	frame.updateScrollBar(getFrameDimensionRequired(gctab));

            //System.out.println("frame selected3 : "+frame.isSelected());
        }

        Manager.graphicToolBar.setVisible(true);
    }
    
    //not working
    private void createInvisibleFrame(String name,GenericComponent [] gctab) {
    	ComponentInternalFrame frame;
    	if (gctab!=null) {
	    	GenericComponent [] gctab2;
    		LinkedList l=new LinkedList();
    		for (int i=0;i<gctab.length;i++)
    	    	if (!(gctab[i] instanceof Link)) l.add(gctab[i]);
	    	gctab2=new GenericComponent[l.size()];
    		int length=l.size();
    		for (int i=0;i<length;i++) 
    			gctab2[i]=(GenericComponent)l.removeFirst();
    	
	        frame = new ComponentInternalFrame(name,gctab2);

            add(frame);
            
            frame.setVisible(true);   // due to incompatibility of Java JDK V.1.3 and V.1.2.2
            
	        try {
    	        frame.setSelected(true);
        	}
        	catch (java.beans.PropertyVetoException ex) {
                System.out.println("createInvisibleFrame : [ "+ex.getMessage()+" ]");
            }
            
	        frame.updateScrollBar(getFrameDimensionRequired(gctab2));
        
    	    if (gctab2.length!=gctab.length) updateFrame(name,gctab);
        }
        else {
	        frame = new ComponentInternalFrame(name,gctab);

            add(frame);
            
            frame.setVisible(true);   // due to incompatibility of Java JDK V.1.3 and V.1.2.2
            
        	try {
            	frame.setSelected(true);
	        }
	        catch (java.beans.PropertyVetoException ex) {
                System.out.println("createInvisibleFrame : [ "+ex.getMessage()+" ]");
            }
            
        	frame.updateScrollBar(getFrameDimensionRequired(gctab));
        }

        Manager.graphicToolBar.setVisible(true);
        frame.setVisible(false);
    }

    
    /**
     * Disposes a frame given its name. Do nothing if no frame found
     * <P><A HREF="../source/GraphicDesktop.html#deleteFrame">Source</A>
     */
    ///deleteFrame
    public void deleteFrame(String name) {
    	JInternalFrame frame = fetchFrame(name);
    	if (frame!=null) {
    		frame.dispose();
    		remove(frame);
    	}
    	updateSize();
    }


    /**
     * Calculate the dimension of panel necessary to show every 
     * components. If the panel is bigger than than the frame, some
     * scroll bars may appear.
     */
    protected static Dimension getFrameDimensionRequired(GenericComponent [] gctab){
    	if (gctab==null) return null;//Nothing to be done.
    	// if we return (new Dimension(ComponentInternalFrame.GRAPHICPANEL_WIDTH,ComponentInternalFrame.GRAPHICPANEL_HEIGHT));
    	// A useless scrollBar can appear.
    	else {
    	    int maxX=ComponentInternalFrame.GRAPHICPANEL_WIDTH;
    	    int maxY=ComponentInternalFrame.GRAPHICPANEL_HEIGHT;
    	    int tempx=0;
    	    int tempy=0;
    	    for (int i=0;i<gctab.length;i++) {
                tempx=gctab[i].getX()+gctab[i].getWidth();
                tempy=gctab[i].getY()+gctab[i].getHeight();
                if (tempx>maxX) maxX=tempx;
                if (tempy>maxY) maxY=tempy;
            }
            return (new Dimension(maxX,maxY));
        }
    }
    
    
    protected void updateSize() {
    	JInternalFrame [] tab=getAllFrames();
    	int maxw=getWidth();
    	int maxh=getHeight();
    	//System.out.println("Desktop: "+maxw+"  "+maxh);
    	int temph,tempw;
    	for (int i=0;i<tab.length;i++) {
    	    tempw=tab[i].getX()+tab[i].getWidth();    	    
    	    temph=tab[i].getY()+tab[i].getHeight();
    	    if (tempw>maxw) maxw=tempw;
    	    if (temph>maxh) maxh=temph;
    	}
    	//System.out.println("Desktop will be: "+maxw+"  "+maxh);
    	setPreferredSize(new Dimension(maxw,maxh));
    	revalidate();
    	//System.out.println("Desktop: "+getWidth()+"  "+getHeight());
    }
    
    /**
     * Close a frame given its name. Do nothing if no frame found
     * <P><A HREF="../source/GraphicDesktop.html#deleteFrame">Source</A>
     */
    ///CloseFrame
    public void closeFrame(String name) {
        try {
            JInternalFrame frame=fetchFrame(name);
            if (frame!=null) frame.setClosed(true);
            updateSize();
        }
        catch(PropertyVetoException ex) {
            System.err.println(ex.getMessage());
        }
    }
}

class CustomDesktopManager extends DefaultDesktopManager {
	
	public void setBoundsForFrame(JComponent f,int newX,int newY, int newWidth,int newHeight) {
		super.setBoundsForFrame(f,newX,newY,newWidth,newHeight);
     	 
     	Manager.desktop.updateSize();     	 
    }
     
    public void closeFrame(JInternalFrame f) {
    	super.closeFrame(f);
     	 
     	if (Manager.desktop.getAllFrames().length==0) 
     	 	Manager.graphicToolBar.setVisible(false);
    }
}