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