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

package domainModel;

import java.util.*;

/**
 * @author 
 */
public class DmConcept extends DmClass 
{
	private static ConceptType cType = ConceptType.getInstance();
	private static DmConcept defaultEntityConcept 
		= new DmConcept("object",ConceptType.getDefaultEntityType());
	private static DmConcept defaultActionConcept  
		= new DmConcept("generic", ConceptType.getDefaultActionType());
	private static DmConcept defaultUserConcept  
		= new DmConcept("user", ConceptType.getDefaultUserType());
	private static DmConcept defaultSystemConcept 
		= new DmConcept("system",ConceptType.getDefaultSystemType());
	private static DmConcept defaultInterfaceConcept 
		= new DmConcept("interface",ConceptType.getInterfaceType());

	//list of different languages 	
	public static final String _ENGLISH = "English";
	public static final String _FRENCH = "French";
	public static final String _CHINESE = "Chinese";

	static{
		defaultUserConcept.setParent(defaultEntityConcept);
		defaultSystemConcept.setParent(defaultEntityConcept);
		
	}
	private Vector instances; 	// list of all instances of the this concept
	private String type =ConceptType.getDefaultEntityType(); 		// the type of this concept belongs
	private DmConcept parent; 	// its parent concept

	private ArrayList children;	// list of all children concept
	
	private HashMap  _languageCards=new HashMap();	// store lexicon infor in different languages
												// in the form of Language and Card pairs
	
	/* create a new DmConcept object with name "na"
	*/
	
	public DmConcept(String na) 
	{
		super(na);
		instances = new Vector(5);
		children = new ArrayList(5);
		
		//initialise _languageCards
		_languageCards.put(_FRENCH, null);
		_languageCards.put(_CHINESE, null);
		
		// create a regular English Noun card by default
		Card engCard = new EnglishNoun(na);
		_languageCards.put(_ENGLISH, engCard);
		
		// add to the card to DmManager object store
	//	DmManager.getInstance().addEnglishN((EnglishNoun)engCard);
		
	}
		
	/* create a new DmConcept object with name "na"
	* and type, "type".
	*/
	
	public DmConcept(String na, String type) 
	{
		super(na);
		instances = new Vector(5);
		children = new ArrayList(5);
		
		// if it is a action-type create a EnglishVerb
		// otherwise, create a EnglishNoun
		Card engCard = new EnglishNoun(na);
		if (setType(type)){
			if (ConceptType.isActionType(getType())){
				//getType().equals(ConceptType.getDefaultActionType())){
				
			 	engCard= new EnglishVerb(na);
			} 
		}else type =ConceptType.getDefaultEntityType();
				
		//initialise _languageCards
		_languageCards.put(_ENGLISH, engCard);
		_languageCards.put(_FRENCH, null);
		_languageCards.put(_CHINESE, null);


	}
	
	/* create a new DmConcept object with ID, "iD"; name "na"
	* and type: "type.
	*/
	
	public DmConcept(String iD, String na,String type) 
	{
		super(iD, na);
		instances = new Vector(5);
		children = new ArrayList(5);
		//System.out.println ("create concept: "+ na); 

		// if it is a action-type create a EnglishVerb
		// otherwise, create a EnglishNoun
		Card engCard = new EnglishNoun(na);
		if (setType(type)){
			//System.out.println ("set type: OK "); 

			if (getType().equals(ConceptType.getDefaultActionType()))
				engCard= new EnglishVerb(na);
		}else {
			type =ConceptType.getDefaultEntityType();
			System.out.println ("set default enitty type: "); 
		}
		
		//initialise _languageCards
		_languageCards.put(_ENGLISH, engCard);
		_languageCards.put(_FRENCH, null);
		_languageCards.put(_CHINESE, null);

	}
	
    /**
     * retrun all known instances for this concept 
     */
    public DmInstance[] getAllInstances() {
    	DmInstance allInstances[] = new DmInstance[instances.size()];
        instances.copyInto(allInstances);
        return allInstances;
    } // getAllInstances()
    	
