// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/**
 *******************************************************************************
 * Copyright (C) 2001-2010, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.demo.translit;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

import com.ibm.icu.lang.UScript;
import com.ibm.icu.text.Replaceable;
import com.ibm.icu.text.Transliterator;
import com.ibm.icu.text.UTF16;
import com.ibm.icu.text.UnicodeFilter;

public class AnyTransliterator extends Transliterator {
    
    static final boolean DEBUG = false;
    private String targetName;
    private RunIterator it;
    private Position run;
    
    
    public AnyTransliterator(String targetName, UnicodeFilter filter, RunIterator it){
        super("Any-" + targetName, filter);
        this.targetName = targetName;
        this.it = it;
        run = new Position();
    }
    
    public AnyTransliterator(String targetName, UnicodeFilter filter){
        this(targetName, filter, new ScriptRunIterator());
    }
    
    static private Transliterator hex = Transliterator.getInstance("[^\\u0020-\\u007E] hex");
    
    protected void handleTransliterate(Replaceable text,
                                       Position offsets, boolean isIncremental) {
        if (DEBUG) {
            System.out.println("- handleTransliterate " + hex.transliterate(text.toString())
                + ", " + toString(offsets));
        }
        it.reset(text, offsets);
        
        while (it.next(run)) {
            if (targetName.equalsIgnoreCase(it.getName())) {
                if (DEBUG) System.out.println("Skipping identical: " + targetName);
                run.start = run.limit; // show we processed
                continue; // skip if same
            }
            
            Transliterator t;
            String id = it.getName() + '-' + targetName;
            try {
                t = Transliterator.getInstance(id);
            } catch (IllegalArgumentException ex) {
                if (DEBUG) System.out.println("Couldn't find: " + id + ", Trying Latin as Pivot");
                id = it.getName() + "-Latin; Latin-" + targetName;
                try {
                    t = Transliterator.getInstance(id);
                } catch (IllegalArgumentException ex2) {
                    if (DEBUG) System.out.println("Couldn't find: " + id);
                    continue;
                }
            }
            // TODO catch error later!!
                
            if (DEBUG) {
                System.out.println(t.getID());
                System.out.println("input: " + hex.transliterate(text.toString())
                 + ", " + toString(run));
            }
            
            if (isIncremental && it.atEnd()) {
                t.transliterate(text, run);
            } else {
                t.finishTransliteration(text, run);
            }
            // adjust the offsets in line with the changes
            it.adjust(run.limit);
            
            if (DEBUG) {
                System.out.println("output: " + hex.transliterate(text.toString())
                 + ", " + toString(run));
            }
        }

        // show how far we got!
        it.getExpanse(offsets);
        if (run.start == run.limit) offsets.start = offsets.limit;
        else offsets.start = run.start;
        if (DEBUG) {
            System.out.println("+ handleTransliterate: " + ", " + toString(offsets));
            System.out.println();
        }
    }
    
    // should be method on Position
    public static String toString(Position offsets) {
        return "[cs: " + offsets.contextStart
                + ", s: " + offsets.start
                + ", l: " + offsets.limit
                + ", cl: " + offsets.contextLimit
                + "]";
    }
    
    public interface RunIterator {
        public void reset(Replaceable text, Position expanse);
        public void getExpanse(Position run);
        public void reset();
        public boolean next(Position run);
        public void getCurrent(Position run);
        public String getName();
        public void adjust(int newCurrentLimit);
        public boolean atEnd();
    }
    
    /**
     * Returns a series of ranges corresponding to scripts. They will be of the form:
     * ccccSScSSccccTTcTcccc    - where c is common, S is the first script and T is the second
     *|            |            - first run
     *         |            |    - second run
     * That is, the runs will overlap. The reason for this is so that a transliterator can
     * consider common characters both before and after the scripts.
     * The only time that contextStart != start is for the first run 
     *    (the context is the start context of the entire expanse)
     * The only time that contextLimit != limit is for the last run 
     *    (the context is the end context of the entire expanse)
     */
    public static class ScriptRunIterator implements RunIterator {
        private Replaceable text;
        private Position expanse = new Position();
        private Position current = new Position();
        private int script;
        private boolean done = true;
        

        public void reset(Replaceable repText, Position expansePos) {
            set(this.expanse, expansePos);
            this.text = repText;
            reset();
        }
            
        public void reset() {
            done = false;
            //this.expanse = expanse;
            script = UScript.INVALID_CODE;
            // set up first range to be empty, at beginning
            current.contextStart = expanse.contextStart;
            current.start = current.limit = current.contextLimit = expanse.start;            
        }
            
