package memoire;

public class Element {

	private EntreeTableSymbole valeur;
	private Element pp; //pointeur sur precedent
	private Element ps; //pointeur sur suivant
	
	
	
	/**
	 * Constructeur de la classe memoire.Element.java
	 * @param valeur
	 */
	public Element(EntreeTableSymbole valeur) {
		this.valeur = valeur;
		this.pp = null;
		this.ps = null;
	}

	/**
	 * Constructeur de la classe memoire.Element.java
	 * @param valeur
	 * @param pp
	 * @param ps
	 */
	public Element(EntreeTableSymbole valeur, Element pp, Element ps) {
		this.valeur = valeur;
		this.pp = pp;
		this.ps = ps;
	}

	/**
	 * Revoie la valeur du membre valeur.
	 */
	public EntreeTableSymbole getValeur() {
		return valeur;
	}

	/**
	 * Affecte une nouvelle valeur au membre valeur.
	 */
	public void setValeur(EntreeTableSymbole valeur) {
		this.valeur = valeur;
	}

	/**
	 * Revoie la valeur du membre pp.
	 */
	public Element getPrecedent() {
		return pp;
	}

	/**
	 * Affecte une nouvelle valeur au membre pp.
	 */
	public void setPrecedent(Element pp) {
		this.pp = pp;
	}

	/**
	 * Revoie la valeur du membre ps.
	 */
	public Element getSuivant() {
		return ps;
	}

	/**
	 * Affecte une nouvelle valeur au membre ps.
	 */
	public void setSuivant(Element ps) {
		this.ps = ps;
	}
	
	/**
	 * Ajoute un symbole dans la liste chainee
	 * @param ets symbole a ajouter
	 */
	public void ajoute(EntreeTableSymbole ets){
		if(this.ps==null){
			this.ps = new Element(ets);
			this.ps.setPrecedent(this);
		}else{
			if(ps!=null){
				this.ps.ajoute(ets);
			}
		}
	}
	
	/**
	 * Supprime un symbole dans la liste chainee
	 * @param ets symbole a ajouter
	 */
	public void supprime(EntreeTableSymbole ets){
		if(this.valeur==ets){
			if(pp!=null){
				pp.setSuivant(ps);
			}
			if(ps!=null){
				ps.setSuivant(pp);
			}
		}else{
			if(ps!=null){
				this.ps.supprime(ets);
			}
		}
	}
	
	/**
	 * Recherche un symbole dans la liste chainee
	 * @param ets elements a ajouter
	 * @return element contenant le symbole
	 */
	public Element recherche(EntreeTableSymbole ets){
		if(this.valeur==ets){
			return this;
		}else{
			if(ps!=null){
				return this.ps.recherche(ets);
			}else{
				return null;
			}
		}
	}
	
	/**
	 * Renvoi la sorte d'un symbole
	 * @param id id du symbole cherche
	 * @param obj objet du symbole chercher
	 * @param portee portee dans laquelle chercher
	 * @return renvoi la sorte du symbole s'il a ete trouve
	 */
	public String rechercheSorte(String id, String obj, String portee){
		if(this.valeur.isId(id) 
				&& this.valeur.isPortee(portee) 
				&& ( this.valeur.isObj(obj) 
						|| (obj.equals("cst") && this.valeur.isObj("var")) 
						|| (obj.equals("var") && this.valeur.isObj("cst")) ) ){
			return this.valeur.sorte;
		}else{
			if(this.ps!=null){
				return this.ps.rechercheSorte(id, obj, portee);
			}else{
				return null;
			}
		}
	}
	
	/**
	 * Renvoi le profil d'un symbole
	 * @param id id du symbole cherche
	 * @param obj objet du symbole chercher
	 * @return renvoi la portee du symbole s'il a ete trouve
	 */
	public String rechercheProfil(String id, String obj, String portee){
		if(this.valeur.isId(id) 
				&& this.valeur.isPortee(portee) 
				&& ( this.valeur.isObj(obj) 
						|| (obj.equals("cst") && this.valeur.isObj("var")) 
						|| (obj.equals("var") && this.valeur.isObj("cst")) ) ){
			return this.valeur.profil;
		}else{
			if(this.ps!=null){
				return this.ps.rechercheProfil(id, obj, portee);
			}else{
				return null;
			}
		}
	}
	
	/**
	 * Renvoi la portee d'un symbole
	 * @param id id du symbole cherche
	 * @param obj objet du symbole chercher
	 * @return renvoi la portee du symbole s'il a ete trouve
	 */
	public String recherchePortee(String id, String obj){
		if(this.valeur.isId(id) && this.valeur.isObj(obj) ){
			return this.valeur.portee;
		}else{
			if(this.ps!=null){
				return this.ps.recherchePortee(id, obj);
			}else{
				return null;
			}
		}
	}
	
	public String toString(){
		String ret = valeur.toString()+" -> ";
		if(ps!=null){
			ret+=ps.toString();
		}else{
			ret+="null";
		}
		return ret;
	}
	
	
	
}