    /**
     * Check if the given DmInstace belongs to this concept 
     * @param aInstance, the aInstance to be checked
     */
    public boolean isTheInstance(DmInstance aInstance) {
        if (this == aInstance.getConceptOf()){
        	return true;
        }else return false;
    } // isTheInstance()
    	
    /**
     * Check if the given DmInstace is already in the
     * concept's instnace list
     * @param aInstance, the aInstance to be checked
     */
    public boolean isInCollection(DmInstance aInstance) {
        if (instances.contains( aInstance)){
        	return true;
        }else return false;
    } // isInCollection()


    /**
     * Remove an Instance from the concept's collection . 
     * 
     * @param aInstance, the Instance to be deleted. 
     * If aInstance is not in the collection, a message is print out.
     */
    public void removeInstance(DmInstance aInstance) {
    	if (!(isInCollection(aInstance))) {
    		System.out.println ("Instance: "+ aInstance.getName() + 
    			" is not in " + getName()+ "'s instance-collection!");
    		return;
    	} else{
    		
    		//after remove an intance from the concepts list
    		// set the instance's conceptOf to dafault concept
    		// and add it to the default-concept's instance list
    		instances.removeElement(aInstance);
    //		if (getType().equals(ConceptType.getDefaultActionType())){
    //			aInstance.setConceptOf(DefaultActionConcept);
    //			DefaultActionConcept.addInstance(aInstance);
    //		} else {
    //			aInstance.setConceptOf(DefaultEntityConcept);
    //			DefaultEntityConcept.addInstance(aInstance);
    //		}
    	}
    } // removeInstance(String type)
    
    /**
	 * Add an Instance to the concept's instance list
	 * @exception 
	 * @author 
*
* @param aInstances: the instance to be added
	 */
	public void addInstance(DmInstance aInstance) {
	//	if (isTheInstance( aInstance)) {
			if (!(isInCollection(aInstance))){
				instances.add(aInstance);
			}
	//	} else{
			//first remove it from its original concept's list
			// then set its conceptOf to this concept, 
	//		aInstance.getConceptOf().removeInstance(aInstance);
	//		aInstance.setConceptOf(this);
	//	}
	} //addInstance()
		
	
/**
* Access method for the type property.
* @return   the current value of the type property
	 */
	public String getType() {
		return type;
	}
	
/**
* Sets the value of the type property.
* @param aType the new value of the type property
	 */
	public boolean setType(String aType) {
		String wellFormed = cType.getConceptType(aType);
		if (!(wellFormed == null))	{
			if (wellFormed.equals("action type")){
				wellFormed =ConceptType.getDefaultActionType();
			}else if (wellFormed.equals("entity type")){
				wellFormed =ConceptType.getDefaultEntityType();
			}

			type = wellFormed;
			return true;
		}
		else {
			System.out.println(aType + " is not a valid concept-type!!");
			return false;
		}
	}	// setType()

	/**
* Access method for the parent property.
*
* @return   the current value of the parent property
	 */
	public DmConcept getParent() {
		return parent;
	}
	
	/**
* Sets the value of the parent property. Explicit action
* is required to add this object ot aParent's children collection
*
* @param aParent the new value of the parent property
	 */
	public void setParent(DmConcept aParent) {
		parent = aParent;
		
	}	// setParent()

    /**
     * Check if the given DmConcept is a child of this
     * concept(in its children collection
     * @param aConcept, the Concept to be checked
     */
    public boolean isChild(DmConcept aConcept) {
    	if (aConcept == null) return false;
    	if (children.contains( aConcept)){
        	return true;
        }else return false;
    } // isChild()

    /**
     * return number of children the concept has
     */
    public int numberChild() {
         return children.size();
    } // numberChild()

    /**
     * return all child concepts 
     */
    public DmConcept[] getAllChildren() {
    	DmConcept allChildren[] = new DmConcept[numberChild()];
		children.toArray(allChildren); 
    	return allChildren; 
    } // getAllChildren()

