/*
   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 domainModel.*;

import java.util.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.print.*;
import javax.swing.*;
import java.lang.reflect.*;
import java.net.*;
import java.io.*;
import java.beans.*;
import utility.*;


/**
 * Manager provide an access to each function required by the GUI.
 */
public class Manager /*extends ManagerToolKit*/{ 

    //tape_recorder
    public static boolean guiEnableFlag = true;

    protected static AttributesPanel attributesPanel;
    protected static KernelTree skeleton;
    protected static FileManager fileManager;
    protected static DisplayManager displayManager;
    protected static OptionsManager optionsManager;
    protected static MainTree tree;
    protected static GraphicDesktop desktop;
    protected static GraphicToolBar graphicToolBar;
    protected static RTFDataBase RTFDB;
    protected static RTFPane editor;
    protected static RTFManager RTFDBM;
    
    //20-2-2002
    protected static SystemOptions systemOptions = new SystemOptions();

    private static XManager xDm =null; // domain model manager  

    static {
		
		if (Manager.getSysOption().getDomainF())
			xDm= new XManager();
	}
	

    public static DomainModelManager dmManager;
    
    protected static JPopupMenu popup;
        
    protected static MainMenu menu;
    
    protected static GenericComponent currentComponent=null;
    
    protected static boolean nodeSelectionVeto=true;
    
    
    protected static String ROOT_STRING;
    
    protected static String searchName="";
    protected static String searchParentName="";
    
    protected static int progressBarValue=0;    // used to pass progress bar vaule between threads
    
    // decide which attribute to include in the HTML report
    protected static TreeMap taskAttributesBool = new TreeMap();
    
    // contains all public fields of Task & their indexes
    protected static TreeMap filedsKey = new TreeMap();
    
    // contains all fields available in HTML Report Settings & their indexes
    protected static TreeMap filedsKeyForHTML = new TreeMap();  
        
    protected static int currentUnusedID = 1;

    protected static Cursor waitCursor = new Cursor(Cursor.WAIT_CURSOR);
	protected static Cursor normalCursor = new Cursor(Cursor.DEFAULT_CURSOR);
    
    protected static final boolean displayLinkInTreeEnableFlag = true;
    
    
    //shijian 2001-4-17
    protected static SortArrayList _predecessorComponents = 
    	new SortArrayList (new GCCompare());
    protected static SortArrayList _successorComponents = 
    	new SortArrayList (new GCCompare());

    //tape_recorder
	public Manager(boolean guiEnableFlag) {
        this.guiEnableFlag = guiEnableFlag;
        
    	skeleton = new KernelTree(ROOT_STRING);
    	RTFDB = new RTFDataBase();
    	
    	//shijian 25-9-2001
    	RTFDBM =new RTFManager();
    	
    	//Static ! 
    	displayManager = new DisplayManager();
    	optionsManager = new OptionsManager();
    	dmManager = new DomainModelManager();
        
        if (guiEnableFlag) {
            tree = MainFrame.tree;
            editor = MainFrame.editor;
            attributesPanel = MainFrame.attributesPanel;
            desktop = MainFrame.desktop;
            graphicToolBar = MainFrame.graphicToolBar;
            menu = MainFrame.menu;
            
            popup = MainFrame.popup;
            
            // this is necessary when the lightweight popup is overlapped by a heavy weight
            // dialog box => trace of popup menu items may leave displayed undesirably
            popup.setLightWeightPopupEnabled(false);
        }
        else {
            tree=TapeRecorder_MainFrame.tree;
        }
        
    	ROOT_STRING=MainTree.ROOT_STRING;
    	    	
        if (guiEnableFlag) {
            systemOptions.readFile();
            menu.setOptions();
        }
        
    	fileManager=new FileManager(guiEnableFlag);
    	
        if (guiEnableFlag) {
        	editor.reset();
        }
    	
    	tree.expandRow(0);
    	tree.setSelectionRow(0);
        
        if (guiEnableFlag) {
            openChildFrame(tree.getPathForRow(0));
            
            // to include all attribute in the html report by defualt 
            Task task= new Task();
            Field[] filds= task.getClass().getFields(); //getDeclaredFields(); 
            
            String fieldName;
            for(int i = 18; i < filds.length; i++) {
                fieldName = filds[i].getName();
                
                filedsKey.put(fieldName,new Integer(i));
                filedsKeyForHTML.put(fieldName,new Integer(i));
               
                // default settings for HTML report generation
                if (HTMLReportSettingDialog.checkIfIncludedInHTMLReportSettings(fieldName))
                    taskAttributesBool.put(fieldName,new Boolean(false));
            }
    
            HTMLReportSettingDialog.readHTMLReportSettings();
        }
    }
    
    //----------------------------------------------------------------
    //				I O
    //----------------------------------------------------------------
    public static void exportHTML() {
    	fileManager.exportHTML();
    }
    
    public static void exportHTMLfromXSL() {
        if (fileSavedForXSL()) {
            fileManager.exportHTMLfromXSL();
        }
    }
        
    public static void exportLG(){
    	fileManager.exportLG();  
    	
    }
    
    public static void importDomain(){
    	fileManager.importDomain();
    }
    
	//Thomas
    //public static void save() {
    public static boolean save() {
    	//fileManager.save();
    	if (fileManager.save()) {
	    	FileManager.MODIFIED=false; 
    		MainFrame.mainFrame.changeTitle();
    		return true;
    	}
    	else
    		return false;
    }
    
    public static void saveAs(){
    	fileManager.saveAs();
    	FileManager.MODIFIED=false; 
    	MainFrame.mainFrame.changeTitle();
    }
    
    //tape_recorder
    public static void saveAs(String fileName) {
        fileManager.saveAs(fileName);
        FileManager.MODIFIED=false; 

        if (guiEnableFlag) {
            MainFrame.mainFrame.changeTitle();
        }
    }
    
    //tape_recorder
    public static void readXML(String fileName) {
        if (fileSaved()) {
            if (fileManager.readXML(fileName)) {
                if (guiEnableFlag) {
                    MainFrame.mainFrame.changeTitle();
                }
                
                resetGUI();
                tree.fill(skeleton);
                tree.expandRow(0);
                tree.setSelectionRow(0);
                openChildFrame(tree.getPathForRow(0));
            }
        }
    }
    
    public static void open() {
    	if (fileManager.open()) {
     	    MainFrame.mainFrame.changeTitle();
    	    resetGUI();
    	    tree.fill(skeleton);
    	    tree.expandRow(0);
    	    tree.setSelectionRow(0);
    	    openChildFrame(tree.getPathForRow(0));
    	}
    	//openAllFramesInternaly();
    }
    
    public static void open(JProgressBarDia jpbarDia) {
        if (fileSaved()) {
	    	if (fileManager.open(jpbarDia)) {
	     	    MainFrame.mainFrame.changeTitle();
	    	    resetGUI();
	    	    tree.fill(skeleton);
	    	    tree.expandRow(0);
	    	    tree.setSelectionRow(0);
	    	    openChildFrame(tree.getPathForRow(0));
	    	}
	    	//openAllFramesInternaly();
        }
    }
    
    public static void domainDialog() {
    	dmManager.editor();
    }
    
    public static void resetID() {
    	currentUnusedID = 1;
    }
    
    //tape_recorder
    private static void resetGUI(){
    	tree.reset();

        if (guiEnableFlag) {
            tree.setVisible(false);
            desktop.reset();
            //System.out.println("Manager: resetGUI, desktop="+desktop);
            //desktop.setVisible(false);
            //desktop=null;
            //desktop=new GraphicDesktop();
            //System.out.println("Manager: resetGUI, desktop="+desktop);
            tree.setVisible(true);
            attributesPanel.reset();
            editor.reset();
            ComponentInternalFrame.resetCount();
        }
    }
    
    //tape_recorder
    public static void newTree(){
    	if (fileSaved()) {	
            if (guiEnableFlag) {
                MainFrame.TITLE_VARIABLE = MainFrame.TITLE_NEW;
                MainFrame.mainFrame.changeTitle();
                FileManager.FILE_NAME= MainFrame.TITLE_NEW;
            }
            
            resetID();
            
            if (guiEnableFlag) {
                resetGUI();
            }
            
            skeleton=new KernelTree(ROOT_STRING);
            tree.fill(skeleton);
                
            RTFDB=new RTFDataBase();
            //shijian 25-9-2001
            RTFDBM=new RTFManager();
            
            //dmManager=new DomainModelManager();
                    
            // create new DOM doc
            //fileManager.setXDM(new XManager());
            
           
            tree.expandRow(0);
            tree.setSelectionRow(0);
            openChildFrame(tree.getPathForRow(0));
            
            FileManager.CURRENT=null;
            FileManager.CURRENT_EXP=null;
            FileManager.CURRENT_HTML=null;
    
            FileManager.MODIFIED=false;
            
            //shijian 2001-3-28
            //now delete all domain elements
            if (Manager.getSysOption().getDomainF())
            	xDm.getDmManager().clearDMAll();
            
    	}
    }
    
