package osa.attribute.atgrammar.grammar;

import java.util.*;
import osa.attribute.atgrammar.grammar.*;
 import osa.attribute.atgrammar.grammar.symbols.*;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Copyright: </p>
 * <p>Company: </p>
 * @author not attributable
 * @version
 */

public class CommonDictionary
  {
  protected TreeMap terminal_dictionary=new TreeMap();
  protected TreeMap non_terminal_dictionary=new TreeMap();
  protected TreeMap output_dictionary=new TreeMap();
  protected TreeMap special_dictionary=new TreeMap();


  protected Grammar grammar_reference;

  public CommonDictionary(Grammar grammar_reference)
    {
    this.grammar_reference=grammar_reference;
    }

  // accessors
  public TerminalSymbol getTerminalSymbol(String symbol_name)
    {
    return (TerminalSymbol)terminal_dictionary.get(symbol_name);
    }

  public NonTerminalSymbol getNonTerminalSymbol(String symbol_name)
    {
    return (NonTerminalSymbol)non_terminal_dictionary.get(symbol_name);
    }

  public OutputSymbol getOutputSymbol(String symbol_name)
    {
    return (OutputSymbol)output_dictionary.get(symbol_name);
    }

  public Collection getTerminals()
    {
    return terminal_dictionary.values();
    }

  public Collection getNonTerminals()
    {
    return non_terminal_dictionary.values();
    }

  public Collection getOutputs()
    {
    return output_dictionary.values();
    }


  // mutators
  public boolean putSymbol(Symbol symbol)
    {
    String symbol_name=symbol.getOriginalName();
    boolean is_put;
    switch(symbol.getType())
          {
          case Symbol.NON_TERMINAL_SYMBOL:
            if(terminal_dictionary.get(symbol_name)==null)
              {
              terminal_dictionary.put(symbol_name,symbol);
              is_put=true;
              }
            else
              {
              is_put=false;
              }
            break;
          case Symbol.TERMINAL_SYMBOL:
            if(non_terminal_dictionary.get(symbol_name)==null)
              {
              non_terminal_dictionary.put(symbol_name,symbol);
              is_put=true;
              }
            else
              {
              is_put=false;
              }
            break;
          case Symbol.OUTPUT_SYMBOL:
            if(output_dictionary.get(symbol_name)==null)
              {
              output_dictionary.put(symbol_name,symbol);
              is_put=true;
              }
            else
              {
              is_put=false;
              }
            break;
          default:
            System.err.println("Error during putting symbol in dictionary!!!");
            is_put=false;
          }
    return is_put;
    }

  public boolean putTerminalSymbol(TerminalSymbol symbol)
    {
    String symbol_name=symbol.getOriginalName();
    if(terminal_dictionary.get(symbol_name)==null)
      {
      terminal_dictionary.put(symbol.getOriginalName(),symbol);
      return true;
      }
    return false;
    }

  public boolean putNonTerminalSymbol(NonTerminalSymbol symbol)
    {
    String symbol_name=symbol.getOriginalName();
    if(non_terminal_dictionary.get(symbol_name)==null)
      {
      non_terminal_dictionary.put(symbol.getOriginalName(),symbol);
      return true;
      }
    return false;
    }

  public boolean putOutputSymbol(OutputSymbol symbol)
    {
    String symbol_name=symbol.getOriginalName();
    if(output_dictionary.get(symbol_name)==null)
      {
      output_dictionary.put(symbol.getOriginalName(),symbol);
      return true;
      }
    return false;
    }

  public void removeTerminalSymbol(String symbol_name)
    {
    Symbol removed_symbol=(Symbol)terminal_dictionary.get(symbol_name);
    if(removed_symbol!=null)
      {
      removed_symbol.setIsDeleted(true);
      }
    terminal_dictionary.remove(symbol_name);
    }

  public void removeNonTerminalSymbol(String symbol_name)
    {
    Symbol removed_symbol=(Symbol)non_terminal_dictionary.get(symbol_name);
    if(removed_symbol!=null)
      {
      removed_symbol.setIsDeleted(true);
      }

    non_terminal_dictionary.remove(symbol_name);
    }

  public void removeOutputSymbol(String symbol_name)
    {
    Symbol removed_symbol=(Symbol)output_dictionary.get(symbol_name);
    if(removed_symbol!=null)
      {
      removed_symbol.setIsDeleted(true);
      }
    output_dictionary.remove(symbol_name);
    }

  public boolean renameSymbol(Symbol symbol,String new_name)
    {
    String old_name=symbol.getOriginalName();
    boolean is_renamed=false;

    switch(symbol.getType())
          {
          case Symbol.NON_TERMINAL_SYMBOL:
            if(non_terminal_dictionary.get(new_name)==null)
              {
              symbol.setOriginalName(new_name);
              non_terminal_dictionary.remove(old_name);
              non_terminal_dictionary.put(new_name,symbol);
              is_renamed=true;
              }
            break;
          case Symbol.TERMINAL_SYMBOL:
            if(terminal_dictionary.get(new_name)==null)
              {
              symbol.setOriginalName(new_name);
              terminal_dictionary.remove(old_name);
              terminal_dictionary.put(new_name,symbol);
              is_renamed=true;
              }
            break;
          case Symbol.OUTPUT_SYMBOL:
            if(output_dictionary.get(new_name)==null)
              {
              symbol.setOriginalName(new_name);
              output_dictionary.remove(old_name);
              output_dictionary.put(new_name,symbol);
              is_renamed=true;
              }
            break;
          }
    return is_renamed;
    }

  public void resetAllCounters()
    {
    Iterator temp_iterator;
    temp_iterator=getNonTerminals().iterator();
    while(temp_iterator.hasNext())
         {
         ((Symbol)temp_iterator.next()).resetCounter();
         }
    temp_iterator=getTerminals().iterator();
    while(temp_iterator.hasNext())
         {
         ((Symbol)temp_iterator.next()).resetCounter();
         }
    temp_iterator=getOutputs().iterator();
    while(temp_iterator.hasNext())
         {
         ((Symbol)temp_iterator.next()).resetCounter();
         }
    }

  public void clearDictionary()
    {
    non_terminal_dictionary.clear();
    terminal_dictionary.clear();
    output_dictionary.clear();
    }
  }