// © 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.util.Vector;

import com.ibm.icu.impl.Utility;

public class ClassTable implements LookupSubtable
{
    static class ClassEntry
    {
        private int glyphID;
        private int classID;
        
        public ClassEntry(int glyphID, int classID)
        {
            this.glyphID = glyphID;
            this.classID = classID;
        }
        
        public int getGlyphID()
        {
            return glyphID;
        }
        
        public int getClassID()
        {
            return classID;
        }
        
        public int compareTo(ClassEntry that)
        {
            return this.glyphID - that.glyphID;
        }
        
        //
        // Straight insertion sort from Knuth vol. III, pg. 81
        //
        public static void sort(ClassEntry[] table, Vector unsorted)
        {
            for (int e = 0; e < table.length; e += 1) {
                int i;
                ClassEntry v = (ClassEntry) unsorted.elementAt(e);

                for (i = e - 1; i >= 0; i -= 1) {
                    if (v.compareTo(table[i]) >= 0) {
                      break;
                    }

                    table[i + 1] = table[i];
                }

                table[i + 1] = v;
            }
        }
        
        public static int search(ClassEntry[] table, int glyphID)
        {
            int log2 = Utility.highBit(table.length);
            int power = 1 << log2;
            int extra = table.length - power;
            int probe = power;
            int index = 0;

            if (table[extra].glyphID <= glyphID) {
              index = extra;
            }

            while (probe > (1 << 0)) {
                probe >>= 1;

                if (table[index + probe].glyphID <= glyphID) {
                    index += probe;
                }
            }

            if (table[index].glyphID == glyphID) {
                return index;
            }

            return -1;
        }
    }
    
    static class ClassRangeRecord
    {
        private int startGlyphID;
        private int endGlyphID;
        private int classID;
        
        public ClassRangeRecord(int startGlyphID, int endGlyphID, int classID)
        {
            this.startGlyphID = startGlyphID;
            this.endGlyphID = endGlyphID;
            this.classID = classID;
        }
        
        public void write(OpenTypeTableWriter writer)
        {
            System.out.print(Utility.hex(startGlyphID, 6));
            System.out.print(" - ");
            System.out.print(Utility.hex(endGlyphID, 6));
            System.out.print(": ");
            System.out.println(classID);
            
            writer.writeData(startGlyphID);
            writer.writeData(endGlyphID);
            writer.writeData(classID);
        }
    }
    
    private Vector classMap;
    private ClassEntry[] classTable;
    private int snapshotSize;
    
    public ClassTable()
    {
        this.classMap = new Vector();
        this.classTable = null;
        this.snapshotSize = -1;
        
    }
    
    public void addMapping(int charID, int classID)
    {
        ClassEntry entry = new ClassEntry(charID, classID);
        
        classMap.addElement(entry);
    }
    
    public void addMapping(int startCharID, int endCharID, int classID)
    {
        for (int charID = startCharID; charID <= endCharID; charID += 1) {
            addMapping(charID, classID);
        }
    }
    
    public int getGlyphClassID(int glyphID)
    {
        int index = ClassEntry.search(classTable, glyphID);
        
        if (index >= 0) {
            return classTable[index].getClassID();
        }
        
        return 0;
    }
    
    public void snapshot()
    {
        if (snapshotSize != classMap.size()) {
            snapshotSize = classMap.size();
            classTable = new ClassEntry[snapshotSize];

            ClassEntry.sort(classTable, classMap);
        }
    }
    
    public void writeClassTable(OpenTypeTableWriter writer)
    {
        snapshot();
        
        Vector classRanges = new Vector();
        int startIndex = 0;
        
        while (startIndex < classTable.length) {
            int startID = classTable[startIndex].getGlyphID();
            int classID = classTable[startIndex].getClassID();
            int nextID = startID;
            int endID = startID;
            int endIndex;
            
            for (endIndex = startIndex; endIndex < classTable.length; endIndex += 1) {
                if (classTable[endIndex].getGlyphID() != nextID ||
                    classTable[endIndex].getClassID() != classID) {
                    break;
                }
                
                endID = nextID;
                nextID += 1;
            }
            
            if (classID != 0) {
                ClassRangeRecord range = new ClassRangeRecord(startID, endID, classID);
                
                classRanges.addElement(range);
            }
            
            startIndex = endIndex;
        }
        
        writer.writeData(2);                    // table format = 2 (class ranges)
        writer.writeData(classRanges.size());   // class range count
        
        for (int i = 0; i < classRanges.size(); i += 1) {
            ClassRangeRecord range = (ClassRangeRecord) classRanges.elementAt(i);
            
            range.write(writer);
        }
    }

    public void writeLookupSubtable(OpenTypeTableWriter writer)
    {
        int singleSubstitutionsBase = writer.getOutputIndex();
        int coverageTableIndex;
        
        snapshot();
        
        writer.writeData(2); // format 2: Specified output glyph indices
        coverageTableIndex = writer.getOutputIndex();
        writer.writeData(0); // offset to coverage table (fixed later)
        writer.writeData(classTable.length); // number of glyphIDs in substitution array
        
        for (int i = 0; i < classTable.length; i += 1) {
            writer.writeData(classTable[i].getClassID());
        }
        
        writer.fixOffset(coverageTableIndex, singleSubstitutionsBase);
        writer.writeData(1);
        writer.writeData(classTable.length);
        
        for (int i = 0; i < classTable.length; i += 1) {
            writer.writeData(classTable[i].getGlyphID());
        }
    }
}
    
    