    public static void resizeAll(double ratio){
    	GenericComponent.u=GenericComponent.u*ratio;
    	resizeNode(skeleton.root,ratio);
    	resizePanels();
    }

    
    private static void resizeNode(Node n,double ratio){
    	Collection c = n.values();
    	TreeMap t;
    	GenericComponent gc;
    	Couple couple;
    	Node child;
    	Rectangle r=new Rectangle();
    	for (Iterator i=c.iterator();i.hasNext();){
    		t = (TreeMap)i.next();
    	    couple=(Couple)t.get(t.firstKey());
    	    gc=couple.object;
    	    child=couple.node;
    	    if (gc instanceof LinkableComponent){
    	    	LinkableComponent lc=(LinkableComponent)gc;
    	        r.width=(int)Math.round(gc.getWidth()*ratio);
    	        r.height=(int)Math.round(gc.getHeight()*ratio);
    	        lc.backupX*=ratio;
    	        lc.backupY*=ratio;
    	        r.x=(int)Math.round(lc.backupX);
    	        r.y=(int)Math.round(lc.backupY);
    	        gc.setBounds(r);
    	    }
    	    if (!child.isEmpty()) resizeNode(child,ratio);    	    
    	}
    	
    	if (DisplayManager.centeredZoom){
    	    JInternalFrame [] tab=desktop.getAllFrames();
            JInternalFrame frameFound=null;
            if (tab!=null){
                GraphicPanel gpanel;
                for (int i=0;i<tab.length;i++){
            	    gpanel=((ComponentInternalFrame)tab[i]).gpanel;
            	    r=gpanel.getVisibleRect();
    	            r.x=r.x+(int)Math.round(r.width*(ratio-1)/2);
    	            r.y=r.y+(int)Math.round(r.height*(ratio-1)/2);
            	    gpanel.scrollRectToVisible(r);
                }
            }
        }    	
    }
    
    protected static void resizePanels(){
        JInternalFrame [] tab=desktop.getAllFrames();
        GraphicPanel gpanel;
        Component [] comps;
        int maxw,maxh,tempw,temph;
        for (int j=0;j<tab.length;j++){
            gpanel=((ComponentInternalFrame)tab[j]).gpanel;
            comps=gpanel.getComponents();
            if (DisplayManager.centeredZoom){
    	        maxw=gpanel.getWidth();
    	        maxh=gpanel.getHeight();            	
            }else{
    	        maxw=0;
    	        maxh=0;
    	    }
    	    for (int i=0;i<comps.length;i++){
    	        tempw=comps[i].getX()+comps[i].getWidth();    	    
    	        temph=comps[i].getY()+comps[i].getHeight();
    	        if (tempw>maxw) maxw=tempw;
    	        if (temph>maxh) maxh=temph;
    	    }
    	    gpanel.setPreferredSize(new Dimension(maxw,maxh));
    	    gpanel.revalidate();
        }
    }
    
    public static void printFrame() {
    	JOptionPane.showMessageDialog(MainFrame.mainFrame,"Use 'Export HTML' to print the complete model","Information",JOptionPane.INFORMATION_MESSAGE);
    	JInternalFrame frame=desktop.getSelectedFrame();
    	if (frame!=null){
            final GraphicPanel comp=(GraphicPanel)((JScrollPane)frame.getContentPane().getComponent(0)).getViewport().getView();    	
    	    // A Thread is required, otherwise the main frame won't be
    	    //repainted since it waits for the end of the print dialog
    	    (new Thread(){
    	    	public void run(){
                    PrinterJob printJob=PrinterJob.getPrinterJob();
                    printJob.setPrintable(comp);
                    if (printJob.printDialog()) {
                        try {
                            printJob.print();
                        } catch (Exception ex) {ex.printStackTrace();}
                    }
                }
            }).start();
        }
    }

    public static void debug() {
        skeleton.printRegister();
    }

    //----------------------------------------------------------------
    //                      Selection methods
    //----------------------------------------------------------------
    
    /**
     * Selects a GenericComponent.
     * If it is the root, deselect and highlight the root.
     */
/*    public static void select(String treePath){
    	String s=treePathToString(treePath);
    	else if (isInTree(s)) select(toParentNode(s).getComponent(s));
    }*/    
    
    /**
     * Select a GenericComponent in its frame. Then update the tree
     * (The node of the concerning this element is highlighted)
     * Do nothing if the component is not in the tree.
     */
    public static void select(TreePath treePath) {
    	String s=treePathToString(treePath);
    	if (skeleton.isRoot(s)) {
    	    if (currentComponent!=null){
    	    	currentComponent.setSelected(false);
    	    	currentComponent.repaint();
    	    }
    	    Manager.selectNode(fetchTreePath(skeleton.ROOT_STRING,null,tree));
    	    //editor.name=skeleton.ROOT_STRING;
            //editor.load(RTFDB.getDocument(skeleton.ROOT_STRING));
    	    currentComponent=null;
    	}
    	else {
    	    String parentS=treePathToString(truncTreePath(treePath));
    	    GenericComponent c=skeleton.stringToGenericComponent(s,parentS);
    	    if (!((c.isSelected())||(c==currentComponent))){
                if (currentComponent!=null) {
            	    currentComponent.setSelected(false);
                    currentComponent.repaint();
                }
                c.setSelected(true);
                c.repaint();
                //Update the tree
                selectNode(treePath);
                
                if (guiEnableFlag) {
                    attributesPanel.displayAttributes(c);
                    editor.name=c.getName();
                    //editor.load(RTFDB.getDocument(c.getName()));
                    //shijian 25-9-2001
                    editor.load(c.getName());
                }
                
                currentComponent=c;
            }
        }
        
        //shijian 2001-3-22
    	menu.setOptions(currentComponent);
  }

    public static void select(GenericComponent gcSel,TreePath treePath,Integer id2) {
    	String name = treePathToString(treePath);
    	
    	//shijian 2001-3-12
    /*	
    	if (skeleton.isRoot(name)) {
    	    if (currentComponent!=null){
    	    	currentComponent.setSelected(false);
    	    	currentComponent.repaint();
    	    }
    	    Manager.selectNode(fetchTreePath(skeleton.ROOT_STRING,null,tree));
    	    //editor.name=skeleton.ROOT_STRING;
            //editor.load(RTFDB.getDocument(skeleton.ROOT_STRING));
    	    currentComponent=null;
    	}
    	else {
    */	    //String parentName = treePathToString(truncTreePath(treePath));
    	    
    	    //GenericComponent c = skeleton.stringToGenericComponent(name,parentName,id2);
            //GenericComponent c = tmpGetComponent(name,parentName,id2);
            GenericComponent c = gcSel;
            
    	    if (!((c.isSelected())||(c==currentComponent))) {
                if (currentComponent!=null) {
            	    currentComponent.setSelected(false);
                    currentComponent.repaint();
                }
                
                c.setSelected(true);
                c.repaint();
                
                //c.displayInfo();
                //displayTreePath(treePath);
                
                //Update the tree
                selectNode(treePath);

                if (guiEnableFlag) {
                    attributesPanel.displayAttributes(c);
                    editor.name=c.getName();
                    //editor.load(RTFDB.getDocument(c.getName()));
                    //shijian 25-9-2001
                    editor.load(c.getName());
                }
                
                currentComponent=c;
            } else {
                //TMUtility.display("select","update node");
                selectNode(treePath);
            }
            
         	//shijian 2001-3-22
    		menu.setOptions(currentComponent);
      // }
    }
    
    public static void select(TreePath treePath,Integer id2) {
        GenericComponent gcSel = null;
        
        String name = treePathToString(treePath);
        
        if (!skeleton.isRoot(name)) {
            String parentName = treePathToString(truncTreePath(treePath));
            
            gcSel = getComponent(name,parentName,id2);
        }
        
        select(gcSel,treePath,id2);
    }
    
    private static GenericComponent getComponent(String name,String parentName,Integer id2) {
        Node firstCurrentNode = skeleton.toChildNode(parentName);
        GenericComponent result = firstCurrentNode.getComponent(name,id2);
        return result;
    }


    public static void displayTreePath(TreePath treePath) {
    	int nb = treePath.getPathCount();
    	Object [] objects = new Object[nb];
    	objects = treePath.getPath();
    	
    	String name;
    	DefaultMutableTreeNode node;
    	System.out.print("displayTreePath : ");
    	for (int i=0; i<nb; i++) {
    		node = (DefaultMutableTreeNode)objects[i];
    		name = (String)node.getUserObject();
    		System.out.print(name+", ");
    	}
    	System.out.println("");
    }
    