    /**
	* add a child to its childen collection. explicit 
	* action is need to set aConcept's parent to this 
	* object
	* @param aConcept, the Concept to be added
     */
    public void addChild(DmConcept aConcept) {
        	if (!(isChild(aConcept))) {
        		children.add(aConcept); 
        	//	aConcept.setParent(this);	
        	}
        	

    } // addChild()

    /**
	* remove a child from its childen collection. Explicit 
	* action is required to unset aConcept's parent other
	* than this.
	* @param aConcept, the Concept to be removed
     */
    public void removeChild(DmConcept aConcept) {
        	if (isChild(aConcept)){
        		children.remove(children.indexOf(aConcept));
        	}
    } // removeChild()

    /**
	* establish a parent and child hierarchy 
	* @param aParent, the Concept to be parent. If aParent == null,
	* aChild will be still be removed from its original parent's 
	* children collection
	* @param aChild, the Concept to be child. If aChild == null,
	* nothing will be done
     */
    public static void setPCHierarchy(DmConcept aParent, DmConcept aChild) {
        if (aChild!= null){
        	DmConcept oldP = aChild.getParent();
        	if (oldP != null) {
        		oldP.removeChild(aChild);
        	}
        	
        	if (aParent != null) aParent.addChild(aChild);
        	aChild.setParent(aParent);
        }
    } // setPCHierarchy()

    /**
	*
	* @return   the number of instances 
	 */
	public int numberOfInstances() {
		return instances.size();
	}
	
    /**
     * retrun default entity-concept 
     */
    public static DmConcept getDefaultEntityConcept() {
    	return defaultEntityConcept;
    } // getDefaultEntityConcept()
    
    /**
     * retrun default action-concept 
     */
    public static DmConcept getDefaultActionConcept() {
    	return defaultActionConcept;
    } // getDefaultActionConcept()
    
    /**
     * retrun default user-concept 
     */
    public static DmConcept getDefaultUserConcept() {
    	return defaultUserConcept;
    } // getDefaultUserConcept()
    
    /**
     * retrun default system-concept 
     */
    public static DmConcept getDefaultSystemConcept() {
    	return defaultSystemConcept;
    } // getDefaultSystemConcept()
    
    /**
     * retrun default interface-concept 
     */
    public static DmConcept getInterfaceConcept() {
    	return defaultInterfaceConcept;
    } // getInterfaceConcept()
    
    /**
     * set default Entity-concept 
     */
    public static void setDefaultEntityConcept(DmConcept de) {
    	if (de != null)  defaultEntityConcept = de;
    } // setDefaultEntityConcept()
    
    /**
     * set default action-concept 
     */
    public static void setDefaultActionConcept(DmConcept de) {
    	if (de != null)  defaultActionConcept = de;
    } // setDefaultActionConcept()
    
    /**
     * set default user-concept 
     */
    public static void setDefaultUserConcept(DmConcept de) {
    	if (de != null)  defaultUserConcept = de;
    } // setDefaultUserConcept()
    
    /**
     * set default system-concept 
     */
    public static void setDefaultSystemConcept(DmConcept de) {
    	if (de != null)  defaultSystemConcept = de;
    } // setDefaultSystemConcept()
    
    /**
     * set default interface-concept 
     */
    public static void setInterfaceConcept(DmConcept de) {
    	if (de != null)  defaultInterfaceConcept = de;
    } // setInterfaceConcept()
	
/**
* Access method for the _languageCards property.
* @return   the current Card for the language as specified by lan
* which should be one of DmConcept._ENGLISH, _FRENCH, _CHINESE...
*/
	public Card getCard(String lan) {
		return (Card)_languageCards.get(lan);
	}
	
/**
* Sets the value of the the Card for the langauge lan.
* @param lan, a language which should be one of 
* DmConcept._ENGLISH, _FRENCH, _CHINESE...; 
* card, the card for that language
*/
	public void setCard(String lan, Card card) {
		_languageCards.put(lan,card);
	}	// setCard()

	
} //DmConcept