import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;

/**
 * Compressed General Category and Numeric Value: Compressor
 * <p>
 * Warranty & Liability
 * To the extent permitted by applicable law and unless explicitly
 * otherwise agreed upon, XLOG Technologies AG makes no warranties
 * regarding the provided information. XLOG Technologies AG assumes
 * no liability that any problems might be solved with the information
 * provided by XLOG Technologies AG.
 * <p>
 * Rights & License
 * All industrial property rights regarding the information - copyright
 * and patent rights in particular - are the sole property of XLOG
 * Technologies AG. If the company was not the originator of some
 * excerpts, XLOG Technologies AG has at least obtained the right to
 * reproduce, change and translate the information.
 * <p>
 * Reproduction is restricted to the whole unaltered document. Reproduction
 * of the information is only allowed for non-commercial uses. Selling,
 * giving away or letting of the execution of the library is prohibited.
 * The library can be distributed as part of your applications and libraries
 * for execution provided this comment remains unchanged.
 * <p>
 * Restrictions
 * Only to be distributed with programs that add significant and primary
 * functionality to the library. Not to be distributed with additional
 * software intended to replace any components of the library.
 * <p>
 * Trademarks
 * Jekejeke is a registered trademark of XLOG Technologies AG.
 */
public class Unicode {

    /**
     * Compress and print.
     */
    public static void main(String[] args) throws IOException {
        long ts = System.currentTimeMillis();
        Compress.compress();

        Writer wr;
        if (args.length > 0) {
            wr = new FileWriter(args[0], StandardCharsets.UTF_8);
        } else {
            wr = new OutputStreamWriter(System.out, StandardCharsets.UTF_8);
        }
        Compress.statistics(ts, wr);
        dump(wr);
        wr.flush();
        if (args.length > 0)
            wr.close();
    }

    /**
     * Print the two pools and the entry point.
     */
    private static void dump(Writer wr) throws IOException {
        wr.write("const pool = [");
        for (int i = 0; i < Compress.pool.size(); i++) {
            if (i != 0) {
                wr.write(",\n");
                wr.write("    ");
            }
            Compress.show(Compress.pool.get(i), wr);
        }
        wr.write("];\n");
        wr.write("const pool2 = [");
        for (int i = 0; i < Compress.pool2.size(); i++) {
            if (i != 0) {
                wr.write(",\n");
                wr.write("    ");
            }
            Compress.show(Compress.pool2.get(i), wr);
        }
        wr.write("];\n");
        wr.write("const buf3 = ");
        Compress.show(Compress.buf3.toString(), wr);
        wr.write(";\n");
        wr.write("\n");
        wr.write("function code_property(ch) {\n");
        wr.write("    return pool[pool2[buf3[ch>>" +
                (Compress.PARA_BITS + Compress.BLOCK_BITS) + "]][(ch>>" +
                Compress.PARA_BITS + ")&0x" +
                Integer.toHexString(Compress.BLOCK_SIZE - 1).toUpperCase() + "]][ch&0x" +
                Integer.toHexString(Compress.PARA_SIZE - 1).toUpperCase() + "];\n");
        wr.write("}\n");

        wr.write("export function code_category(ch) {\n");
        wr.write("    return code_property(ch) & 0x1F;\n");
        wr.write("}\n");

        wr.write("export function code_numeric(ch) {\n");
        wr.write("    return (code_property(ch) >> 5) - 1;\n");
        wr.write("}\n");
    }

}