        public boolean next(Position run) {
            if (done) return false;
            if (DEBUG) {
                System.out.println("+cs: " + current.contextStart
                    + ", s: " + current.start
                    + ", l: " + current.limit
                    + ", cl: " + current.contextLimit);
            }
            // reset start context run to the last end
            current.start = current.limit;
            
            // Phase 1. Backup the START value through COMMON until we get to expanse.start or a real script.
            int i, cp;
            int limit = expanse.start;
            for (i = current.start; i > limit; i -= UTF16.getCharCount(cp)) {
                cp = text.char32At(i);
                int scrpt = UScript.getScript(cp);
                if (scrpt != UScript.COMMON && scrpt != UScript.INHERITED) break;
            }
            current.start = i;
            current.contextStart = (i == limit) ? expanse.contextStart : i; // extend at start
            
            // PHASE 2. Move up the LIMIT value through COMMON or single script until we get to expanse.limit
            int lastScript = UScript.COMMON;
            //int veryLastScript = UScript.COMMON;
            limit = expanse.limit; 
            for (i = current.limit; i < limit; i += UTF16.getCharCount(cp)) {
                cp = text.char32At(i);
                int scrpt = UScript.getScript(cp);
                if (scrpt == UScript.INHERITED) scrpt = UScript.COMMON;
                if (scrpt != UScript.COMMON) {
                    // if we find a real script:
                    //   if we already had a script, bail
                    //   otherwise set our script
                    if (lastScript == UScript.COMMON) lastScript = scrpt;
                    else if (lastScript != scrpt) break;
                }
            }
            current.limit = i;
            current.contextLimit = (i == limit) ? expanse.contextLimit : i; // extend at end
            done = (i == limit);
            script = lastScript;
            
            if (DEBUG) {
                System.out.println("-cs: " + current.contextStart
                    + ", s: " + current.start
                    + ", l: " + current.limit
                    + ", cl: " + current.contextLimit);
            }
            
            set(run, current);
            return true;
        }
        
        // SHOULD BE METHOD ON POSITION
        public static void set(Position run, Position current) {
            run.contextStart = current.contextStart;
            run.start = current.start;
            run.limit = current.limit;
            run.contextLimit = current.contextLimit;
        }
        
        public boolean atEnd() {
            return current.limit == expanse.limit;
        }
        
        public void getCurrent(Position run) {
            set(run, current);
        }
        
        public void getExpanse(Position run) {
            set(run, expanse);
        }
        
        public String getName() {
            return UScript.getName(script);
        }
        
        public void adjust(int newCurrentLimit) {
            if (expanse == null) {
                throw new IllegalArgumentException("Must reset() before calling");
            }
            int delta = newCurrentLimit - current.limit;
            current.limit += delta;
            current.contextLimit += delta;
            expanse.limit += delta;
            expanse.contextLimit += delta;
        }
        
        // register Any-Script for every script.
        
        private static Set scriptList = new HashSet();
        
        public static void registerAnyToScript() {
            synchronized (scriptList) {
                Enumeration sources = Transliterator.getAvailableSources();
                while(sources.hasMoreElements()) {
                    String source = (String) sources.nextElement();
                    if (source.equals("Any")) continue; // to keep from looping
                    
                    Enumeration targets = Transliterator.getAvailableTargets(source);
                    while(targets.hasMoreElements()) {
                        String target = (String) targets.nextElement();
                        if (UScript.getCode(target) == null) continue; // SKIP unless we have a script (or locale)
                        if (scriptList.contains(target)) continue; // already encountered
                        scriptList.add(target); // otherwise add for later testing
                        
                        Set variantSet = add(new TreeSet(), Transliterator.getAvailableVariants(source, target));
                        if (variantSet.size() < 2) {
                            AnyTransliterator at = new AnyTransliterator(target, null);
                            DummyFactory.add(at.getID(), at);
                        } else {
                            Iterator variants = variantSet.iterator();
                            while(variants.hasNext()) {
                                String variant = (String) variants.next();
                                AnyTransliterator at = new AnyTransliterator(
                                    (variant.length() > 0) ? target + "/" + variant : target, null);
                                DummyFactory.add(at.getID(), at);
                            }
                        }
                    }
                }
            }
        }
        
        static class DummyFactory implements Transliterator.Factory {
            static DummyFactory singleton = new DummyFactory();
            static HashMap m = new HashMap();

            // Since Transliterators are immutable, we don't have to clone on set & get
            static void add(String ID, Transliterator t) {
                m.put(ID, t);
                System.out.println("Registering: " + ID + ", " + t.toRules(true));
                Transliterator.registerFactory(ID, singleton);
            }
            public Transliterator getInstance(String ID) {
                return (Transliterator) m.get(ID);
            }
        }
        
        // Nice little Utility for converting Enumeration to collection
        static Set add(Set s, Enumeration enumeration) {
            while(enumeration.hasMoreElements()) {
                s.add(enumeration.nextElement());
            }
            return s;
        }
        
        
    }
}
