/*
   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 javax.swing.*;
import java.util.*;
import javax.swing.tree.*;


public class NewManager {

  /**
   * Create a new {@link Task}
   * and automaticly position this component in the selected frame.
   * <A HREF="../source/Manager.html#newTask">Source</A>
   */
  //tape_recorder
  public static Task newTask(int posx,int posy) {
    //TMUtility.display("newTask","");
        
    Task result = createNewTask(posx,posy);

    EditManager.edit(true);
        
    if (EditManager.abort) {
      //TMUtility.display("newTask","aborted");
            
      // delete the new task created
      DeleteManager.deleteGenericComponent(result);
            
      result = null;
    }
        
    return result;
  }
    
  public static Task newTask() {
    return newTask(-1,-1);
  }

  public static Task newTaskWithoutDuplicatedName() {
    Task result = createNewTask(-1,-1);

    EditManager.edit(false);
        
    if (EditManager.abort) {
      TMUtility.display("newTaskWithoutDuplicatedName","aborted");
            
      // delete the new task created
      DeleteManager.deleteGenericComponent(result);
            
      result = null;
    }
        
    return result;
  }
    
  private static Task createNewTask(int posx,int posy) {
    String DEFAULTTASKNAME = "do something";
        
    Task gc = null;
    boolean auto = (posx<0)||(posy<0);
    TreePath treePath = Manager.tree.getSelectionPath();
        
    if (treePath != null) {
      String name = Manager.treePathToString(treePath);
      String parentName;
      Task parentTask = null;        //shijian 2001-3-28
            
      boolean ok = (name.equals(Manager.ROOT_STRING));
      if (!ok) {
	parentName = Manager.treePathToString(Manager.truncTreePath(treePath));
	GenericComponent pa = Manager.skeleton.stringToGenericComponent(name,parentName);
	if (pa instanceof Task){    //CompositeComponent){
	  ok = true ;
	  parentTask = (Task) pa;
	} else {
	  ok = false ;
	  parentTask = null;
	}
      }
      else
	parentName = Manager.skeleton.ROOT_STRING;/*_PARENT*/
            
      if (ok) {
	if (auto) gc = new Task(DEFAULTTASKNAME);
	else gc = new Task(DEFAULTTASKNAME,posx,posy);
                
	gc.setID();
                
	String childName = gc.getName();
	Integer childID = new Integer(gc.ID);
                
	Node currentNode;
	Integer currentID = null;
                
	if (Manager.currentComponent != null) {
	  currentID = new Integer(Manager.currentComponent.ID);
	}

	// Adds in a branch
	if ((currentID != null) && (Manager.skeleton.hasChildNode(name,currentID))) {
	  currentNode = Manager.skeleton.toChildNode(name,currentID);
                    
	  currentNode.add(gc);
	  // JOptionPane.showMessageDialog(MainFrame.mainFrame,"add brach");
	}
	else if (Manager.skeleton.hasChildNode(name)) {
	  currentNode = Manager.skeleton.toChildNode(name);
	  currentID = Manager.skeleton.toChildNodeID(name);
                    
	  currentNode.add(gc);
	}
	// Adds in a leaf
	else {
	  Node parentNode = Manager.skeleton.toParentNode(name,parentName);
                    
	  currentNode = parentNode.getChild(name);
	  currentID = parentNode.getChildID(name);
                    
	  currentNode.add(gc);
	  // JOptionPane.showMessageDialog(MainFrame.mainFrame,"add leaf");
	}
	Manager.skeleton.addInRegister(childName,childID,name,currentNode);

	// String mesg =   "treePathToString: "+ s+ "  Parent Name: " +  parentS+ "task name : " +newCompName;
	// JOptionPane.showMessageDialog(MainFrame.mainFrame,mesg);

	Manager.RTFDB.add(childName);
    //Shijian 25-9-2001
    Manager.RTFDBM.add(childName);
    
	int childIndex = Manager.skeleton.getTreeIndex(childName,name,childID);
	Manager.tree.addInTree(treePath,childName,childIndex);

	Manager.tree.synchronizeTreeStructure(treePath);
                
	Manager.updateChildFrame(treePath);

	if (!Manager.isRoot(treePath)) {
	  ((Task) Manager.skeleton.toParentNode(name,parentName).getComponent(name)).setComposite(true);
	  Manager.updateParentFrame(treePath);
                
	  //synchronize everything of the same duplicated tasks
	  EditManager.restoreChildrenCoherence(name,parentName,currentID,false);
	  EditManager.synchronizeCoreFields(name,parentName,currentID);
	}
        
	if (Manager.guiEnableFlag) {
	  // automaticly find a position for the GenericComponent
	  Manager.attributesPanel.displayAttributes(Manager.currentComponent);
	}
                
	if (auto) Manager.autoPlace(gc,currentNode);
                
	//mark parent task as dirty TRUE if it is not the root
	Manager.markTaskDirty(name,true); 
      }
      Manager.tree.expandRow(0);
            
      //shijian 2001-3-28
      if (parentTask != null)
	Manager.inherentParentActor(gc, parentTask);
            
    }
        
    //shijian 2001-3-12
    Manager.select(gc,treePath,new Integer(1));  
        
    Manager.menu.setOptions(gc);
        
    FileManager.MODIFIED = true;    
        
    return gc;
  }
    
  //tape_recorder
  public static Task newTask(String taskName,String semantics) {
    Manager.tree.setSelectionRow(0);                    // point to the root

    Task task = newTask(-1,-1,taskName);
    task.semantics = semantics;
        
    return task;
  }

  //tape_recorder
  public static Task newTask(String parentName,String taskName,String semantics) {
    TreePath treePath = Manager.fetchTreePath(parentName,Manager.tree);
    Manager.tree.setSelectionPath(treePath);

    Task task = newTask(-1,-1,taskName);
    task.setSemantics(semantics);
        
    return task;
  }

  //tape_recorder
  public static Task newTask(int posx,int posy,String taskName) {
    String DEFAULTTASKNAME = taskName;
        
    Task gc = null;
    boolean auto = (posx<0)||(posy<0);
    TreePath treePath = Manager.tree.getSelectionPath();
        
    if (treePath != null) {
      String name = Manager.treePathToString(treePath);
      String parentName;
            
      //System.out.println("newTask : name = "+name+", taskName = "+taskName);
            
      boolean ok = (name.equals(Manager.ROOT_STRING));
      if (!ok) {
	parentName = Manager.treePathToString(Manager.truncTreePath(treePath));
	ok = (Manager.skeleton.stringToGenericComponent(name,parentName) instanceof CompositeComponent);
      }
      else
	parentName = Manager.skeleton.ROOT_STRING;/*_PARENT*/
            
      if (ok) {
	if (auto) gc = new Task(DEFAULTTASKNAME);
	else gc = new Task(DEFAULTTASKNAME,posx,posy);
                
	gc.setID();
                
	String childName = gc.getName();
	Integer childID = new Integer(gc.ID);
                
	Node currentNode;
	Integer currentID;

	// Adds in a branch
	if (Manager.skeleton.hasChildNode(name)) {
	  currentNode = Manager.skeleton.toChildNode(name);
	  currentID = Manager.skeleton.toChildNodeID(name);
                    
	  currentNode.add(gc);
	  // JOptionPane.showMessageDialog(MainFrame.mainFrame,"add brach");
	}
	// Adds in a leaf
	else {
	  Node parentNode = Manager.skeleton.toParentNode(name,parentName);
                    
	  currentNode = parentNode.getChild(name);
	  currentID = parentNode.getChildID(name);
                    
	  currentNode.add(gc);
	  //  JOptionPane.showMessageDialog(MainFrame.mainFrame,"add leaf");
	}
	Manager.skeleton.addInRegister(childName,childID,name,currentNode);

	// String mesg =   "treePathToString: "+ s+ "  Parent Name: " +  parentS+ "task name : " +newCompName;
	//JOptionPane.showMessageDialog(MainFrame.mainFrame,mesg);

	Manager.RTFDB.add(childName);
    //Shijian 25-9-2001
    Manager.RTFDBM.add(childName);
                
                
	int childIndex = Manager.skeleton.getTreeIndex(childName,name,childID);
	Manager.tree.addInTree(treePath,childName,childIndex);

	Manager.tree.synchronizeTreeStructure(treePath);
                
	Manager.updateChildFrame(treePath);

	if (!Manager.isRoot(treePath)) {
	  ((Task) Manager.skeleton.toParentNode(name,parentName).getComponent(name)).setComposite(true);
	  Manager.updateParentFrame(treePath);
                
	  //synchronize everything of the same duplicated tasks
	  EditManager.restoreChildrenCoherence(name,parentName,currentID,false);
	  EditManager.synchronizeCoreFields(name,parentName,currentID);
	}
        
	if (Manager.guiEnableFlag) {
	  // automaticly find a position for the GenericComponent
	  Manager.attributesPanel.displayAttributes(Manager.currentComponent);
	}
                
	if (auto) Manager.autoPlace(gc,currentNode);
                
	//mark parent task as dirty TRUE if it is not the root
	Manager.markTaskDirty(name,true); 
      }
      Manager.tree.expandRow(0);
    }
        
    FileManager.MODIFIED = true;    
        
    return gc;
  }
    
  /**
   * Create a new {@link BooleanConnector}
   * and automaticly position this component in the selected frame.
   * <A HREF="../source/Manager.html#newBooleanConnector">Source</A>
   */
  //tape_recorder
  public static BooleanConnector newBooleanConnector(String type,int posx,int posy) {
    BooleanConnector gc = null;
    boolean auto = (posx<0)||(posy<0);
    TreePath treePath = Manager.tree.getSelectionPath();
        
    if (treePath!=null) {
      String name = Manager.treePathToString(treePath);
      String parentName;
            
      boolean ok = (name.equals(Manager.ROOT_STRING));
      if (!ok) {
	parentName = Manager.treePathToString(Manager.truncTreePath(treePath));
	ok = (Manager.skeleton.stringToGenericComponent(name,parentName) instanceof CompositeComponent);
      }
      else
	parentName = Manager.skeleton.ROOT_STRING;/*_PARENT*/
                
      if (ok) {
	//gc=new BooleanConnector(type);
	if (auto) gc = new BooleanConnector(type);
	else gc = new BooleanConnector(type,posx,posy);
                
	gc.setID();
                
	String childName = gc.getName();
	Integer childID = new Integer(gc.ID);
                
	Node currentNode;
	Integer currentID;
                
	// Adds in a branch
	if (Manager.skeleton.hasChildNode(name)){
	  currentNode = Manager.skeleton.toChildNode(name);
	  currentID = Manager.skeleton.toChildNodeID(name);
                    
	  currentNode.add(gc);
	}
	// Adds in a leaf
	else {
	  Node parentNode = Manager.skeleton.toParentNode(name,parentName);
                    
	  currentNode = parentNode.getChild(name);
	  currentID = parentNode.getChildID(name);
                    
	  currentNode.add(gc);
	}   
	Manager.skeleton.addInRegister(childName,childID,name,currentNode);
                
	Manager.RTFDB.add(childName);
    //Shijian 25-9-2001
    Manager.RTFDBM.add(childName);
                
	int childIndex = Manager.skeleton.getTreeIndex(childName,name,childID);
	Manager.tree.addInTree(treePath,childName,childIndex);
                
	Manager.updateChildFrame(treePath);

	if (!Manager.isRoot(treePath)) {
	  ((Task) Manager.skeleton.toParentNode(name,parentName).getComponent(name)).setComposite(true);
	  Manager.updateParentFrame(treePath);
                   
	  EditManager.restoreChildrenCoherence(name,parentName,currentID,false);
	}
        
	// automaticly find a position for the GenericComponent
	if (auto) Manager.autoPlace(gc,currentNode);
                
	if (Manager.guiEnableFlag) {
	  Manager.attributesPanel.displayAttributes(Manager.currentComponent);
	}
                
	//mark parent task as dirty TRUE if it is not the root
	Manager.markTaskDirty(name,true); 
      }
            
      Manager.tree.expandRow(0);
    }
    FileManager.MODIFIED = true;
        
    return gc;        
  }
    
  public static BooleanConnector newBooleanConnector(String type) {
    return newBooleanConnector(type,-1,-1);
  }

  /**
   * Create a new {@link Link}
   * and automaticly position this component in the selected frame.
   * <A HREF="../source/Manager.html#newLink">Source</A>
   */
  ///newLink
  public static void newLink(LinkableComponent lc1,LinkableComponent lc2,String name) {
    TreePath currentTreePath = Manager.truncTreePath(Manager.fetchTreePath(lc1.getName(),
									   name,Manager.tree,new Integer(lc1.ID)));
        
    Link link = new Link(lc1,lc2,name);
                
    link.setID();
        
    String linkName = link.getName();
    Integer linkID = new Integer(link.ID);
        
    Node currentNode = Manager.skeleton.toChildNode(name);
    Integer currentID = Manager.skeleton.toChildNodeID(name);
    String parentName = Manager.skeleton.toParentName(name);

    currentNode.add(link);
    Manager.skeleton.addInRegister(linkName,linkID,name,currentNode);
        
    Manager.RTFDB.add(linkName);
    //Shijian 25-9-2001
    Manager.RTFDBM.add(linkName);
                
    int linkIndex = Manager.skeleton.getTreeIndex(linkName,name,linkID);
    Manager.tree.addInTree(currentTreePath,linkName,linkIndex);

    Manager.updateChildFrame(currentTreePath);
        
    if (!Manager.isRoot(currentTreePath)) {
      //synchronize everything of the same duplicated tasks
      EditManager.restoreChildrenCoherence(name,parentName,currentID,false);
    }
        
    //mark parent task as dirty TRUE if it is not the root
    Manager.markTaskDirty(name,true); 

    FileManager.MODIFIED = true;         
  }
	
  //brasser 2001-6-21
  //create a new link with the currently selected node as parent
  //used by the extraction tools
  public static void newLink(String fromTaskName,String toTaskName) {
    //System.out.println("creating link from " + fromTaskName + " to " + toTaskName);
        
    TreePath treePath = Manager.tree.getSelectionPath();
    //System.out.println("treePath: " + treePath);
        
    if (treePath!=null) {
      String name = Manager.treePathToString(treePath);
      String parentName;
      Task parentTask = null;		//shijian 2001-3-28
            
      boolean ok = (name.equals(Manager.ROOT_STRING));
      if (!ok) {
	parentName = Manager.treePathToString(treePath);
	GenericComponent pa = Manager.skeleton.stringToGenericComponent(name,parentName);
	if (pa instanceof Task){	//CompositeComponent){
	  ok = true ;
	  parentTask = (Task) pa;
	} else {
	  ok = false ;
	  parentTask = null;
	}
      }
      else
	parentName = Manager.skeleton.ROOT_STRING;/*_PARENT*/
        
			
		
      //System.out.println("parent name: " + parentName);
		
      if (parentName.equals(FileManager.ROOT))
	parentName = Manager.skeleton.ROOT_STRING;
            
      GenericComponent gc1 = Manager.skeleton.getComponent(fromTaskName,parentName);
      GenericComponent gc2 = Manager.skeleton.getComponent(toTaskName,parentName);
        
      if ((gc1 instanceof LinkableComponent) && (gc2 instanceof LinkableComponent)) {
	LinkableComponent lc1 = (LinkableComponent) gc1;
	LinkableComponent lc2 = (LinkableComponent) gc2;
            
	newLink(lc1,lc2,parentName);
      }
	
    }
  }

  //brasser 2001-7-19
  //create a new link with the specified parent
  //used by the extraction tools
  public static void newLink(String parentTaskName, String fromTaskName,String toTaskName) {
    //System.out.println("creating link from " + fromTaskName + " to " + toTaskName);
        
    TreePath treePath = Manager.fetchTreePath(parentTaskName,Manager.tree);
    //System.out.println("treePath: " + treePath);
        
    if (treePath!=null) {
      String name = Manager.treePathToString(treePath);
      String parentName;
      Task parentTask = null;		//shijian 2001-3-28
            
      boolean ok = (name.equals(Manager.ROOT_STRING));
      if (!ok) {
	parentName = Manager.treePathToString(treePath);
	GenericComponent pa = Manager.skeleton.stringToGenericComponent(name,parentName);
	if (pa instanceof Task){	//CompositeComponent){
	  ok = true ;
	  parentTask = (Task) pa;
	} else {
	  ok = false ;
	  parentTask = null;
	}
      }
      else
	parentName = Manager.skeleton.ROOT_STRING;/*_PARENT*/
        
			
		
      //System.out.println("parent name: " + parentName);
		
      if (parentName.equals(FileManager.ROOT))
	parentName = Manager.skeleton.ROOT_STRING;
            
      GenericComponent gc1 = Manager.skeleton.getComponent(fromTaskName,parentName);
      GenericComponent gc2 = Manager.skeleton.getComponent(toTaskName,parentName);
        
      if ((gc1 instanceof LinkableComponent) && (gc2 instanceof LinkableComponent)) {
	LinkableComponent lc1 = (LinkableComponent) gc1;
	LinkableComponent lc2 = (LinkableComponent) gc2;
            
	newLink(lc1,lc2,parentName);
      }
	
    }
  }
	
  //brasser 2001-7-19
  //used by extraction tools. Provides a wrapper to the newTask function above.
  //lets us set the path back to its original location when done
  public static Task newTask(String parentName,String taskName,String semantics, boolean reset) {
    //System.out.println("---------------calling newTask(string,string,string,boolean)");
    TreePath originalPath = Manager.tree.getSelectionPath(); //get original path

    Task task = newTask(parentName, taskName, semantics);
        
    Manager.tree.setSelectionPath(originalPath); //reset to original path
    return task;
  }
	
  //brasser 2001-7-27
  //used by extraction tools. Provides a wrapper to the newTask function above.
  //lets us set the path back to the node just created
  public static Task newTask(int posx,int posy,String taskName, boolean set) {
    //System.out.println("---------------calling newTask(int,int,string,boolean)");
    Task task = newTask (posx, posy, taskName);
		
    Manager.tree.setSelectionPath(Manager.fetchTreePath(task.getName(),Manager.tree));
		
    return task;
  }

    
}