    /**
     * Deselect and chose the parent a default position in the tree.
     */
    public static void deselect(GraphicPanel p){
    	//System.out.println("deselect!");
        if (currentComponent!=null){
            currentComponent.setSelected(false);
            currentComponent.repaint();
            currentComponent=null;
        }
        Component current=p;
        while (!(current instanceof JInternalFrame)) current=current.getParent();
    	String s=((ComponentInternalFrame)current).getName();
        selectNode(s);
        attributesPanel.displayAttributes(null);
        editor.name=null;
        editor.reset();
    	//System.out.println("Selection of: "+fetchTreePath(s,tree));        
    }

    /**
     * Deselect.
     */
    protected static void deselect(){
    	select(fetchTreePath(skeleton.ROOT_STRING,tree));
    }

    /**
     * Selected the node matching c in MainTree
     */
    /*public static void selectNode(GenericComponent c){
    	selectNode(c.getName());
    }*/
    
    /**
     * Selected the node matching s in MainTree
     */
    public static void selectNode(String s){
    	if (skeleton.isInTree(s)) tree.setSelectionPath(fetchTreePath(s,tree));
    	
    	//shijian 2001-3-22
    	menu.setOptions(null);

    }

    /**
     * Selected the node matching s in MainTree
     */
    public static void selectNode(TreePath t){
    	tree.setSelectionPath(t);
    	
    	//shijian 2001-3-22
    	menu.setOptions(null);

    }

    //Thomas : 
    // display tree paths of tmpTaskName
    // which tmpTaskName is in the nodeRegister of skeleton
    private static int displayTaskAndTreePath_WithFindNext(String tmpTaskName) {
    	String name;
		String [] options={"Ok","Cancel"};
        int c;
		
    	Set keys = ((TreeMap)skeleton.nodeRegister.get(tmpTaskName)).keySet();
		
        for (Iterator i=keys.iterator();i.hasNext();) {
            name=(String)i.next();
            //Manager.select(Manager.fetchTreePath(searchName,name,Manager.tree));
            select(fetchTreePath(tmpTaskName,name,Manager.tree));

            //String mesg =   "Task Name: "+ searchName+ "  Parent Name: " +  name;
	        String mesg =   "Task Name : \"" + tmpTaskName + 
    	        "\"\nParent Task Name : \"" + name + "\"";
        	JOptionPane.showMessageDialog(MainFrame.mainFrame,mesg);

            if (i.hasNext()) {
            	c=JOptionPane.showOptionDialog(MainFrame.mainFrame,
            		"Select next component ?","Search",
	            	JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE,
    	        	null,options,options[0]);
                        
        	    if (c!=0) return c;
            }
        }
        
        return 0;
    }
    
    //Thomas : 
    // display all the tasks and their tree paths for searchTaskName
    // which searchTaskName may have '*' for wild-card search
    private static void displayAllTaskAndTreePath(String searchTaskName) {
    	int i = searchName.indexOf('*');
    	
    	if (i<0) {
			displayTaskAndTreePath_WithFindNext(searchTaskName);
    	}
   		else {
			String [] options={"Ok","Cancel"};
	    	String tmpTaskName;
    		int c,iReturnValue;
    		boolean first = true;

	    	for (Iterator itTaskName = skeleton.taskNameIterator();itTaskName.hasNext();) {
		       	tmpTaskName = (String)(itTaskName.next());
		       	
		       	if (skeleton.string_wide_card_search(tmpTaskName,searchTaskName)) {
		       		if (first) first = false;
		       		else {
			       		c=JOptionPane.showOptionDialog(MainFrame.mainFrame,
    	        			"Select next component ?","Search",
			            	JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE,
    			        	null,options,options[0]);
                        
        			    if (c!=0) return;
		       		}
		       		
		       		iReturnValue = displayTaskAndTreePath_WithFindNext(tmpTaskName);
		       		if (iReturnValue != 0) return;     // return if user clicks 'Cancel'
		       	}
			}
   		}
    }

    //Thomas
    public static void search() {
    	String [] options={"Ok","Cancel"};

    	JPanel panel=new JPanel();
    	panel.setLayout(new GridLayout(2,2,10,10));
    	panel.add(new JLabel("Name"));
    	JTextField tname=new JTextField(searchName);
    	panel.add(tname);
    	panel.add(new JLabel("(Expansion name)"));
    	JTextField tparentName=new JTextField(searchParentName);
    	panel.add(tparentName);

    	int choice=JOptionPane.showOptionDialog(MainFrame.mainFrame,panel,
                "Search",JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE,
                null,options,options[0]);

        if (choice==0) {
            searchName=tname.getText();
            searchParentName=tparentName.getText();

            if (searchName.equals("")) 
                JOptionPane.showMessageDialog(MainFrame.mainFrame,"Invalid name!");
            //Thomas
            //else if (!skeleton.isInTree(searchName))     
            else if (!skeleton.isInTree_wild_card_search(searchName))     
                    JOptionPane.showMessageDialog(MainFrame.mainFrame,
                    	"Task \""+searchName+"\" not found!");
            else if (skeleton.isRoot(searchName)) 
                    select(fetchTreePath(skeleton.ROOT_STRING,tree));
            else if (searchParentName.equals(""))
            {
            	//Thomas
            	displayAllTaskAndTreePath(searchName);
            } 
            else if (!skeleton.isInTree(searchParentName)) 
                    JOptionPane.showMessageDialog(MainFrame.mainFrame,
                                   searchParentName+" not found!");
            else {
            	TreeMap t=(TreeMap)skeleton.nodeRegister.get(searchName);
            	if (t.containsKey(searchParentName)) 
            	    Manager.select(Manager.fetchTreePath(searchName,searchParentName,Manager.tree));
            	else JOptionPane.showMessageDialog(MainFrame.mainFrame,"No "+searchName+" in "+searchParentName+"!");
            }

        }
    	
    }

    /**
     * Opens a frame for a composite GenericComponent
     */
    protected static void openComposite(GenericComponent c,String parentName) {
    	if (c instanceof CompositeComponent) {
    		CompositeComponent cc = (CompositeComponent)c;
    		
    		String name = cc.getName();
           	Integer id2 = new Integer(cc.ID);
    		
            if ((cc.isComposite()) && skeleton.isInTree(name)) {
                TreePath treePath = fetchTreePath(name,parentName,tree,id2);

                tree.expandPath(treePath);
                
                openChildFrame(treePath);
            }
        }
    }
 
    /**
     * Opens the child frame if this frame is found
     */
    //tape_recorder
    protected static void openChildFrame(TreePath treePath) {
        if (!guiEnableFlag) return;
        
    	String name = treePathToString(treePath);
    	
    	if (skeleton.isInTree(name)) {
    		//get all GenericComponents in the decomposition window of name
    	    GenericComponent [] gctab = fetchComponents(treePath);
            
            //if (gctab != null)
            //    System.out.println("openChildFrame : length of gctab = "+gctab.length);
    	    
    	    desktop.openFrame(name,gctab);
    	}
    }

    /**
     * Opens the parent frame if this frame is found
     */
    //tape_recorder
    protected static void openParentFrame(TreePath treePath) {
        if (!guiEnableFlag) return;
        
    	String s=treePathToString(treePath);
    	if (skeleton.isInTree(s)){
    	    treePath=truncTreePath(treePath);
    	    s=treePathToString(treePath);
    	    GenericComponent [] gctab=fetchComponents(treePath);
            
    	    desktop.openFrame(s,gctab);
    	}
    }
    
    
    /**
     * Update the child frame if not empty. Destroys it else.
     */
    //tape_recorder
    protected static void updateChildFrame(TreePath treePath) {
        if (!guiEnableFlag) return;
        
    	String s = treePathToString(treePath);
    	if (skeleton.isInTree(s)) {
    	    GenericComponent [] gctab = fetchComponents(treePath);
    	    if ((gctab==null) && (!(skeleton.isRoot(s)))) deleteFrame(s);
    	    else desktop.updateFrame(s,gctab);
    	}
    }
    
    /**
     * Update the parent frame if not empty. Destroys it else (if it is not
     * the root frame).
     */
    //tape_recorder
    protected static void updateParentFrame(TreePath treePath) {
        if (!guiEnableFlag) return;
        
    	TreePath parentTreePath = truncTreePath(treePath);
    	
    	String parentName = treePathToString(parentTreePath);
    	
    	if (skeleton.isInTree(parentName)) {
    		//fetch all the GenericComponents of parentName
    	    GenericComponent [] gctab = fetchComponents(parentTreePath);
    	    
    	    if ((gctab == null) && (!(skeleton.isRoot(parentName)))) {
    	    	// remove frame if empty
    	    	deleteFrame(parentName);
    	    }
    	    else {
    	    	//redisplay the current frame
    	    	desktop.updateFrame(parentName,gctab);
    	    }
    	}
    }
    
