/*
 *******************************************************************************
 * Copyright (C) 1998-2010, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * Created on Dec 3, 2003
 *
 *******************************************************************************
 */
package com.ibm.icu.dev.tool.layout;


import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;

import com.ibm.icu.impl.Utility;
import com.ibm.icu.text.UTF16;

public class LigatureTree
{
    static class Lignode
    {
        int target;
        int ligature = -1;
        Lignode[] subnodes = null;

        Lignode()
        {
            target = -1;
        }

        Lignode(int target)
        {
            this.target = target;
        }

        boolean isMatch()
        {
            return ligature != -1;
        }

        int getLigature()
        {
            return ligature;
        }

        Lignode subnode(int c)
        {
            if (subnodes != null) {
                int len = subnodes.length;

                if (c <= subnodes[len - 1].target) {
                    for (int i = 0; i < len; i+= 1) {
                        int t = subnodes[i].target;

                        if (t > c) {
                            return null;
                        }

                        if (t == c) {
                            return subnodes[i];
                        }
                    }
                }
            }

            return null;
        }

        String ligatureString(int[] chars)
        {
            StringBuffer result = new StringBuffer();
            int len = chars.length - 1;
            
            for (int i = 0; i < len; i += 1) {
                if (i > 0) {
                    result.append(" + ");
                }
                
                result.append(Utility.hex(chars[i], 6));
           }
            
            result.append(" => " + Utility.hex(chars[len], 6));
            
            return result.toString();
        }
        
        void insert(int[] chars, int index)
        {
            int c = chars[index];
            int len = chars.length;

            if (len == index + 1) {
                if (ligature != -1) {
                    System.out.println("ignoring ligature " + ligatureString(chars) +
                                       ": already have " + Utility.hex(ligature, 6));
                } else {
                    ligature = c;
                }

                return;
            }

            if (subnodes == null) {
                subnodes = new Lignode[1];
                subnodes[0] = new Lignode(c);
                subnodes[0].insert(chars, index + 1);
            } else {
                int i;

                for (i = 0; i < subnodes.length; i += 1)
                {
                    int t = subnodes[i].target;

                    if (t == c) {
                        subnodes[i].insert(chars, index + 1);
                        return;
                    } else if (t > c) {
                        break;
                    }
                }

                Lignode[] nnodes = new Lignode[subnodes.length + 1];

                if (i > 0) {
                    System.arraycopy(subnodes, 0, nnodes, 0, i);
                }

                nnodes[i] = new Lignode(c);

                if (i < subnodes.length) {
                    System.arraycopy(subnodes, i, nnodes, i + 1, subnodes.length - i);
                }

                subnodes = nnodes;

                subnodes[i].insert(chars, index + 1);
            }
        }
        
        public void walk(TreeWalker walker)
        {
            if (target != -1) {
                walker.down(target);
            }
            
            if (subnodes != null) {
                for (int i = 0; i < subnodes.length; i += 1)
                {
                    subnodes[i].walk(walker);
                }
            }
            
            if (ligature != -1) {
                walker.ligature(ligature);
            }
                
            walker.up();
        }

        static final String ind = "                                      ";

        /*
         * Write debugging information to w, starting at the provided indentation level.
         */
        public void dump(Writer w, int indent)
        {
            String tab = ind.substring(0, Math.min(indent, ind.length()));

            try {
                w.write(tab);
                if (target != -1) {
                    w.write(Utility.hex(target, 6));
                }
                
                if (ligature != -1)
                {
                    w.write(" --> ");
                    w.write(Utility.hex(ligature, 6));
                }
                
                w.write("\n");
                
                if (subnodes != null) {
                    w.write(tab);
                    w.write("{\n");
                    indent += 4;
                    
                    for (int i = 0; i < subnodes.length; i += 1) {
                        subnodes[i].dump(w, indent);
                    }
                    
                    w.write(tab);
                    w.write("}\n");
                }
            } catch (IOException e) {
                System.out.println(e);
            }
        }

    }

    private Lignode root = new Lignode();
    
    public LigatureTree()
    {
        // anything?
    }

    private int[] toIntArray(String s)
    {
        int count = UTF16.countCodePoint(s);
        int[] result = new int[count];
        
        for (int i = 0; i < count; i += 1) {
            result[i] = UTF16.charAt(s, i);
        }
        
        return result;
    }

    public void insert(String string)
    {
        root.insert(toIntArray(string), 0);
    }
    
    public void insert(int[] chars)
    {
        root.insert(chars, 0);
    }
    
    public void walk(TreeWalker walker)
    {
        root.walk(walker);
        walker.done();
    }
    
    public void dump()
    {
        PrintWriter pw = new PrintWriter(System.out);
        
        root.dump(pw, 0);
        pw.flush();
    }
}
