/* GENERATED SOURCE. DO NOT MODIFY. */
/*
 *******************************************************************************
 * Copyright (C) 2014-2016, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */
package android.icu.impl;

import java.text.CharacterIterator;
import java.util.HashSet;

import android.icu.text.BreakIterator;
import android.icu.text.FilteredBreakIteratorBuilder;
import android.icu.text.UCharacterIterator;
import android.icu.util.BytesTrie;
import android.icu.util.CharsTrie;
import android.icu.util.CharsTrieBuilder;
import android.icu.util.StringTrieBuilder;
import android.icu.util.ULocale;
import android.icu.util.UResourceBundle;

/**
 * @author tomzhang
 * @hide Only a subset of ICU is exposed in Android
 */
public class SimpleFilteredSentenceBreakIterator extends BreakIterator {

    private BreakIterator delegate;
    private UCharacterIterator text; // TODO(Tom): suffice to move into the local scope in next() ?
    private CharsTrie backwardsTrie; // i.e. ".srM" for Mrs.
    private CharsTrie forwardsPartialTrie; // Has ".a" for "a.M."

    /**
     * @param adoptBreakIterator
     *            break iterator to adopt
     * @param forwardsPartialTrie
     *            forward & partial char trie to adopt
     * @param backwardsTrie
     *            backward trie to adopt
     */
    public SimpleFilteredSentenceBreakIterator(BreakIterator adoptBreakIterator, CharsTrie forwardsPartialTrie,
            CharsTrie backwardsTrie) {
        this.delegate = adoptBreakIterator;
        this.forwardsPartialTrie = forwardsPartialTrie;
        this.backwardsTrie = backwardsTrie;
    }