    /**
     * Disposes a frame.
     */	
    //tape_recorder
    protected static void deleteFrame(String name) {
        if (!guiEnableFlag) return;
        
    	if (skeleton.isInTree(name))
    		desktop.deleteFrame(name);
    }
    
    
//--------------------------------------------------------------
//--------------------------------------------------------------
//--------------------------------------------------------------
//--------------------   ManagerToolKit    ---------------------
//--------------------------------------------------------------
//--------------------------------------------------------------
//--------------------------------------------------------------

    
    //---------------------------------------------------------------
    //               GenericComponents Layout
    //---------------------------------------------------------------
    /**
     * Check if the component's area intersects with the area of other 
     * components of the same branch. 
     */
    /*protected static boolean intersection(GenericComponent gc,Node n){
    	//Node n=toParentNode(gc);
    	boolean result=false;
    	Set keys=n.getKeys();
        for(Iterator it=keys.iterator();it.hasNext();){
            GenericComponent gc2=n.getComponent((String)(it.next()));
    	    if (gc2!=gc) if (gc2.intersection(gc)){
    	    	result=true;
    	    	break;
    	    }
    	}
    	return result;	
    }*/            


    protected static void autoPlaceAll(){
    	
    }


    protected static void autoPlace(String name,String parentName){
    	autoPlace(skeleton.stringToGenericComponent(name,parentName),skeleton.toParentNode(name,parentName));
    }
    
    /**
     * Automaticly place a component in a frame so that it could not
     * overlap with other component.
     */
    protected static void autoPlace(GenericComponent gc, Node n) {
        //TMUtility.display("autoPlace : gc",gc.name);
        
    	int maxWidth = ComponentInternalFrame.GRAPHICPANEL_WIDTH;      // max. width of the frame
    	final int GAP_X = 10;   // x gap to separate the last component with the new appended component
    	final int GAP_Y = 10;   // the corresponding y gap
    	
        //TMUtility.display("autoPlace : maxWidth",maxWidth);
        
    	LinkableComponent lc;
    	
    	// find a free space
    	int maxX = 0;       // (maxX,maxY) of the bottom-right point of all the components inside the node
    	int maxY = 0;
    	int maxmaxY = 0;
    	GenericComponent maxgc = null;   // the gc component to which (maxX,maxY) corresponds
    	int tempx,tempy;    // (x,y) of the bottom-right point of the individual component inside the node
    	
    	//Node n=toParentNode(gc);
        //if (n.size() > 1) {
    	if (n.getNumCouples() > 1) {
    	    Set keys = n.keySet();
    	    GenericComponent gc2;
            
            for (Iterator it = keys.iterator(); it.hasNext();) {
                String name = (String) it.next();
                TreeMap treeMap = (TreeMap) n.get(name);
                
                for (Iterator i2 = (treeMap.keySet()).iterator(); i2.hasNext();) {
                    Integer id2 = (Integer) i2.next();

                    gc2 = n.getComponent(name,id2);
                
                    if (gc2 != gc) {
                        //TMUtility.display("autoPlace : gc2",gc2.name);
                        
                        if (gc2 instanceof LinkableComponent) {
                            lc = (LinkableComponent) gc2;
                            tempx = gc2.getX() + (int) Math.round(lc.giveWidth() * lc.u);
                            tempy = gc2.getY() + gc2.getHeight();
                        } else {
                            tempx = gc2.getX() + gc2.getWidth();
                            tempy = gc2.getY() + gc2.getHeight();
                        }
                        
                        //TMUtility.display("autoPlace : tempx",tempx);
                        //TMUtility.display("autoPlace : tempy",tempy);
                        
                        if ((tempy > maxY) || ((tempy == maxY) && (tempx > maxX))) {
                            maxY = tempy;
                            maxX = tempx;
                            maxgc = gc2;
                        }

                        //TMUtility.display("autoPlace : maxX",maxX);
                        //TMUtility.display("autoPlace : maxY",maxY);
                    }
                }
    	    }
    	
    	    // A posible position has been found
    	    //maxX=gc2.getX+gc2.getWidth(); already done
    	    maxmaxY = maxY;    // (maxX,maxmaxY) of the bottom-right point of all the components inside the node
    	    maxY = maxgc.getY();   // (max,maxY) of the top-right point of the last bottom component inside the node
    	
            //TMUtility.display("autoPlace : maxmaxY",maxmaxY);
            //TMUtility.display("autoPlace : maxY",maxY);
            
    	    // Second verification:
            for (Iterator it = keys.iterator(); it.hasNext();) {
                String name = (String) it.next();
                TreeMap treeMap = (TreeMap) n.get(name);
                
                for (Iterator i2 = (treeMap.keySet()).iterator(); i2.hasNext();) {
                    Integer id2 = (Integer) i2.next();
                
                    gc2 = n.getComponent(name,id2);
                    
                    if (gc2 != gc) {
                        if (gc2 instanceof LinkableComponent) {
                            lc = (LinkableComponent)gc2;
                            tempx = gc2.getX() + (int) Math.round(lc.giveWidth() * lc.u);
                            tempy = gc2.getY() + gc2.getHeight();
                        } else {
                            tempx = gc2.getX() + gc2.getWidth();
                            tempy = gc2.getY() + gc2.getHeight();
                        }
                    
                        //TMUtility.display("autoPlace2 : tempx",tempx);
                        //TMUtility.display("autoPlace2 : tempy",tempy);
                        
                        if ((tempx > maxX) && (tempy > maxY)) {
                            maxY = tempy;
                        }

                        //TMUtility.display("autoPlace2 : maxY",maxY);
                    }
                }
    	    }
    	}
    	
    	GraphicPanel gp = (GraphicPanel)gc.getParent();
    	
    	int maxFrameWidth = 
            (gp == null) ? (ComponentInternalFrame.GRAPHICPANEL_WIDTH) : (gp.getWidth());
    	int maxFrameHeight = 
            (gp == null) ? (ComponentInternalFrame.GRAPHICPANEL_HEIGHT) : (gp.getHeight());
        
        //TMUtility.display("autoPlace3 : maxFrameWidth",maxFrameWidth);
        //TMUtility.display("autoPlace3 : maxFrameHeight",maxFrameHeight);
        
    	//necessary true
    	if (gc instanceof LinkableComponent) {
    	    lc = (LinkableComponent) gc;
            
            if (maxFrameWidth < gc.WIDTH) maxFrameWidth = gc.WIDTH;
            
            if ((maxX + gc.WIDTH) <= maxFrameWidth) {
                // if gc can be fit within the current row, append it in the current row
    	        gc.setLocation(maxX+GAP_X/*+(int)Math.round((lc.giveWidth()-lc.w0)*lc.u)*/,maxY);
            } else {
                // else append it in the beginning of the next row
                gc.setLocation(GAP_X/*+(int)Math.round((lc.giveWidth()-lc.w0)*lc.u)*/,maxmaxY+GAP_Y);
            }
            
    	    lc.backupX = lc.getX();
    	    lc.backupY = lc.getY();
            
            //TMUtility.display("autoPlace3 : backupX",lc.backupX);
            //TMUtility.display("autoPlace3 : backupY",lc.backupY);
    	} else {
            if (maxFrameWidth < gc.WIDTH) maxFrameWidth = gc.WIDTH;
            
            if ((maxX + gc.WIDTH) <= maxFrameWidth)
    	        gc.setLocation(maxX + GAP_X, maxY);
    	    else 
                gc.setLocation(GAP_X, maxmaxY + GAP_Y);
    	}

        //TMUtility.display("autoPlace3 : maxFrameWidth",maxFrameWidth);
        
        if ((gp != null) && ((gc.getY() + gc.getHeight()) >= maxFrameHeight)) {
            // update to the new dimension of the graphic panel when time available
            gp.setPreferredSize(new Dimension(maxFrameWidth, gc.getY() + gc.getHeight()));
            gp.revalidate();
        }

    }
    
    //----------------------------------------------------------------
    //           From the TreePath to the GenericComponent
    //----------------------------------------------------------------
    
