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

package domainModel;

import java.util.TreeMap;

/**
 * @author 
 */
public class EntityInstance extends DmInstance 
{
	private static String defaultCardinality ="singular";
	private static final String CARDINALITIES[]= 
		{defaultCardinality, "plural", "mass_noun"};
		
	private static EntityInstance defaultUserInstance 
		= new EntityInstance("user",DmConcept.getDefaultUserConcept());
	private static EntityInstance defaultSystemInstance 
		= new EntityInstance("system",DmConcept.getDefaultSystemConcept());

	private String cardinality;
	private DmRelation entityRelation = DmRelation.getInstance();
	private TreeMap instanceRelation; 
	
	//17-10-2001
	private String _determinator;	//eg, a, the, my...
	private String _label;
	
	/* create an EntityInstance object of name: na
	* and DmConcept of DefaultEntityConcept.
	* @param na, the name of the new EntityInstance. 
	*/
	public EntityInstance(String na) 
	{
		super(na);
		initialise(DmConcept.getDefaultEntityConcept());
	}
	
	/* create an EntityInstance object of ID, ID; name: na
	* and DmConcept of DefaultEntityConcept.
	* @param iD, the ID of the new EntityInstance. 
	* @param na, the name of the new EntityInstance. 
	*/
	public EntityInstance(String iD,String na) 
	{
		super(iD,na);
		initialise(DmConcept.getDefaultEntityConcept());
	}
	
	/* create an EntityInstance object of name: na
	* and DmConcept of con.
	* @param na, the name of the new EntityInstance. 
	* @param con, the concept of the new EntityInstance. 
	*/
		public EntityInstance(String na, DmConcept con) 
	{
		super(na);
		initialise(con);
	}
		
	private void initialise(DmConcept con){
		setCardinality(defaultCardinality);
		
		super.setConceptOf(con);
		con.addInstance(this);
		
		instanceRelation= new TreeMap();
		String eRaltion[] = entityRelation.getAllEntityRelations();
		for (int i = 0; i< eRaltion.length; i++){
			instanceRelation.put(eRaltion[i], null);
		}
		
	}
	
	/**
	 * set the conceptOf to the specified Dmconcept.
	 * it first reomove the origial conceptOf,
	 * then check the type of aCOncept is of DefaultEntityType
	 * if yes, the conceptOf is changed and true is returned.
	 * if no, a message is printed and false is returned
	 * @param aConceptOf: the new value of the conceptOf property
	 */
/*	public boolean setConceptOf(DmConcept aConceptOf){
	//	removeConceptOf();
		DmConcept temp = getConceptOf();
		if (aConceptOf == null) {
			super.setConceptOf(aConceptOf);
			if (temp != null) temp.removeInstance(this);
			return true;

		}
		if (!(aConceptOf.getType().equals(ConceptType.getDefaultActionType()))){
			super.setConceptOf(aConceptOf);
			aConceptOf.addInstance(this);
			if (temp != null) temp.removeInstance(this);
			return true;
		}else{
			System.out.println("DmConcept " + aConceptOf.getName()+ " is wrong type!!");
			return false;
		}
	} //setConceptOf()
*/
	/**
	 * remove this instance from its DmConcept's
	 * instances list
	 * 
	 */
	public void removeConceptOf() {	
		/*
		if (getConceptOf() == null) return;
			
		}else {
			getConceptOf().removeInstance(this);
			setConceptOf(null);
		}
		*/
		
	}//removeConceptOf()
    
    /**
     * 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 static String getWellFormedCardinality(String cardi){
    	return (cardi.toLowerCase()).trim();
    } //getWellFormedCardinality()
    
    /**
     * Check if the given string is a defined cardinality 
     * @param type, the string to be checked
     */
    public static boolean isCardinality(String cardi) {
    	boolean is = false;
    	for (int i = 0; i<CARDINALITIES.length; i++) {
    		if (getWellFormedCardinality(cardi).equals(CARDINALITIES[i])){
    			is = true;
    			break;
    		}
    		
    	}
    	return is;

    } // isCardinality()
        
    	/**
	 * Access method for the cardinality property.
  	 *
	 * @return   the current value of the cardinality property
	 */
	public String getCardinality() {
		return cardinality;
	}
	
	/**
	 * Set the instance's cardinality to specified
	 * if the specified cardinality is not a valid
	 * cardinality, the default is assigned instead.
	 *
	 * @param aCardinality the new value of the cardinality property
	 */
	public void setCardinality(String aCardinality) {
		if (isCardinality(aCardinality)){
			cardinality = aCardinality;
		}else cardinality = defaultCardinality;
		
	} //setCardinality()
	
	/**
	* Add entity-relation object.
	* If the relation previously contained an instance, the old 
	* instance is replaced
	* @param rel,  the name of the relation 
	* @param aInstance, the instance to which the relation applies
	*/
	public boolean setEntityRelation(String rel, DmInstance aInstance) {
		String goodRel=entityRelation.getEntityRelation(rel);
		if (!(goodRel.equals(null))){
			instanceRelation.put(goodRel, aInstance);
			return true;
		} else return false;
		//may need to check , or restrict aInstance to be of class
		// EntityInstance
	}
	
	/**
	* Get all entityRelations .
	*/
	public TreeMap getEntityRelations() {
		return instanceRelation;
	}

    /**
     * retrun the default Cardinality 
     */
    public static String getDefaultCardinality() {
    	return defaultCardinality;
    } // getDefaultCardinality()