    @Override
    public int next() {
        int n = delegate.next();
        if (n == BreakIterator.DONE || // at end or
                backwardsTrie == null) { // .. no backwards table loaded == no exceptions
            return n;
        }
        // UCharacterIterator text;
        text = UCharacterIterator.getInstance((CharacterIterator) delegate.getText().clone());
        do { // outer loop runs once per underlying break (from fDelegate).
             // loops while 'n' points to an exception.
            text.setIndex(n);
            backwardsTrie.reset();
            int uch;

            // Assume a space is following the '.' (so we handle the case: "Mr. /Brown")
            if ((uch = text.previousCodePoint()) == ' ') { // TODO: skip a class of chars here??
                // TODO only do this the 1st time?
            } else {
                uch = text.nextCodePoint();
            }

            BytesTrie.Result r = BytesTrie.Result.INTERMEDIATE_VALUE;

            int bestPosn = -1;
            int bestValue = -1;

            while ((uch = text.previousCodePoint()) != BreakIterator.DONE && // more to consume backwards and..
                    ((r = backwardsTrie.nextForCodePoint(uch)).hasNext())) {// more in the trie
                if (r.hasValue()) { // remember the best match so far
                    bestPosn = text.getIndex();
                    bestValue = backwardsTrie.getValue();
                }
            }

            if (r.matches()) { // exact match?
                bestValue = backwardsTrie.getValue();
                bestPosn = text.getIndex();
            }

            if (bestPosn >= 0) {
                if (bestValue == Builder.MATCH) { // exact match!
                    n = delegate.next(); // skip this one. Find the next lowerlevel break.
                    if (n == BreakIterator.DONE)
                        return n;
                    continue; // See if the next is another exception.
                } else if (bestValue == Builder.PARTIAL && forwardsPartialTrie != null) {
                    // make sure there's a forward trie
                    // We matched the "Ph." in "Ph.D." - now we need to run everything through the forwards trie
                    // to see if it matches something going forward.
                    forwardsPartialTrie.reset();

                    BytesTrie.Result rfwd = BytesTrie.Result.INTERMEDIATE_VALUE;
                    text.setIndex(bestPosn); // hope that's close ..
                    while ((uch = text.nextCodePoint()) != BreakIterator.DONE
                            && ((rfwd = forwardsPartialTrie.nextForCodePoint(uch)).hasNext())) {
                    }
                    if (rfwd.matches()) {
                        // only full matches here, nothing to check
                        // skip the next:
                        n = delegate.next();
                        if (n == BreakIterator.DONE)
                            return n;
                        continue;
                    } else {
                        // no match (no exception) -return the 'underlying' break
                        return n;
                    }
                } else {
                    return n; // internal error and/or no forwards trie
                }
            } else {
                return n; // No match - so exit. Not an exception.
            }
        } while (n != BreakIterator.DONE);
        return n;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null)
            return false;
        if (this == obj)
            return true;
        if (getClass() != obj.getClass())
            return false;
        SimpleFilteredSentenceBreakIterator other = (SimpleFilteredSentenceBreakIterator) obj;
        return delegate.equals(other.delegate) && text.equals(other.text) && backwardsTrie.equals(other.backwardsTrie)
                && forwardsPartialTrie.equals(other.forwardsPartialTrie);
    }

    @Override
    public int hashCode() {
        return (forwardsPartialTrie.hashCode() * 39) + (backwardsTrie.hashCode() * 11) + delegate.hashCode();
    }

    @Override
    public Object clone() {
        SimpleFilteredSentenceBreakIterator other = (SimpleFilteredSentenceBreakIterator) super.clone();
        return other;
    }

    @Override
    public int first() {
        return delegate.first();
    }

    @Override
    public int last() {
        return delegate.last();
    }

    @Override
    public int next(int n) {
        // TODO
        throw new UnsupportedOperationException("next(int) is not yet implemented");
    }

    @Override
    public int previous() {
        // TODO
        throw new UnsupportedOperationException("previous() is not yet implemented");
    }

    @Override
    public int following(int offset) {
        // TODO
        throw new UnsupportedOperationException("following(int) is not yet implemented");
    }

    @Override
    public int current() {
        return delegate.current();
    }

    @Override
    public int preceding(int offset) {
        // TODO
        throw new UnsupportedOperationException("preceding(int) is not yet implemented");
    }

    @Override
    public CharacterIterator getText() {
        return delegate.getText();
    }

    @Override
    public void setText(CharacterIterator newText) {
        delegate.setText(newText);
    }

    public static class Builder extends FilteredBreakIteratorBuilder {
        /**
         * filter set to store all exceptions
         */
        private HashSet<String> filterSet = new HashSet<String>();

        static final int PARTIAL = (1 << 0); // < partial - need to run through forward trie
        static final int MATCH = (1 << 1); // < exact match - skip this one.
        static final int SuppressInReverse = (1 << 0);
        static final int AddToForward = (1 << 1);

        /**
         * Create SimpleFilteredBreakIteratorBuilder using given locale
         * @param loc the locale to get filtered iterators
         */
        public Builder(ULocale loc) {
            ICUResourceBundle rb = (ICUResourceBundle) UResourceBundle.getBundleInstance(
                    ICUResourceBundle.ICU_BRKITR_BASE_NAME, loc);
            ICUResourceBundle exceptions = rb.findWithFallback("exceptions");
            if (exceptions != null) {
                ICUResourceBundle breaks = exceptions.findWithFallback("SentenceBreak");
    
                if (breaks != null) {
                    for (int index = 0, size = breaks.getSize(); index < size; ++index) {
                        ICUResourceBundle b = (ICUResourceBundle) breaks.get(index);
                        String br = b.getString();
                        filterSet.add(br);
                    }
                }
            } // else - no exceptions.
        }

        /**
         * Create SimpleFilteredBreakIteratorBuilder with no exception
         */
        public Builder() {
            filterSet = new HashSet<String>();
        }

        @Override
        public boolean suppressBreakAfter(String str) {
            if (filterSet == null) {
                filterSet = new HashSet<String>();
            }
            return filterSet.add(str);
        }

        @Override
        public boolean unsuppressBreakAfter(String str) {
            if (filterSet == null) {
                return false;
            } else {
                return filterSet.remove(str);
            }
        }

        @Override
        public BreakIterator build(BreakIterator adoptBreakIterator) {
            if( filterSet.isEmpty() ) {
                // Short circuit - nothing to except.
                return adoptBreakIterator;
            }
            
            CharsTrieBuilder builder = new CharsTrieBuilder();
            CharsTrieBuilder builder2 = new CharsTrieBuilder();

            int revCount = 0;
            int fwdCount = 0;

            int subCount = filterSet.size();
            String[] ustrs = new String[subCount];
            int[] partials = new int[subCount];

            CharsTrie backwardsTrie = null; // i.e. ".srM" for Mrs.
            CharsTrie forwardsPartialTrie = null; // Has ".a" for "a.M."

            int i = 0;
            for (String s : filterSet) {
                ustrs[i] = s; // copy by value?
                partials[i] = 0; // default: no partial
                i++;
            }

            for (i = 0; i < subCount; i++) {
                int nn = ustrs[i].indexOf('.'); // TODO: non-'.' abbreviations
                if (nn > -1 && (nn + 1) != ustrs[i].length()) {
                    // is partial.
                    // is it unique?
                    int sameAs = -1;
                    for (int j = 0; j < subCount; j++) {
                        if (j == i)
                            continue;
                        if (ustrs[i].regionMatches(0, ustrs[j], 0, nn + 1)) {
                            if (partials[j] == 0) { // hasn't been processed yet
                                partials[j] = SuppressInReverse | AddToForward;
                            } else if ((partials[j] & SuppressInReverse) != 0) {
                                sameAs = j; // the other entry is already in the reverse table.
                            }
                        }
                    }

                    if ((sameAs == -1) && (partials[i] == 0)) {
                        StringBuilder prefix = new StringBuilder(ustrs[i].substring(0, nn + 1));
                        // first one - add the prefix to the reverse table.
                        prefix.reverse();
                        builder.add(prefix, PARTIAL);
                        revCount++;
                        partials[i] = SuppressInReverse | AddToForward;
                    }
                }
            }

            for (i = 0; i < subCount; i++) {
                if (partials[i] == 0) {
                    StringBuilder reversed = new StringBuilder(ustrs[i]).reverse();
                    builder.add(reversed, MATCH);
                    revCount++;
                } else {
                    // an optimization would be to only add the portion after the '.'
                    // for example, for "Ph.D." we store ".hP" in the reverse table. We could just store "D." in the
                    // forward,
                    // instead of "Ph.D." since we already know the "Ph." part is a match.
                    // would need the trie to be able to hold 0-length strings, though.
                    builder2.add(ustrs[i], MATCH); // forward
                    fwdCount++;
                }
            }

            if (revCount > 0) {
                backwardsTrie = builder.build(StringTrieBuilder.Option.FAST);
            }

            if (fwdCount > 0) {
                forwardsPartialTrie = builder2.build(StringTrieBuilder.Option.FAST);
            }
            return new SimpleFilteredSentenceBreakIterator(adoptBreakIterator, forwardsPartialTrie, backwardsTrie);
        }
    }
}