    /**
     * Converts a TreePath to a String (which is the name of a 
     * GenericComponent).
     */
    public static String treePathToString(TreePath treePath) {
    	/*System.out.println("inside treePathToString()");
  
    	String mesg =   "Component Name: "+ (String)(((DefaultMutableTreeNode)(treePath.getLastPathComponent())).getUserObject());  
        System.out.println(mesg);*/

        //JOptionPane.showMessageDialog(MainFrame.mainFrame,mesg);
        return (String)(((DefaultMutableTreeNode)(treePath.getLastPathComponent())).getUserObject());    	
    		
    }
    
    /**
     * Converts a TreePath to a String (which is the name of a 
     * GenericComponent)
     */
    public static String treePathToString(TreePath treePath,int i){
    		String mesg =   "Component Name: "+i+ (String)(((DefaultMutableTreeNode)(treePath.getLastPathComponent())).getUserObject());  
        System.out.println(mesg);

    		//JOptionPane.showMessageDialog(MainFrame.mainFrame,mesg);

        return (String)(((DefaultMutableTreeNode)(treePath.getPathComponent(i))).getUserObject());    	
    }
        
    /**
     * Check in the register if the Treepath leads to a leaf.
     */
    public static boolean isLeaf(TreePath treePath){
    	return !skeleton.hasChildNode(treePathToString(treePath));
    }

    /**
     * True if the TreePath leads to the root.
     */
    public static boolean isRoot(TreePath treePath){
    	return (skeleton.isRoot(treePathToString(treePath)));
    }

    /**
     * Returns all the GenericComponents in a given branch. 
     * Null if the node has no branch (leaf) or if the last component is not is the tree.
     */
    public static GenericComponent [] fetchComponents(TreePath treePath) {
    	String name1 = treePathToString(treePath);
    	
    	if (skeleton.hasChildNode(name1)) {
    	    Node firstCurrentNode = skeleton.toChildNode(name1);
    	    
    	    if (firstCurrentNode.isEmpty()) return null;
    	    else {
    	        /*Set keys = firstCurrentNode.keySet();
    	        GenericComponent [] result = new GenericComponent[keys.size()];
    	        
    	        int count = 0;
                for(Iterator it = keys.iterator();it.hasNext();)
	            	result[count++] = firstCurrentNode.getComponent((String)(it.next()));*/
	            	
	            int numComponents = firstCurrentNode.getNumCouples();
                //System.out.println("fetchComponents : numComponents = "+numComponents);
    	        GenericComponent [] result = new GenericComponent[numComponents];

    	        Set keys = firstCurrentNode.keySet();
    	        int count = 0;
    	        String name;
    	        Integer childID;
    	        
                for (Iterator it = keys.iterator();it.hasNext();) {
                	name = (String)it.next();
                	
			        for (Iterator itID = firstCurrentNode.getIDIterator(name);itID.hasNext();) {
	    		    	childID = (Integer)itID.next();

				        result[count++] = firstCurrentNode.getComponent(name,childID);
			        }
                }
	            	
	        	return result;
    	    }
    	}
    	else return null; // Nothing inside this component
    }	

  
    //---------------------------------------------------------------
    //               From a GenericComponent to a TreePath
    //---------------------------------------------------------------
  
    /**
     * Return the position in the JTree of a GenericComponent,
     * null if the component is not in the tree.
     */
    /*public static TreePath fetchTreePath(GenericComponent c){
	return fetchTreePath(c.getName());
    }*/

    /**
     * Return the position in the JTree of a GenericComponent,
     * null if the component is not in the tree.     
     *
     * return nodes array from parentS to c given tree
     *
     */
    public static TreePath fetchTreePath(String taskName,String parentS,MainTree tree) {
    	if (skeleton.isInTree(taskName)) {
    	    DefaultMutableTreeNode [] tab;
    	    
    	    if (skeleton.isRoot(taskName)){
                tab = new DefaultMutableTreeNode[1];                
                tab[0] = (DefaultMutableTreeNode)((DefaultTreeModel)tree.getModel()).getRoot();      
            } else {
                // Create a String Stack
                Stack s = new Stack();
                
                s.push(taskName);
                s.push(parentS);
                
                String name = taskName;
                String parentName = parentS;
                TreeMap t;
                while (!parentName.equals(skeleton.ROOT_STRING)) {
    	            t = (TreeMap)skeleton.nodeRegister.get(parentName);
    	            name = parentName;
    	            parentName = (String)t.firstKey();
                    s.push(parentName);
                }
                //The Stack is now filled
            
                tab = new DefaultMutableTreeNode[s.size()];                
                DefaultMutableTreeNode jcurrent = 
                	(DefaultMutableTreeNode)((DefaultTreeModel)tree.getModel()).getRoot();
        
                String rootString = (String)s.pop();        // take out the ROOT_STRING "/"
                tab[0]=jcurrent;
                for (int i=1;i<tab.length;i++) {
                    String ref = (String)s.pop();

                    int count = 0;
                    for (Enumeration e = jcurrent.children();e.hasMoreElements();) {
             	        String temp = (String)((DefaultMutableTreeNode)(e.nextElement())).getUserObject();
             	        
             	        if (ref.equals(temp))
             	  	    	break;
             	        count++;
                    }

                    jcurrent = (DefaultMutableTreeNode)jcurrent.getChildAt(count);
                    
                    tab[i] = jcurrent;             
                } 
            }
            return (new TreePath(tab)); 
        }
        else return null;           	
    }

    public static TreePath fetchTreePath(String taskName,String parentS,MainTree tree,Integer id2) {
    	if (skeleton.isInTree(taskName)) {
    	    DefaultMutableTreeNode [] tab;
    	    
    	    if (skeleton.isRoot(taskName)){
                tab = new DefaultMutableTreeNode[1];                
                tab[0] = (DefaultMutableTreeNode)((DefaultTreeModel)tree.getModel()).getRoot();      
            } else {
                // Create a String Stack
                Stack s = new Stack();
                
                s.push(taskName);
                s.push(parentS);
                
                String name = taskName;
                String parentName = parentS;
                TreeMap t;
                while (!parentName.equals(skeleton.ROOT_STRING)) {
    	            t = (TreeMap)skeleton.nodeRegister.get(parentName);
    	            name = parentName;
    	            parentName = (String)t.firstKey();
                    s.push(parentName);
                }
                //The Stack is now filled
                
                int positionForDuplicatedTasks = skeleton.getPositionForDuplicatedTasks(taskName,parentS,id2);
            
                tab = new DefaultMutableTreeNode[s.size()];                
                DefaultMutableTreeNode jcurrent = 
                	(DefaultMutableTreeNode)((DefaultTreeModel)tree.getModel()).getRoot();
        
                String rootString = (String)s.pop();   // take out the ROOT_STRING "/" which corresponds to jcurrent
                tab[0]=jcurrent;
                
                for (int i=1;i<tab.length;i++) {
                    String ref = (String)s.pop();

                    //find index (stores in count) within jcurrent which points at ref
                    int count = 0;
                    for (Enumeration e = jcurrent.children();e.hasMoreElements();) {
             	        String temp = (String)((DefaultMutableTreeNode)(e.nextElement())).getUserObject();
             	        
             	        if (i == (tab.length-1)) {
             	        	// last node corresponding to taskName : 
             	        	// need to point to corresponding duplicated task
             	        	if (ref.equals(temp)) {
             	        		positionForDuplicatedTasks--;
             	        		if (positionForDuplicatedTasks == 0)
             	        			break;
             	        	}
             	        }
             	        else {
             	        	// same as before
             	        	if (ref.equals(temp))
             	  	    		break;
             	        }
             	        
             	        count++;
                    }

                    jcurrent = (DefaultMutableTreeNode)jcurrent.getChildAt(count);
                    
                    tab[i] = jcurrent;             
                } 
            }
            return (new TreePath(tab)); 
        }
        else return null;           	
    }

    /**
     * Return the position in the JTree of a GenericComponent,
     * null if the component is not in the tree.     
     */
    public static TreePath fetchTreePath(String c,MainTree tree) {
    	if (skeleton.isInTree(c)){
    	    DefaultMutableTreeNode [] tab;
    	    if (skeleton.isRoot(c)){
                tab=new DefaultMutableTreeNode[1];                
                tab[0]=(DefaultMutableTreeNode)((DefaultTreeModel)tree.getModel()).getRoot();      
            } else {
                // Create a String Stack
                Stack s=new Stack();
                s.push(c);
                String name=c;
                TreeMap t;
                while (!name.equals(skeleton.ROOT_STRING)) {
    	            t=(TreeMap)skeleton.nodeRegister.get(name);
    	            name=(String)t.firstKey();
                    s.push(name);
                }
                //The Stack is now filled
                //System.out.println("fetchTreePath --> "+s);
            
                tab=new DefaultMutableTreeNode[s.size()];                
                DefaultMutableTreeNode jcurrent=(DefaultMutableTreeNode)((DefaultTreeModel)tree.getModel()).getRoot();
        
                s.pop();        
                tab[0]=jcurrent;
                for (int i=1;i<tab.length;i++) {
                    //System.out.println("tour: "+i);
                    String ref=(String)s.pop();              
                    int count=0;
                    for (Enumeration e=jcurrent.children();e.hasMoreElements();){
             	        String temp=(String)((DefaultMutableTreeNode)(e.nextElement())).getUserObject();
             	        //System.out.println("ref="+ref+"   temp="+temp);
             	        if (ref.equals(temp))
             	  	    break;
             	        count++;
                    }
                    jcurrent=(DefaultMutableTreeNode)jcurrent.getChildAt(count);
                    tab[i]=jcurrent;             
                } 
            }
            return (new TreePath(tab)); 
        } else return null;           	
    }

