package osa.attribute.atgrammar.grammar.symbols;

import java.util.*;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2005</p>
 * <p>Company: </p>
 * @author not attributable
 * @version 1.0
 */

public class Symbol
  implements Cloneable
  {
  public static final int UNKNOWN_SYMBOL=0;
  public static final int TERMINAL_SYMBOL=1;
  public static final int NON_TERMINAL_SYMBOL=2;
  public static final int OUTPUT_SYMBOL=3;
  public static final int SPECIAL_SYMBOL=4;

  protected int counter=0;

  protected String symbol_name=null;
  protected int symbol_type;
  protected int symbol_index;

  protected ArrayList attributes_list=new ArrayList();
  protected int attributes_count=0;

  protected boolean is_cloned; // mean that symbol _was_ cloned!
  protected Symbol original_reference;

  protected boolean is_deleted; // mean that symbol _was_ deleted from dictionary!

  protected Symbol()
    {
    symbol_type=UNKNOWN_SYMBOL;
    symbol_name="---!abstract!---";
    is_cloned=false;
    original_reference=this;
    }

  public void incrementCounter()
    {
    counter++;
    }

  public void resetCounter()
    {
    counter=0;
    }

  public int getCounterValue()
    {
    return counter;
    }

  protected Symbol(String symbol_representation)
    {
    this.symbol_name=symbol_representation.toString();
    }

  public int getType()
    {
    return symbol_type;
    }

  public Object clone()
    {
    return null;
    }

  public String toString()
    {
    String result="";
    switch(symbol_type)
          {
          case NON_TERMINAL_SYMBOL:
            result+="<";
            result+=getIndexedName();
            result+=">";
            break;
          case TERMINAL_SYMBOL:
            if(symbol_name.length()>1)
              {
              result+="\"";
              result+=getIndexedName();
              result+="\"";
              }
            else
              {
              result+=getIndexedName();
              }
            break;
          case OUTPUT_SYMBOL:
            result+="{";
            result+=getIndexedName();
            result+="}";
            break;
          }
    return result;
    }

  public boolean addAttribute(Attribute attribute)
    {
    boolean is_added=false;
    if(findAttribute(attribute.getName())==null)
      {
      attributes_list.add(attribute);
      attribute.setOwner(this);
      attributes_count++;
      is_added=true;
      }
    return is_added;
    }

  public Attribute findAttribute(String name)
    {
    Attribute temp_attribute;
    for(int i=0;i<this.attributes_count;i++)
       {
       temp_attribute=(Attribute)attributes_list.get(i);
       if(temp_attribute.getName().equals(name))
         {
         return temp_attribute;
         }
       }
    return null;
    }

  public void removeAttribute(Attribute attribute)
    {
    attributes_list.remove(attribute);
    attributes_count--;
    }

  public void removeAttributeAt(int index_of_attribute)
    {
    attributes_list.remove(index_of_attribute);
    attributes_count--;
    }

  public Attribute getAttributeAt(int index_of_attribute)
    {
    return (Attribute)attributes_list.get(index_of_attribute);
    }

  public int getAttrubutesCount()
    {
    return attributes_list.size();
    }


  public String getOriginalName()
    {
    return symbol_name;
    }




  public void setOriginalName(String name)
    {
    symbol_name=name;
    }

  public String getIndexedName()
    {
    if(symbol_index==0)return symbol_name;
    return symbol_name+"_"+symbol_index;
    }

  public boolean isDeleted()
    {
    return is_deleted;
    }

  public void setIsDeleted(boolean is_deleted)
    {
    this.is_deleted=is_deleted;
    }

  public Symbol getOriginalReference()
    {
    return original_reference;
    }

  }