package emn.fr.ascola.extractor;

import java.util.Vector;

import emn.fr.ascola.extractor.Decision.Values;

/**
 * Class for information about the types
 * @author jroyer
 *
 */
public class Information {
	
	/**
	 * Decision indicator.
	 */
	private Decision data;
	
	/**
	 * Main point indicator.
	 */
	private boolean root;
	
	/**
	 * Add type resolved.
	 */
	private MyIType ibind;

	/**
	 * Parent component type names in the composition or null.
	 */
	private Vector<String> parents;
	
	/**
	 * Utility flag.
	 */
	private boolean viewed;
	
	/**
	 * Cycle structure indicator.
	 */
	private boolean cycle;
	
	/**
	 * Default constructor.
	 */
	public Information() {
		this.data = new Decision();
		this.ibind = new MyIType();
		this.root = false;
		this.viewed = false;
		this.cycle = false;
		this.parents = null;
	}
	
	/**
	 * Constructor for root type.
	 * @param r
	 */
	public Information(boolean r) {
		this(); 
		this.root = true;
	}

	/**
	 * String description.
	 */
	public String toString() {
		String result = "";
		if (this.data.isDataType()) {
			result = " is a Data type\n";
		} else if (this.data.isComponentType()) {
			result = " is a Component type\n";
		} else {
			result = " undefined \n";
		}
		if (this.root) {
			result += " ROOT\n";
		}
		if (this.ibind != null) {
			result += " BINDING: " + this.ibind;
		}
		return result + " VIEWED=" + this.viewed + " CYCLE=" + this.cycle
		 				+ " PARENT: " + this.parents;
	}
	
	/**
	 * Set data type indicator.
	 * @param data
	 */
	public void setDataType(boolean data) {
		if (data) {
			this.data = new Decision(Values.DATA);
		}
	}

	/**
	 * Set component type indicator.
	 * @param data
	 */
	public void setComponentType(boolean data) {
		if (data) {
			this.data = new Decision(Values.COMP);
		} 
	}
	
	/**
	 * Set the resolved type.
	 * @param it
	 */
	public void setType(MyIType it) {
		this.ibind = it;
	}
	
	/**
	 * Set root indicator.
	 */
	public void setRoot() {
		this.root = true;
	}

	/**
	 * Check if type information is resolved.
	 * @return
	 */
	public boolean isResolved() {
		return (this.ibind.isResolved());
	}
	
	/**
	 * test if has fields.
	 * @return
	 */
	public boolean hasFields() {
		return this.ibind.hasFields();
	}
	
	/**
	 * Check if type information is resolved.
	 * @return
	 */
	public boolean isDataType() {
		return this.data.isDataType();
	}
	
	/**
	 * Check if type information is resolved.
	 * @return
	 */
	public boolean isComponentType() {
		return this.data.isComponentType();
	}
	
	public boolean isUndefined() {
		return this.data.isUndefined();
	}

	/**
	 * Get ITypeBinding.
	 * @return
	 */
	public MyIType getIbind() {
		return ibind;
	}

	public boolean isViewed() {
		return viewed;
	}

	public void setViewed(boolean viewed) {
		this.viewed = viewed;
	}

	public boolean hasCycle() {
		return cycle;
	}

	public void setCycle(boolean cycle) {
		this.cycle = cycle;
	}

	/**
	 * Get the list of parents.
	 * @return
	 */
	public Vector<String> getParents() {
		return parents;
	}
	
	/**
	 * Add a new parent name.
	 * @param p
	 */
	public void addParent (String p) {
		if (this.parents == null) {
			Vector<String> tmp = new Vector<String>();
			tmp.add(p);
			this.parents = tmp; 
		} else {
			Vector<String> tmp = this.getParents();
			if (!tmp.contains(p)) {
				tmp.add(p);
			}
		}
	}
}
