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

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

//Source file: C:/Data/Isolde/Tamot2/Current/domainModel/DmRelation.java

package domainModel;

import java.util.Vector;

/**
 * This class implements the Singleton pattern 
 * so that only one DmRelation object can be created.
 * Relations created on the fly is instently visible.
 * It manages relations. 
 */
 public class DmRelation extends Object{
	private final static String predefinedEntityRelations[] 
		= {"part of"};		
	private final static String predefinedActionRelations[] 
		= {"actor",
			"actee",
			"source",
			"destination",
			"instrument"
			//,"rest"
		};	
		
	//26-6-2002, add process as a special action relation
	// to instore non-imparative verb-forms
	public final static String ACTION_PROCESS = "process";
	
	//14-11-2001
	private final static String predefinedActActRelations[] 
		= {"purpose request"};		

	private static Vector entityRelations;
	private static Vector actionRelations;
	private static Vector actionActRelations;

	private static DmRelation dRInstance
      = new DmRelation();
      
      //static initialisation
   static {
    	//initialise entity-relation collection with predefined 
    	entityRelations = new Vector(5);	
    	for (int i = 0; i < predefinedEntityRelations.length; i++) {	
    		entityRelations.add(predefinedEntityRelations[i]);				
       	}    
       	
       	//initialise action-relation collection with predefined 
    	actionRelations = new Vector(5);	
    	for ( int i = 0; i < predefinedActionRelations.length; i++) {	
    		actionRelations.add(predefinedActionRelations[i]);				
       	}    
       	
       	//initialise action-act-relation collection with predefined 
    	actionActRelations = new Vector(5);	
    	for ( int i = 0; i < predefinedActActRelations.length; i++) {	
    		actionActRelations.add(predefinedActActRelations[i]);				
       	}    
   	
   }

    /**
     * This private constructor is defined so the compiler won't
     * generate a default public constructor.
     */
    private DmRelation() { 
    }	
    
    /**
     * Return a reference to the only instance of this class.
     */
    public static DmRelation getInstance() {
        return dRInstance;
    } // getInstance()
    
    /**
     * This private method preprocess a input type for 
     * comparison or add-in to the collection. it makes sure that
     * 	(1) type is in lower-case, and
     *	(2) leading or tailing spaces are trimmed off
     * @param rel, the string to be processed
     */
    private String getWellFormedRelation(String rel){
    	return (rel.toLowerCase()).trim();
    } //getWellFormedRelation
    
    /**
     * Check if the given string is a defined entityRelation 
     * @param type, the string to be checked
     */
    public boolean isEntityRelation(String rel) {
        if (entityRelations.contains(getWellFormedRelation(rel) )){
        	return true;
        }else return false;
    } // isEntityRelation()
    
    /**
     * Check if the given string is a defined actionRelation 
     * @param type, the string to be checked
     */
    public boolean isActionRelation(String rel) {
        if (actionRelations.contains(getWellFormedRelation(rel) )){
        	return true;
        }else return false;
    } // isActionRelation()

    /**
     * Check if the given string is a defined a (entity/action) Relation 
     * @param type, the string to be checked
     */
    public boolean isRelation(String rel) {
        if (actionRelations.contains(getWellFormedRelation(rel) )
        	|| entityRelations.contains(getWellFormedRelation(rel) )){
        	return true;
        }else return false;
    } // isRelation()

    /**
     * Add a relation to the entity-relations collection
     * 
     * @param rel, the new entity-relation to add.
     */
    public void addEntityRelation(String rel) {
    	String temp = getWellFormedRelation(rel);
    	if (!(isEntityRelation(temp))) 
    		entityRelations.add(temp);
    } // addEntityRelation(String rel)    
    
    /**
     * Add a relation to the action-relations collection
     * 
     * @param rel, the new entity-relation to add.
     */
    public void addActionRelation(String rel) {
    	String temp = getWellFormedRelation(rel);
    	if (!(isActionRelation(temp))) 
    		actionRelations.add(temp);
    } // addActionRelation(String rel)    

    /**
     * Delete a relation from the entity-relations collection
     * But a predefined relation cannot be deleted
     * @param rel, the new entity-relation to deleted.
     */
    public void deleteEntityRelation(String rel) {
    	boolean isPredefinedRelation = false;
    	String temp = getWellFormedRelation(rel);
    	if (isEntityRelation(temp)) {
    		for(int i = 0; i<predefinedEntityRelations.length; i++){
    			if (temp.equals(predefinedEntityRelations[i])){
    				isPredefinedRelation = true;	
    				break;
    			}
    			
    		}
    		if (isPredefinedRelation){
    			taskModellingTool.TMUtility.display("Entity-relation: "+ temp + 
    			" is a predefined entity-relation, it cannot be deleted!");
    		}else entityRelations.removeElement(temp);
    		
    	} else 	{
    		taskModellingTool.TMUtility.display("Entity-relation: "+ temp + 
    			" is not in entity-relation collection!");
    	}
    } // addEntityRelation(String rel)    

    /**
     * Delete a relation from the Action-relations collection
     * But a predefined relation cannot be deleted
     * @param rel, the new action-relation to deleted.
     */
    public void deleteActionRelation(String rel) {
    	boolean isPredefinedRelation = false;
    	String temp = getWellFormedRelation(rel);
    	if (isActionRelation(temp)) {
    		for(int i = 0; i<predefinedActionRelations.length; i++){
    			if (temp.equals(predefinedActionRelations[i])){
    				isPredefinedRelation = true;	
    				break;
    			}
    			
    		}
    		if (isPredefinedRelation){
                taskModellingTool.TMUtility.display("Action-relation: "+ temp + 
                    " is a predefined action-relation, it cannot be deleted!");
    		}else actionRelations.removeElement(temp);
    		
    	} else 	{
    		taskModellingTool.TMUtility.display("Action-relation: "+ temp + 
    			" is not in entity-relation collection!");
    	}
    } // addEntityRelation(String rel)    
    
    /**
     * retrun all known entity-relations 
     */
    public String[] getAllEntityRelations() {
    	String eRelations[] = new String[entityRelations.size()];
        entityRelations.copyInto(eRelations);
        return eRelations;
    } // getAllEntityRelations()
    
    /**
     * retrun all known action-relations 
     */
    public String[] getAllActionRelations() {
    	String aRelations[] = new String[actionRelations.size()];
        actionRelations.copyInto(aRelations);
        return aRelations;
    } // getAllActionRelations()
    
    /**
     * retrun all known entity and action-relations 
     */
    public String[] getAllRelations() {
    	int eSize = entityRelations.size();
		int aSize = actionRelations.size();
    	String all[] = new String[eSize + aSize];
    	
    	String eRelations[] = getAllEntityRelations();
    	String aRelations[] = getAllActionRelations();
    	
        for (int i =0; i< eSize ; i++){
        	all[i] = eRelations[i];
        }
        for (int i =eSize; i< eSize + aSize; i++){
        	all[i] = aRelations[i-eSize];
        }
        return all;
        
    } // getAllRelations()
        
    
    /**
     * retrun number of all known entity relations 
     */
    public int getEntityRelationCount() {
    	return entityRelations.size();
    } // getEntityRelationCount()
    
    /**
     * retrun number of all known entity and action relations 
     */
    public int getActionRelationCount() {
    	return actionRelations.size();
    } // getActionRelationCount()
    
    /**
     * retrun number of all known entity and action relations 
     */
    public int getAllRelationCount() {
    	return getActionRelationCount() + getEntityRelationCount();
    } // getRelationCount()

    /**
     * get a valid EntityRelation from the collection. 
     * 
     * @param rel, it may be not-well-formed. 
	 * @return String, well-formed EntityRelation
     */
    public String getEntityRelation(String rel) {
    	String temp = getWellFormedRelation(rel);
    	if (isEntityRelation(temp)) 
    		return temp;
    	else return null;
    } // getEntityRelation(String rel)

    /**
     * get a valid ActionRelation from the collection. 
     * 
     * @param rel, it may be not-well-formed. 
	 * @return String, well-formed ActionRelation
     */
    public String getActionRelation(String rel) {
    	String temp = getWellFormedRelation(rel);
    	if (isActionRelation(temp)) 
    		return temp;
    	else return null;
    } // getActionRelation(String rel)

    	/**
	 * getPartOf returns the string used to reprent
	 * "partOf" relation
	* 
	*/
	public static String getPartOf() {
		return predefinedEntityRelations[0];
	}

    	/**
	 * getActor returns the string used to reprent
	 * "actor" relation
	* 
	*/
	public static String getActor() {
		return predefinedActionRelations[0];
	}
	
    	/**
	 * getActee returns the string used to reprent
	 * "actee" relation
	* 
	*/
	public static String getActee() {
		return predefinedActionRelations[1];
	}
	
    	/**
	 * getSoure returns the string used to reprent
	 * "source" relation
	* 
	*/
	public static String getSource() {
		return predefinedActionRelations[2];
	}

	
    	/**
	 * getDestination returns the string used to reprent
	 * "Destination" relation
	* 
	*/
	public static String getDestination() {
		return predefinedActionRelations[3];
	}
	
    	/**
	 * getInstrument returns the string used to reprent
	 * "Instrument" relation
	*/
	
	public static String getInstrument() {
		return predefinedActionRelations[4];
	}
	
	
    	/**
	 * getInstrument returns the string used to reprent
	 * "Instrument" relation
	*/
	
	public static String getRest() {
		return null;
		//predefinedActionRelations[5];
	}
    
	//14-11-2001
    /**
     * Check if the given string is a defined actionActRelation 
     * @param type, the string to be checked
     */
    public boolean isActionActRelation(String rel) {
        if (actionActRelations.contains(getWellFormedRelation(rel) )){
        	return true;
        }else return false;
    } // isActionRelation()

    /**
     * Add a relation to the action-act-relations collection
     * @param rel, the new entity-relation to add.
     */
    public void addActionActRelation(String rel) {
    	String temp = getWellFormedRelation(rel);
    	if (!(isActionActRelation(temp))) 
    		actionActRelations.add(temp);
    } // addActionActRelation(String rel)    
    
    /**
     * retrun all known action-relations 
     */
    public String[] getAllActionActRelations() {
    	String aRelations[] = new String[actionActRelations.size()];
        actionActRelations.copyInto(aRelations);
        return aRelations;
    } // getAllActionRelations()

    /**
     * get a valid ActionActRelation from the collection. 
     * 
     * @param rel, it may be not-well-formed. 
	 * @return String, well-formed ActionRelation
     */
    public String getActionActRelation(String rel) {
    	String temp = getWellFormedRelation(rel);
    	if (isActionActRelation(temp)) 
    		return temp;
    	else return null;
    } // getActionRelation(String rel)

    	/**
	 * getActor returns the string used to reprent
	 * "actor" relation
	* 
	*/
	public static String getPurposeRequest() {
		return predefinedActActRelations[0];
	}
	
/**
	 * @return void
	* test the class.
	*
	* 
	*/
	public static void main(String args[]) {
    	
		DmRelation R1 = DmRelation.getInstance();		
		System.out.println("nO of relations: " + R1.getAllRelationCount());
		System.out.println("nO of entity relations: " + R1.getEntityRelationCount());
		System.out.println("nO of action relations: " + R1.getActionRelationCount());

		R1.addEntityRelation("new entityR");
		R1.addActionRelation("new ActionR");
		String ty="Part of";
		R1.addEntityRelation(ty);
		

		String eRelations[] = R1.getAllEntityRelations();
//		System.out.println("No of Relation: " + R2types.length);
		for (int i = 0; i < eRelations.length; i++) {
    		System.out.println(i+"Relation: " + eRelations[i]);				
       	}  
        System.out.println("nO of relations: " + R1.getAllRelationCount());

       	R1.deleteEntityRelation("new entityR");
       	R1.deleteEntityRelation(ty);
       	System.out.println("nO of relations: " + R1.getAllRelationCount());

       	R1.deleteActionRelation("actoR");

 
       	System.out.println();

       	DmRelation R2 = DmRelation.getInstance();
		String R2types[] = R2.getAllRelations();
		System.out.println("No of Relation: " + R2types.length);

		for (int i = 0; i < R2types.length; i++) {
    		System.out.println("R2 relation: " + R2types[i]);				
       	}    
				
    } //main()
} //class: DmRelation