    /**
     * Truncate the last object from the treePath.
     */
    public static TreePath truncTreePath(TreePath treePath){
    	int nb=treePath.getPathCount();
    	if (nb>1){
            Object [] o=treePath.getPath();
            Object [] o2=new Object[nb-1];
            for (int i=0;i<nb-1;i++) o2[i]=o[i];
            return (new TreePath(o2));
        }
    	else return null;
    }



    //Composite component fix 8-19-99
    public static void openAllFramesInternaly(){
    	openFramesInternaly(skeleton.ROOT_STRING,skeleton.root);
    }

    private static void openFramesInternaly(String s,Node node){
        Set set=node.keySet();
        GenericComponent [] tab=new GenericComponent[set.size()];
        LinkedList children=new LinkedList();
        int count=0;
        String name;
        int childCount=0;
        Node child;
        for (Iterator i=set.iterator();i.hasNext();count++){
            name=(String)i.next();
            tab[count]=node.getComponent(name);
            if (node.hasBranch(name)) {
            	children.add(name);
            	children.add(node.getChild(name));
            	childCount++;
            }
        }
        desktop.openFrame(s,tab);
        for (int i=0;i<childCount;i++){
            name=(String)children.removeFirst();
            child=(Node)children.removeFirst();
            openFramesInternaly(name,child);
        }
    }

    public static void openAllInvisibleFramesInternaly(){
    	openInvisibleFramesInternaly(skeleton.ROOT_STRING,skeleton.root);
    }

    private static void openInvisibleFramesInternaly(String s,Node node){
        Set set=node.keySet();
        GenericComponent [] tab=new GenericComponent[set.size()];
        LinkedList children=new LinkedList();
        int count=0;
        String name;
        int childCount=0;
        Node child;
        for (Iterator i=set.iterator();i.hasNext();count++){
            name=(String)i.next();
            tab[count]=node.getComponent(name);
            if (node.hasBranch(name)) {
            	children.add(name);
            	children.add(node.getChild(name));
            	childCount++;
            }
        }
        desktop.openInvisibleFrame(s,tab);
        for (int i=0;i<childCount;i++){
            name=(String)children.removeFirst();
            child=(Node)children.removeFirst();
            openInvisibleFramesInternaly(name,child);
        }
    }

    //tape_recorder
    public static boolean fileSaved() {
        if (FileManager.MODIFIED) {
            int choice;
            
            if (guiEnableFlag) {
                //String name=(String)alist.getSelectedValue();                
                String [] options={"Yes","No","Cancel"};
                choice=JOptionPane.showOptionDialog(MainFrame.mainFrame,
                    "Save changes made to '"+FileManager.FILE_NAME+"' ?","Warning",
                    JOptionPane.YES_NO_CANCEL_OPTION,JOptionPane.WARNING_MESSAGE,null,
                    options,options[0]);
            }
            else
                choice = 0;
            
            if (choice==0) {
            	//save();
            	//return true;
            	return save();
            }
            else if (choice==1) {
            	FileManager.MODIFIED=false; 
				return true;
	    	}
            else return false;
         }
         else return true;
	}

    public static boolean fileSavedForXSL() {
        if (FileManager.MODIFIED) {
            String [] options={"Yes","No","Cancel"};
            int choice=JOptionPane.showOptionDialog(MainFrame.mainFrame,
                "To generate HTML from XSL, the changes must be saved in XML first.\n\n"+
                "Save changes made to '"+FileManager.FILE_NAME+"' ?","Warning",
                JOptionPane.YES_NO_CANCEL_OPTION,JOptionPane.WARNING_MESSAGE,null,
                options,options[0]);
            
            if (choice==0) {
                return save();
            }
            else return false;
         }
         else return true;
    }
        
    public static   TreeMap getTaskAttributesBool() {
     	return taskAttributesBool;
  	}
     
        
     public static void setHTML()
     {
     	HTMLReportSettingDialog dialog = new HTMLReportSettingDialog(Manager.getTaskAttributesBool());
     	
     }
     
     public static void LGlogin()
     {
     	System.out.println ( "selected LG login:");
     	
     }

     public static void LGhelp  ()
     {
     	// System.out.println ( "selected LG Help");
         String helpInfor = "There is no reponse from the server. \n"+
                           "Please start the Language Generation server first!!!";


         final JFileChooser fc=new JFileChooser(fileManager.getFolder());
         fc.addChoosableFileFilter(new LGFilter());
         fc.setFileView(new LGFileView());
         if (fileManager.CURRENT_EXP != null) fc.setSelectedFile(fileManager.CURRENT_EXP);
         String approveButtonText="Generate";
         int returnVal=fc.showDialog(MainFrame.mainFrame,approveButtonText);
								//MainFrame.mainFrame);
         if (returnVal==JFileChooser.APPROVE_OPTION) {
             File f=fc.getSelectedFile();
             
             //FOLDER = f.getParent();
             //FILE_NAME = f.getName();  
             fileManager.CURRENT_EXP =f;          
             
             javax.swing.filechooser.FileFilter ff=fc.getFileFilter();
             if (ff instanceof LGFilter)
             {
             
                try
                {

                   //Properties props= new Properties();
                  /* String key = "file.separator";
                   String value = "/";
                   System.setProperty( key,  value) ;
                  */

                   LGServer lgServer= new LGServer();
                   lgServer.connect(lgServer.getLGServerName(), lgServer.getDEFAULT_portNumber() );

                   String fullPathName = fileManager.CURRENT_EXP.getCanonicalPath();
                   fullPathName = relpaceBackSlashWithForwardSlash(fullPathName);


                   //JOptionPane.showMessageDialog(MainFrame.mainFrame,fullPathName );
             
                   lgServer.generateOLP(fullPathName);
                } catch (UnknownHostException e)
                {JOptionPane.showMessageDialog(MainFrame.mainFrame, helpInfor);
                } catch (IOException e)
                {JOptionPane.showMessageDialog(MainFrame.mainFrame, helpInfor);
                } catch (InterruptedException e)
                {JOptionPane.showMessageDialog(MainFrame.mainFrame, helpInfor);}


             }
         }

     
     
      }


     protected static String relpaceBackSlashWithForwardSlash(String s){
           
          int m = s.length();
          if (m == 0) return  s;

          StringBuffer sb=new StringBuffer("");
          for (int i = 0; i<m;i++ )
          {
              if (s.charAt(i) == '\\')  sb.append('/');
              else sb.append(s.charAt(i));

          }


          return sb.toString();

     }

      //exportGenerateLG()

    public static void exportGenerateLG(){

	System.out.println("here we are...");

    	if (fileManager.exportGenerateLG()) {  
	    	//System.out.println ( fileManager.FILE_NAME);
	        System.out.println ( fileManager.CURRENT_EXP.getAbsolutePath());
	
	        String helpInfor = "There is no reponse from the server. \n"+
	                           "Please start the Language Generation server first!!!";
	                           
	       try  
	       {
	
	          LGServer lgServer= new LGServer();
	          lgServer.connect(lgServer.getLGServerName(), lgServer.getDEFAULT_portNumber() );
	          String fullPathName = fileManager.CURRENT_EXP.getCanonicalPath();
	          
	          fullPathName = relpaceBackSlashWithForwardSlash(fullPathName);
	      
	          //JOptionPane.showMessageDialog(MainFrame.mainFrame,fullPathName ); 
	      
	          lgServer.generateOLP(fullPathName);
	       } catch (UnknownHostException e)
	       {JOptionPane.showMessageDialog(MainFrame.mainFrame, helpInfor);
	       } catch (IOException e)
	       {JOptionPane.showMessageDialog(MainFrame.mainFrame, helpInfor);  
	       } catch (InterruptedException e)
	       {JOptionPane.showMessageDialog(MainFrame.mainFrame, helpInfor);}
	       
	       
	        // code to add for text view - kvlinden, 22feb00 
       		//     probably should check the feedback from generateOLP() before doing this...
       		String fileroot = fileManager.CURRENT_EXP.getAbsolutePath();

            //desktop.openTVFrame("TV", 
			//   fileroot.substring(0, fileroot.lastIndexOf('.')) + ".html");
            openTVFrame("TV", 
               fileroot.substring(0, fileroot.lastIndexOf('.')) + ".html");

    	}

    }
    

