// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 *******************************************************************************
 * 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();
    }
}
