// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 1996-2015, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */
package com.ibm.icu.impl;

import com.ibm.icu.text.Replaceable;
import com.ibm.icu.text.ReplaceableString;
import com.ibm.icu.text.UCharacterIterator;
import com.ibm.icu.text.UTF16;

/**
 * DLF docs must define behavior when Replaceable is mutated underneath
 * the iterator.
 *
 * This and ICUCharacterIterator share some code, maybe they should share
 * an implementation, or the common state and implementation should be
 * moved up into UCharacterIterator.
 *
 * What are first, last, and getBeginIndex doing here?!?!?!
 */
public class ReplaceableUCharacterIterator extends UCharacterIterator {

    // public constructor ------------------------------------------------------

    /**
     * Public constructor
     * @param replaceable text which the iterator will be based on
     */
    public ReplaceableUCharacterIterator(Replaceable replaceable){
        if(replaceable==null){
            throw new IllegalArgumentException();
        }
        this.replaceable  = replaceable;
        this.currentIndex = 0;
    }

    /**
     * Public constructor
     * @param str text which the iterator will be based on
     */
    public ReplaceableUCharacterIterator(String str){
        if(str==null){
            throw new IllegalArgumentException();
        }
        this.replaceable  = new ReplaceableString(str);
        this.currentIndex = 0;
    }

    /**
     * Public constructor
     * @param buf buffer of text on which the iterator will be based
     */
    public ReplaceableUCharacterIterator(StringBuffer buf){
        if(buf==null){
            throw new IllegalArgumentException();
        }
        this.replaceable  = new ReplaceableString(buf);
        this.currentIndex = 0;
    }

    // public methods ----------------------------------------------------------

    /**
     * Creates a copy of this iterator, does not clone the underlying
     * <code>Replaceable</code>object
     * @return copy of this iterator
     */
    @Override
    public Object clone(){
        try {
          return super.clone();
        } catch (CloneNotSupportedException e) {
            return null; // never invoked
        }
    }

    /**
     * Returns the current UTF16 character.
     * @return current UTF16 character
     */
    @Override
    public int current(){
        if (currentIndex < replaceable.length()) {
            return replaceable.charAt(currentIndex);
        }
        return DONE;
    }

    /**
     * Returns the current codepoint
     * @return current codepoint
     */
    @Override
    public int currentCodePoint(){
        // cannot use charAt due to it different
        // behaviour when index is pointing at a
        // trail surrogate, check for surrogates

        int ch = current();
        if(UTF16.isLeadSurrogate((char)ch)){
            // advance the index to get the next code point
            next();
            // due to post increment semantics current() after next()
            // actually returns the next char which is what we want
            int ch2 = current();
            // current should never change the current index so back off
            previous();

            if(UTF16.isTrailSurrogate((char)ch2)){
                // we found a surrogate pair
                return Character.toCodePoint((char)ch, (char)ch2);
            }
        }
        return ch;
    }

    /**
     * Returns the length of the text
     * @return length of the text
     */
    @Override
    public int getLength(){
        return replaceable.length();
    }

    /**
     * Gets the current currentIndex in text.
     * @return current currentIndex in text.
     */
    @Override
    public int getIndex(){
        return currentIndex;
    }

    /**
     * Returns next UTF16 character and increments the iterator's currentIndex by 1.
     * If the resulting currentIndex is greater or equal to the text length, the
     * currentIndex is reset to the text length and a value of DONECODEPOINT is
     * returned.
     * @return next UTF16 character in text or DONE if the new currentIndex is off the
     *         end of the text range.
     */
    @Override
    public int next(){
        if (currentIndex < replaceable.length()) {
            return replaceable.charAt(currentIndex++);
        }
        return DONE;
    }


    /**
     * Returns previous UTF16 character and decrements the iterator's currentIndex by
     * 1.
     * If the resulting currentIndex is less than 0, the currentIndex is reset to 0 and a
     * value of DONECODEPOINT is returned.
     * @return next UTF16 character in text or DONE if the new currentIndex is off the
     *         start of the text range.
     */
    @Override
    public int previous(){
        if (currentIndex > 0) {
            return replaceable.charAt(--currentIndex);
        }
        return DONE;
    }

    /**
     * <p>Sets the currentIndex to the specified currentIndex in the text and returns that
     * single UTF16 character at currentIndex.
     * This assumes the text is stored as 16-bit code units.</p>
     * @param currentIndex the currentIndex within the text.
     * @exception IllegalArgumentException is thrown if an invalid currentIndex is
     *            supplied. i.e. currentIndex is out of bounds.
     * @returns the character at the specified currentIndex or DONE if the specified
     *         currentIndex is equal to the end of the text.
     */
    @Override
    public void setIndex(int currentIndex) throws IndexOutOfBoundsException{
        if (currentIndex < 0 || currentIndex > replaceable.length()) {
            throw new IndexOutOfBoundsException();
        }
        this.currentIndex = currentIndex;
    }

    @Override
    public int getText(char[] fillIn, int offset){
        int length = replaceable.length();
        if(offset < 0 || offset + length > fillIn.length){
            throw new IndexOutOfBoundsException(Integer.toString(length));
        }
        replaceable.getChars(0,length,fillIn,offset);
        return length;
    }

    // private data members ----------------------------------------------------

    /**
     * Replacable object
     */
    private Replaceable replaceable;
    /**
     * Current currentIndex
     */
    private int currentIndex;

}