    public static void setLGServerName(){
        MainFrame.mainFrame.repaint();
        LGserverDialog dialog=new LGserverDialog();


   }
   
    public static void markTaskDirty(String taskName, boolean b) {
		if (Manager.skeleton.isInRegister(taskName)){
        	Node n=Manager.skeleton.getFirstNode(taskName);
           	GenericComponent geC = n.getComponent(taskName);
           	if (geC instanceof Task) {
              	((Task)geC).dirty=b;
                 //System.out.println(" This rthe task name: "+ geC.getName());
             }
         }   
    }
    
   public static void openHTMLView() {
        fileManager.openHTMLView();
   }

    
   public static void listenHelp() {
        fileManager.listenHelp();
   }

   public static void openHelpContents() {
        fileManager.openHelpContents();
   }
   
   
   	/**
	* return a reference of the XMamager xDm (domain model Xmanager)
	*/
	public static XManager getXDM(){
		return xDm;
	}//getXDM()
	
	/**
	* set the XMamager xDm (domain model Xmanager) to aX
	*/
	public static void setXDM(XManager aX){
		xDm = aX;
	}//setXDM()
	
	//Shijian
	//2001-2-12
    public static void newECon(){
    	xDm.getDmManager().newECon();
    }
    
  	//Shijian 2001-2-12
    public static void newACon(){
    	xDm.getDmManager().newACon();
    }
    
  	//Shijian 2001-2-12
    public static void newEIns(){
    	xDm.getDmManager().newEIns();
    }
    
  	//Shijian 2001-2-12
    public static void newAIns(){
    	xDm.getDmManager().newAIns();
    }
    
  	//Shijian 2001-2-12
    public static void newERels(){
    	xDm.getDmManager().newERels();
    }
    
  	//Shijian 2001-2-12
    public static void newARels(){
    	xDm.getDmManager().newARels();
    }
    
  	//Shijian 2001-2-12
    public static void editDM(){
    	xDm.getDmManager().editDM();
    }
    
  	//Shijian 2001-2-12
    public static void createDMAll(){
    	xDm.getDmManager().createDMAll();
    }
    
  	//Shijian 2001-2-12
    public static void createDMIfNil(){
    	xDm.getDmManager().createDMIfNil();
    }
    
  	//Shijian 2001-2-12
    public static void markDirty(){
    	xDm.getDmManager().markDirty();
    }
    
  	//Shijian 2001-2-12
    public static void markClean(){
    	xDm.getDmManager().markClean();
    }
    
  	//Shijian 2001-2-12
    public static void clearDMAll(){
    	xDm.getDmManager().clearDMAll();
    }
    
	//shijian 2001-2-13
  public static Collection getAllTask(){
  	SortArrayList sv = new SortArrayList (new GCCompare());
  	
    Set compSet=new TreeSet();
  	Set set=Manager.skeleton.nodeRegister.keySet();
  	GenericComponent gc;
  	String name;
  	for (Iterator i=set.iterator();i.hasNext();){
          String pName= (String) i.next();
  	    gc=Manager.skeleton.stringToFirstGenericComponent(pName);   
  	    name=gc.getName();
          
   	    if (!compSet.contains(name)){
  	    	compSet.add(name);
   	    	if ( gc instanceof Task) {
				sv.add(gc);
   	    	}
  	    }
  	}
  	
	sv.sort(); 
	return Collections.unmodifiableCollection(sv);
  	
  }
	
  //shijian 2001-3-28
  public static Collection getAllLink(){
  	ArrayList sv = new ArrayList ();
  	
    Set compSet=new TreeSet();
  	Set set=Manager.skeleton.nodeRegister.keySet();
  	GenericComponent gc;
  	String name;
  	for (Iterator i=set.iterator();i.hasNext();){
          String pName= (String) i.next();
  	    gc=Manager.skeleton.stringToFirstGenericComponent(pName);   
  	    name=gc.getName();
          
   	    if (!compSet.contains(name)){
  	    	compSet.add(name);
   	    	if ( gc instanceof Link) {
				sv.add(gc);
   	    	}
  	    }
  	}
  	
	return Collections.unmodifiableCollection(sv);
  	
  }
  
  //shijian 2001-3-28
  public static Collection getAllBoolConnector(){
  	ArrayList sv = new ArrayList ();
  	
    Set compSet=new TreeSet();
  	Set set=Manager.skeleton.nodeRegister.keySet();
  	GenericComponent gc;
  	String name;
  	for (Iterator i=set.iterator();i.hasNext();){
          String pName= (String) i.next();
  	    gc=Manager.skeleton.stringToFirstGenericComponent(pName);   
  	    name=gc.getName();
          
   	    if (!compSet.contains(name)){
  	    	compSet.add(name);
   	    	if ( gc instanceof BooleanConnector) {
				sv.add(gc);
   	    	}
  	    }
  	}
  	
	return Collections.unmodifiableCollection(sv);
  	
  }
  
  	//Shijian 2001-2-20
    // remove semantics (set semantics to nil "")
    // ta is a collection of tasks
    public static void removeSemantics(Collection ta){
    	
		Iterator it = ta.iterator();
		Task t;
		while (it.hasNext()) {
			t= (Task)it.next();
			t.setSemantics("");	
		}
    }
    
  	//Shijian 2001-3-28
    // remove Action Instance refereneces for 
    // semantics, precondition, and feedback 
    // ta is a collection of tasks
    public static void removeTaskDomain(Collection ta){
    	
		Iterator it = ta.iterator();
		Task t;
		while (it.hasNext()) {
			t= (Task)it.next();
			t.setSemantics("");	
			t.setPreconDM("");	
			t.setFeedbackDM("");	
		}
    }
    
  	//Shijian 2001-3-28
    // remove Action Instance refereneces for 
    // link precondition  
    // ls is a collection of links
    public static void removeLinkDomain(Collection ls){
    	
		Iterator it = ls.iterator();
		Link l;
		while (it.hasNext()) {
			l= (Link)it.next();
			l.setPreconDM("");	
		}
    }
    
  	//Shijian 2001-3-28
    public static void inherentParentActor(Task t, Task parent){
    	String actor = parent.getActor();
    	if (actor != null && actor != ""){
    		t.setActor(actor);
    	}
    	
    	return;
    }
    
  	//Shijian 2001-4-17
    public static void findPredecessorComponents(LinkableComponent lc){
    	
    	//first find linked components
    	findLinkedComponents(lc);
    	
    	//now find all parents
    	String name = lc.getName();
    	Set se = skeleton.getAllParents(name);
    	if (se == null) return;
    	
    	Iterator it = se.iterator();
    	
    	GenericComponent gcTemp;
    	String parentName;
    	while (it.hasNext()){
    		parentName = (String) it.next();
    		//System.out.println("(parent name): " + parentName);
    		if (!skeleton.isRoot(parentName)){
	
				GenericComponent [] gcs = skeleton.getComponents(parentName);
				int size = gcs.length;
	
	    		if (size >0){
					for (int i=0;i<size;i++) {
						gcTemp = gcs[i];
	   	    			addPredecessor(gcTemp);	   	    			
	   	    			//find parent's parent
	   	    			findPredecessorComponents((LinkableComponent)gcTemp);
					}
		        	
		        }
    		}
    	}
    	return;
    }
    
  	//Shijian 2001-4-17
    private static void findLinkedComponents(LinkableComponent lc){
    	Vector links = lc.getLinks();
    	int size = links.size();
    	Link l;
    	LinkableComponent lc1;
        for (int i=size-1;i>=0;i--) {
    	    l=(Link)links.elementAt(i);
    	    if ((l.getSecondLC()).equals(lc)){
     	    	lc1=l.getFirstLC();
     	    	
   	    		addPredecessor(l);
   	    		if (! isPredecessor(lc1)){ // stop after one loop if it is circular
	     	    	addPredecessor(lc1);
	    			//System.out.println("predecessor:(linked) " + lc1.getName());
	     	    	findLinkedComponents(lc1);
   	    		}
   	    	}	
        }
    	return;
    }
    
  	//Shijian 2001-4-17
    public static void resetPredecessorStore(){
    	_predecessorComponents.clear();
    	return;
    }
    
  	//Shijian 2001-4-17
    public static Collection getAllPredecessors(){
		_predecessorComponents.sort(); 
		return Collections.unmodifiableCollection(_predecessorComponents);
    }
    
