/*
***************************************************************************
*   Copyright (C) 2002-2006 International Business Machines Corporation   *
*   and others. All rights reserved.                                      *
***************************************************************************
*/
package com.ibm.icu.text;

import java.util.HashMap;
import java.util.Collection;

import java.text.ParsePosition;
import com.ibm.icu.lang.UCharacter;

class RBBISymbolTable implements SymbolTable{
    
    String               fRules;
    HashMap              fHashTable;
    RBBIRuleScanner      fRuleScanner;

    // These next two fields are part of the mechanism for passing references to
    //   already-constructed UnicodeSets back to the UnicodeSet constructor
    //   when the pattern includes $variable references.
    String               ffffString;
    UnicodeSet           fCachedSetLookup;
    
    
    
    static class RBBISymbolTableEntry  { 
        String          key;
        RBBINode        val;
         };


    
 RBBISymbolTable(RBBIRuleScanner rs, String rules) {
     fRules       = rules;
     fRuleScanner = rs;
     fHashTable   = new HashMap();
     ffffString   = "\uffff";
}




//
//  RBBISymbolTable::lookup       This function from the abstract symbol table inteface
//                                looks up a variable name and returns a UnicodeString
//                                containing the substitution text.
//
//                                The variable name does NOT include the leading $.
//
public char[]  lookup(String s) 
{
    RBBISymbolTableEntry  el;
    RBBINode              varRefNode;
    RBBINode              exprNode;
    
    RBBINode              usetNode;
    String                retString;
 
    el = (RBBISymbolTableEntry)fHashTable.get(s);
    if (el == null) {
        return null;
    }

    // Walk through any chain of variable assignments that ultimately resolve to a Set Ref.
    varRefNode = el.val;
    while (varRefNode.fLeftChild.fType == RBBINode.varRef) {
        varRefNode = varRefNode.fLeftChild;
    }
    
    exprNode   = varRefNode.fLeftChild;     // Root node of expression for variable
    if (exprNode.fType == RBBINode.setRef) {
        // The $variable refers to a single UnicodeSet
        //   return the ffffString, which will subsequently be interpreted as a
        //   stand-in character for the set by RBBISymbolTable::lookupMatcher()
        usetNode = exprNode.fLeftChild;
        fCachedSetLookup = usetNode.fInputSet;
        retString = ffffString;
    }
    else
    {
        // The variable refers to something other than just a set.
        // This is an error in the rules being compiled.  $Variables inside of UnicodeSets
        //   must refer only to another set, not to some random non-set expression.
        //   Note:  single characters are represented as sets, so they are ok.
        fRuleScanner.error(RBBIRuleBuilder.U_BRK_MALFORMED_SET);
        retString = exprNode.fText;
        fCachedSetLookup = null;
    }
    return retString.toCharArray();
}



//
//  RBBISymbolTable::lookupMatcher   This function from the abstract symbol table
//                                   interface maps a single stand-in character to a
//                                   pointer to a Unicode Set.   The Unicode Set code uses this
//                                   mechanism to get all references to the same $variable
//                                   name to refer to a single common Unicode Set instance.
//
//    This implementation cheats a little, and does not maintain a map of stand-in chars
//    to sets.  Instead, it takes advantage of the fact that  the UnicodeSet
//    constructor will always call this function right after calling lookup(),
//    and we just need to remember what set to return between these two calls.
public UnicodeMatcher lookupMatcher(int ch)  
{
    UnicodeSet retVal = null;
    if (ch == 0xffff) {
        retVal = fCachedSetLookup;
        fCachedSetLookup = null;
    }
    return retVal;
}

//
// RBBISymbolTable::parseReference   This function from the abstract symbol table interface
//                                   looks for a $variable name in the source text.
//                                   It does not look it up, only scans for it.
//                                   It is used by the UnicodeSet parser.
//
public String   parseReference( String text, ParsePosition pos, int limit) 
{
    int start = pos.getIndex();
    int i = start;
    String result = "";
    while (i < limit) {
        int c = UTF16.charAt(text, i);
        if ((i==start && !UCharacter.isUnicodeIdentifierStart(c)) || !UCharacter.isUnicodeIdentifierPart(c)) {
            break;
        }
        i += UTF16.getCharCount(c);
    }
    if (i == start) { // No valid name chars
        return result; // Indicate failure with empty string
    }
    pos.setIndex(i);
    result = text.substring(start, i);
    return result;
}



//
// RBBISymbolTable::lookupNode      Given a key (a variable name), return the
//                                  corresponding RBBI Node.  If there is no entry
//                                  in the table for this name, return NULL.
//
RBBINode       lookupNode(String key) {

    RBBINode              retNode = null;
    RBBISymbolTableEntry  el;

    el = (RBBISymbolTableEntry)fHashTable.get(key);
    if (el != null) {
        retNode = el.val;
    }
    return retNode;
}


//
//    RBBISymbolTable::addEntry     Add a new entry to the symbol table.
//                                  Indicate an error if the name already exists -
//                                    this will only occur in the case of duplicate
//                                    variable assignments.
//
void   addEntry  (String key, RBBINode val)  {
    RBBISymbolTableEntry e;
    e = (RBBISymbolTableEntry )fHashTable.get(key);
    if (e != null) {
        fRuleScanner.error(RBBIRuleBuilder.U_BRK_VARIABLE_REDFINITION);
        return;
    }

    e = new RBBISymbolTableEntry();
    e.key = key;
    e.val = val;
    fHashTable.put(e.key, e);
}





//
//  RBBISymbolTable::print    Debugging function, dump out the symbol table contents.
//
void rbbiSymtablePrint() {
    System.out.print("Variable Definitions\n" +
           "Name               Node Val     String Val\n" +
           "----------------------------------------------------------------------\n");

    int pos = -1;
    RBBISymbolTableEntry [] syms = new RBBISymbolTableEntry[0];
    Collection  t = fHashTable.values();
    syms = (RBBISymbolTableEntry[])  t.toArray(syms);
    
    for (int i=0; i<syms.length; i++) {
        RBBISymbolTableEntry  s   = syms[i];

        System.out.print("  " + s.key + "  ");   // TODO:  format output into columns.
        System.out.print("  " + s.val + "  ");
        System.out.print(s.val.fLeftChild.fText);
        System.out.print("\n");
    }

    System.out.println("\nParsed Variable Definitions\n");
    pos = -1;
    for (int i=0; i<syms.length; i++) {
        RBBISymbolTableEntry  s   = syms[i];
        System.out.print(s.key);
        s.val.fLeftChild.printTree(true);
        System.out.print("\n");
    }
}
    
    
}