    /**
     * Set the default Cardinality 
     */
    public static void setDefaultCardinality(String aCardinality) {
		if (isCardinality(aCardinality))
			defaultCardinality = aCardinality;
		return;
    } // setDefaultCardinality()

    /**
     * retrun the default user instance 
     */
    public static EntityInstance getDefaultUserInstance() {
    	return defaultUserInstance;
    } // getDefaultUserInstance()

    /**
     * retrun the default System instance 
     */
    public static EntityInstance getDefaultSystemInstance() {
    	return defaultSystemInstance;
    } // getDefaultSystemInstance()

    /**
     * Set the default user instance 
     */
    public static void setDefaultUserInstance(EntityInstance anIn) {
		defaultUserInstance= anIn;
    } // setDefaultUserInstance()

    /**
     * Set the default system instance 
     */
    public static void setDefaultSystemInstance(EntityInstance anIn) {
		defaultSystemInstance= anIn;
    } // setDefaultSystemInstance()
    
    	/**
	 * Access method for the cardinality property.
  	 *
	 * @return  a array of different cardinality values
	 */
	public static String[] getCardinalityAll() {
		return CARDINALITIES;
	}
        
    	/**
	 * Access method for the _determinator property.
	 * @return   the current value of the _determinator property
	 */
	public String getDeterminator() {
		return _determinator;
	}
	
	/**
	 * Set the instance's _determinator to specified
	 * @param aCardinality the new value of the aDeterminator property
	 */
	public void setDeterminator(String aDeterminator) {
		if (aDeterminator != null)
			_determinator =aDeterminator;
		
	} //setDeterminator()
	
	/**
	 * Set the instance's _label to specified
	 * @param aCardinality the new value of the aLabel property
	 */
	public void setLabel(String aLabel) {
		if (aLabel != null)
			_label =aLabel;
		
	} //setLabel()
        
    	/**
	 * Access method for the Label property.
	 * @return   the current value of the Label property
	 */
	public String getLabel() {
		return _label;
	}
	/**
	 * @return void
	* test the class.
	*/
	public static void main(String args[]) {
    	
		DmConcept dc1= new DmConcept("menu");
		dc1.setType("entity type");
		DmConcept dc2= new DmConcept("menuitem");
		dc2.setType("entity type");

		EntityInstance ei1= new EntityInstance ("file");
		ei1.setConceptOf(dc1);	
		
		EntityInstance ei2= new EntityInstance ("new");
		ei2.setConceptOf(dc2);
		ei2.setEntityRelation("part of",ei1);
		
		EntityInstance ei3= new EntityInstance ("open");
		ei3.setConceptOf(dc2);
		ei3.setEntityRelation("part of",ei1);
		ei3.setCardinality("plural");

		
		EntityInstance ei4= new EntityInstance ("save");
		dc2.addInstance(ei4);
		ei4.setEntityRelation("part of",ei1);
		
		EntityInstance ei5= new EntityInstance ("somthing");
		EntityInstance ei6= new EntityInstance ("new thing");
		ei6.setConceptOf(dc1);
			
		System.out.println("DmConcept: " + DmConcept.getDefaultEntityConcept().getName()+ " of type "+ dc1.getType()+" has the following instance:");
		DmInstance dc5In[]= DmConcept.getDefaultEntityConcept().getAllInstances();
		for (int i = 0; i < dc5In.length; i++) {
    		System.out.println("     "+i+"Instance: " + dc5In[i].getName() + " " + dc5In[i].getConceptOf().getName());				
       	}  
			
			
		System.out.println("DmConcept: " + dc1.getName()+ " of type "+ dc1.getType()+" has the following instance:");
		DmInstance dc1In[]= dc1.getAllInstances();
		for (int i = 0; i < dc1In.length; i++) {
    		System.out.println("     "+i+"Instance: " + dc1In[i].getName());				
       	}  
			
		System.out.println("DmConcept: " + dc2.getName()+ " of type "+ dc2.getType()+" has the following instance:");
		DmInstance dc2In[]= dc2.getAllInstances();
		for (int i = 0; i < dc2In.length; i++) {
    		System.out.println("     "+i+"Instance: " + dc2In[i].getName()+ 
    			" " + dc2In[i].getConceptOf().getName() +
    			"  " + ((EntityInstance)dc2In[i]).getCardinality());
    		DmRelation relM = DmRelation.getInstance();

    		String allEnRle[] = relM.getAllEntityRelations();
			TreeMap reInstances = ((EntityInstance)dc2In[i]).getEntityRelations();    
			for (int j = 0; j < allEnRle.length; j++) {
    			System.out.println("     "+allEnRle[j]+" Instance: " 
    			+((DmInstance) reInstances.get(allEnRle[j])).getName());				
       		}  

       	}  
		
		System.out.println("entity insteance: " + ei3.getName() + " of concept " + ei3.getConceptOf().getName()+ " has relations: ");
		TreeMap relationInstances = ei3.getEntityRelations();
		DmRelation relM = DmRelation.getInstance();
		String allEnRle[] = relM.getAllEntityRelations();
		for (int i = 0; i < allEnRle.length; i++) {
    		System.out.println("     "+allEnRle[i]+" Instance: " 
    			+((DmInstance) relationInstances.get(allEnRle[i])).getName());				
       	}  
		
				
    } //main()
	
}//class: EntityInstance