  	//Shijian 2001-4-17
    public static void addPredecessor(GenericComponent gc){
		_predecessorComponents.add(gc); 
		return;
    }
  	//Shijian 2001-4-17
    public static void printPredecessors(){
    	Collection col = getAllPredecessors();
    	Iterator it = col.iterator();
    	GenericComponent gc;
    	while (it.hasNext()){
    		gc = (GenericComponent) it.next();
    		System.out.println("predecessor: " + gc.getName());
    	}
		return;
    }
    
  	//Shijian 2001-4-18
    public static boolean isPredecessor(GenericComponent gc){
    	
    	return _predecessorComponents.contains(gc);
    }
    
  	//Shijian 2001-4-18
    public static void resetSuccessorStore(){
    	_successorComponents.clear();
    	return;
    }
    
  	//Shijian 2001-4-18
    public static boolean isSuccessor(GenericComponent gc){
    	
    	return _successorComponents.contains(gc);
    }
    
  	//Shijian 2001-4-18
    public static void addSuccessor(GenericComponent gc){
		_successorComponents.add(gc); 
		return;
    }
  	//Shijian 2001-4-18
    public static void printSuccessors(){
    	Collection col = getAllSuccessors();
    	Iterator it = col.iterator();
    	GenericComponent gc;
    	while (it.hasNext()){
    		gc = (GenericComponent) it.next();
    		System.out.println("Successor: " + gc.getName());
    	}
		return;
    }
    
  	//Shijian 2001-4-18
    public static Collection getAllSuccessors(){
		return Collections.unmodifiableCollection(_successorComponents);
    }
    	
  	//Shijian 2001-4-18
    private static void findChildrenComponents(LinkableComponent lc){
    	
    	//findSiblingComponents(lc);
    	
    	Node nodeParent = skeleton.getFirstNode(lc.getName());
    	Couple c=nodeParent.getCouple(lc.getName());
    	Node node = c.node;
    	
    	if (node == null) return;
    	
    	Set keys=node.keySet();
    	LinkableComponent lc1;
    	String childName;
   	
    	if (keys.size() <= 0) return;
    	
    	for (Iterator it=keys.iterator();it.hasNext();){
            childName=(String)it.next();
    	    c=node.getCouple(childName);
    	    
   	    	if (c.object instanceof LinkableComponent){
    	    	lc1=(LinkableComponent)c.object;
    	    	if (isFirstComponent(lc1)){
	   	    		if (! isSuccessor(lc1)){ 
		     	    	addSuccessor(lc1);
	 	    			findSuccessorComponents(lc1);
	   	    		}
    	    	}
   	    	}
   	    	
    	}
    	return;
    }
    
  	//Shijian 2001-4-18
    public static void findSuccessorComponents(LinkableComponent lc){
    	findChildrenComponents(lc);

    	Vector links = lc.getLinks();
    	int size = links.size();
    	Link l;
    	LinkableComponent lc2;
        for (int i=size-1;i>=0;i--) {
    	    l=(Link)links.elementAt(i);
    	    if ((l.getFirstLC()).equals(lc)){
     	    	lc2=l.getSecondLC();
     	    	
   	    		addSuccessor(l);
   	    		if (! isSuccessor(lc2)){ // stop after one loop if it is circular
	     	    	addSuccessor(lc2);
	    			//System.out.println("child:(linked) " + lc2.getName());
	     	    	findSuccessorComponents(lc2);
	     	    	findChildrenComponents(lc2);
   	    		}
   	    	}	
        }
    	return;
    }
    
    public static boolean isFirstComponent(LinkableComponent lc){
    	boolean result=true;
    	int nb=lc.linkList.size();
    	Link l;
    	for (int i=0;i<nb;i++){
    	    l=(Link)lc.linkList.elementAt(i);
    	    if (l.lc2==lc) {
    	    	result=false;
    	    	break;
    	    }
    	}
    	return result;
    }
    		
    
  	//Shijian 2001-4-20
    public static void findPrecComLink(Link l){
    	LinkableComponent lc=l.getFirstLC();
		if (! isPredecessor(lc)){ 
	    	addPredecessor(lc);
	    	findPredecessorComponents(lc);
		}
    }
    
  	//Shijian 2001-4-20
    public static void findPrecComs(GenericComponent gc){
    	
    	if (gc instanceof LinkableComponent){
    		LinkableComponent lc=(LinkableComponent)gc;
    		findPredecessorComponents(lc);
    	}else if (gc instanceof Link){
    		Link l = (Link) gc;
    		findPrecComLink(l);
    	}
    	
    	return;
    }
    
  	//Shijian 2001-4-20
    public static void findSuccComs(GenericComponent gc){
    	
    	if (gc instanceof LinkableComponent){
    		LinkableComponent lc=(LinkableComponent)gc;
    		findSuccessorComponents(lc);
    	}else if (gc instanceof Link){
    		Link l = (Link) gc;
    		findSuccComLink(l);
    	}
    	
    	return;
    }
    
  	//Shijian 2001-4-20
    public static void findSuccComLink(Link l){
    	LinkableComponent lc=l.getSecondLC();
		if (! isSuccessor(lc)) { 
	    	addSuccessor(lc);
	    	findSuccessorComponents(lc);
		}
    }
    
  	//Shijian 2001-4-20
    // return true, if any of the component in col is either 
    //a predecessor, successor of gc, or gc itself
    public static boolean isRelated(GenericComponent gc, Collection col){
    	
    	if (gc == null) return false;
    	
		//find predecessors
    	resetPredecessorStore();
		findPrecComs(gc);
	//	printPredecessors();
		
		//find successors
		resetSuccessorStore();
		findSuccComs(gc);
	//	printSuccessors();
		
		GenericComponent gc1;
		Iterator it = col.iterator();
		while (it.hasNext()) {
			gc1= (GenericComponent)it.next();
			if ( isPredecessor(gc1) || isSuccessor(gc1) ||
				gc.equals(gc1))
				return true;	
		}
		
		return false;

    }
    
    //shijian 2001-7-16
    public static void computeOrderedComs(ArrayList orderedSet){
    	computeOrderedComs(skeleton.root, orderedSet);
    	return;
    }
    
    private static void computeOrderedComs(Node node,ArrayList orderedSet){
    	Set keys=node.keySet();
    	Couple c;
    	LinkableComponent lc;
    	String childName;
    	LinkedList list=new LinkedList();
    	int nb=0;
   	
   	//1. add starting components from the node
    	boolean first;
    	for (Iterator it=keys.iterator();it.hasNext();){
            childName=(String)it.next();
    	    c=node.getCouple(childName);
   	    	if (c.object instanceof LinkableComponent){
    	    	lc=(LinkableComponent)c.object;
    	    	first=isFirstComponent(lc);
    	    	if (first)
    	    		orderedSet.add(lc);
    	    		
                //only for a CompositeComponent
    	    	if (!c.node.isEmpty()){
    	    	    list.add(c.node);
    	    	    //list.add(childName);
    	    	    nb++;
    	    	}
    	    }
    	}
    	
    //2 add the remaining components
    	for (Iterator it=keys.iterator();it.hasNext();){
            childName=(String)it.next();
            c=node.getCouple(childName);
           	if (c.object instanceof LinkableComponent){
    	    	lc=(LinkableComponent)c.object;

	     	    if (!orderedSet.contains(lc))
	   	    		orderedSet.add(lc);
           	}
    	}
    	
    //3. one level down the tree 
    	Node n;
    	for (int i=0;i<nb;i++){
    	    n=(Node)list.removeFirst();    	    
    	  //childName=(String)list.removeFirst();
    	    //c=n.getCouple(childName);
    	  //if (!orderedSet.contains(childName)){
    	    	//orderedSet.add(c.object);
    	    	computeOrderedComs(n,orderedSet);
    	  //}
    	}
      
    }
    
    public static void openTVFrame(String name, String htmlPathName) {
        // This should be smarter about existing TV frames...
        createTVFrame(name,htmlPathName);
    }
    
    private static void createTVFrame(String name, String htmlPathName) {
        if (htmlPathName!=null) {
            //TVInternalFrame frame = new TVInternalFrame(name,htmlPathName);
            TVFrame frame = new TVFrame(name,htmlPathName);
            frame.setVisible(true);   // due to incompatibility of Java JDK V.1.3 and V.1.2.2
        }
        else {
            System.out.println("Can't open the HTML file: " + htmlPathName);
        }
    }
 	
    //20-11-2001
    public static KernelTree getSkeleton(){
    	return skeleton;
    }
    
    //20-02-2002
    public static SystemOptions getSysOption(){
    	return systemOptions;
    }
    	
}
