/*
 *******************************************************************************
 * Copyright (C) 1996-2015, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */
package com.ibm.icu.text;


import java.text.CharacterIterator;

import com.ibm.icu.impl.CharacterIteratorWrapper;
import com.ibm.icu.impl.ReplaceableUCharacterIterator;
import com.ibm.icu.impl.UCharArrayIterator;
import com.ibm.icu.impl.UCharacterIteratorWrapper;


/**
 * Abstract class that defines an API for iteration on text objects.This is an 
 * interface for forward and backward iteration and random access into a text 
 * object. Forward iteration is done with post-increment and backward iteration 
 * is done with pre-decrement semantics, while the 
 * <code>java.text.CharacterIterator</code> interface methods provided forward 
 * iteration with "pre-increment" and backward iteration with pre-decrement 
 * semantics. This API is more efficient for forward iteration over code points.
 * The other major difference is that this API can do both code unit and code point 
 * iteration, <code>java.text.CharacterIterator</code> can only iterate over 
 * code units and is limited to BMP (0 - 0xFFFF)
 * @author Ram
 * @stable ICU 2.4
 */
public abstract class UCharacterIterator 
                      implements Cloneable,UForwardCharacterIterator {

    /**
     * Protected default constructor for the subclasses
     * @stable ICU 2.4
     */
    protected UCharacterIterator(){
    }
    
    // static final methods ----------------------------------------------------
    
    /**
     * Returns a <code>UCharacterIterator</code> object given a 
     * <code>Replaceable</code> object.
     * @param source a valid source as a <code>Replaceable</code> object
     * @return UCharacterIterator object
     * @exception IllegalArgumentException if the argument is null
     * @stable ICU 2.4
     */
    public static final UCharacterIterator getInstance(Replaceable source){
        return new ReplaceableUCharacterIterator(source);
    }
    
    /**
     * Returns a <code>UCharacterIterator</code> object given a 
     * source string.
     * @param source a string
     * @return UCharacterIterator object
     * @exception IllegalArgumentException if the argument is null
     * @stable ICU 2.4
     */
    public static final UCharacterIterator getInstance(String source){
        return new ReplaceableUCharacterIterator(source);
    }
    
    /**
     * Returns a <code>UCharacterIterator</code> object given a 
     * source character array.
     * @param source an array of UTF-16 code units
     * @return UCharacterIterator object
     * @exception IllegalArgumentException if the argument is null
     * @stable ICU 2.4
     */
    public static final UCharacterIterator getInstance(char[] source){
        return getInstance(source,0,source.length);
    }
    
    /**
     * Returns a <code>UCharacterIterator</code> object given a 
     * source character array.
     * @param source an array of UTF-16 code units
     * @return UCharacterIterator object
     * @exception IllegalArgumentException if the argument is null
     * @stable ICU 2.4
     */
    public static final UCharacterIterator getInstance(char[] source, int start, int limit){
        return new UCharArrayIterator(source,start,limit);
    }
    /**
     * Returns a <code>UCharacterIterator</code> object given a 
     * source StringBuffer.
     * @param source an string buffer of UTF-16 code units
     * @return UCharacterIterator object
     * @exception IllegalArgumentException if the argument is null
     * @stable ICU 2.4
     */
    public static final UCharacterIterator getInstance(StringBuffer source){
        return new ReplaceableUCharacterIterator(source);
    }

    /**
     * Returns a <code>UCharacterIterator</code> object given a 
     * CharacterIterator.
     * @param source a valid CharacterIterator object.
     * @return UCharacterIterator object
     * @exception IllegalArgumentException if the argument is null
     * @stable ICU 2.4
     */    
    public static final UCharacterIterator getInstance(CharacterIterator source){
        return new CharacterIteratorWrapper(source);
    }
       
    // public methods ----------------------------------------------------------
    /**
     * Returns a <code>java.text.CharacterIterator</code> object for
     * the underlying text of this iterator.  The returned iterator is
     * independent of this iterator.
     * @return java.text.CharacterIterator object
     * @stable ICU 2.4 
     */
    public CharacterIterator getCharacterIterator(){
        return new UCharacterIteratorWrapper(this);
    }    
   
    /**
     * Returns the code unit at the current index.  If index is out
     * of range, returns DONE.  Index is not changed.
     * @return current code unit
     * @stable ICU 2.4
     */
    public abstract int current();
    
    /**
     * Returns the codepoint at the current index.
     * If the current index is invalid, DONE is returned.
     * If the current index points to a lead surrogate, and there is a following
     * trail surrogate, then the code point is returned.  Otherwise, the code
     * unit at index is returned.  Index is not changed. 
     * @return current codepoint
     * @stable ICU 2.4
     */
    public int currentCodePoint(){
        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 char 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 the codepoint
                return Character.toCodePoint((char)ch, (char)ch2);
            }
        }
        return ch;
    }
    
    /**
     * Returns the length of the text
     * @return length of the text
     * @stable ICU 2.4
     */
    public abstract int getLength();

    
    /**
     * Gets the current index in text.
     * @return current index in text.
     * @stable ICU 2.4
     */
    public abstract int getIndex();


    /**
     * Returns the UTF16 code unit at index, and increments to the next
     * code unit (post-increment semantics).  If index is out of
     * range, DONE is returned, and the iterator is reset to the limit
     * of the text.
     * @return the next UTF16 code unit, or DONE if the index is at the limit
     *         of the text.
     * @stable ICU 2.4  
     */
    public abstract int next();

    /**
     * Returns the code point at index, and increments to the next code
     * point (post-increment semantics).  If index does not point to a
     * valid surrogate pair, the behavior is the same as
     * <code>next()</code>.  Otherwise the iterator is incremented past
     * the surrogate pair, and the code point represented by the pair
     * is returned.
     * @return the next codepoint in text, or DONE if the index is at
     *         the limit of the text.
     * @stable ICU 2.4  
     */
    public int nextCodePoint(){
        int ch1 = next();
        if(UTF16.isLeadSurrogate((char)ch1)){
            int ch2 = next();
            if(UTF16.isTrailSurrogate((char)ch2)){
                return Character.toCodePoint((char)ch1, (char)ch2);
            }else if (ch2 != DONE) {
                // unmatched surrogate so back out
                previous();
            }
        }
        return ch1;
    }

    /**
     * Decrement to the position of the previous code unit in the
     * text, and return it (pre-decrement semantics).  If the
     * resulting index is less than 0, the index is reset to 0 and
     * DONE is returned.
     * @return the previous code unit in the text, or DONE if the new
     *         index is before the start of the text.
     * @stable ICU 2.4  
     */
    public abstract int previous();

    
    /**
     * Retreat to the start of the previous code point in the text,
     * and return it (pre-decrement semantics).  If the index is not
     * preceeded by a valid surrogate pair, the behavior is the same
     * as <code>previous()</code>.  Otherwise the iterator is
     * decremented to the start of the surrogate pair, and the code
     * point represented by the pair is returned.
     * @return the previous code point in the text, or DONE if the new
     *         index is before the start of the text.
     * @stable ICU 2.4  
     */
    public int previousCodePoint(){
        int ch1 = previous();
        if(UTF16.isTrailSurrogate((char)ch1)){
            int ch2 = previous();
            if(UTF16.isLeadSurrogate((char)ch2)){
                return Character.toCodePoint((char)ch2, (char)ch1);
            }else if (ch2 != DONE) {
                //unmatched trail surrogate so back out
                next();
            }   
        }
        return ch1;
    }

    /**
     * Sets the index to the specified index in the text.
     * @param index the index within the text. 
     * @exception IndexOutOfBoundsException is thrown if an invalid index is 
     *            supplied
     * @stable ICU 2.4
     */
    public abstract void setIndex(int index);

    /**
     * Sets the current index to the limit.
     * @stable ICU 2.4
     */
    public void setToLimit() {
        setIndex(getLength());
    }
    
    /**
     * Sets the current index to the start.
     * @stable ICU 2.4
     */
    public void setToStart() {
        setIndex(0);
    }

    /**
     * Fills the buffer with the underlying text storage of the iterator
     * If the buffer capacity is not enough a exception is thrown. The capacity
     * of the fill in buffer should at least be equal to length of text in the 
     * iterator obtained by calling <code>getLength()</code>).
     * <b>Usage:</b>
     * 
     * <code>
     * <pre>
     *         UChacterIterator iter = new UCharacterIterator.getInstance(text);
     *         char[] buf = new char[iter.getLength()];
     *         iter.getText(buf);
     *         
     *         OR
     *         char[] buf= new char[1];
     *         int len = 0;
     *         for(;;){
     *             try{
     *                 len = iter.getText(buf);
     *                 break;
     *             }catch(IndexOutOfBoundsException e){
     *                 buf = new char[iter.getLength()];
     *             }
     *         }
     * </pre>
     * </code>
     *             
     * @param fillIn an array of chars to fill with the underlying UTF-16 code 
     *         units.
     * @param offset the position within the array to start putting the data.
     * @return the number of code units added to fillIn, as a convenience
     * @exception IndexOutOfBoundsException exception if there is not enough
     *            room after offset in the array, or if offset < 0.
     * @stable ICU 2.4  
     */
    public abstract int getText(char[] fillIn, int offset); 

    /**
     * Convenience override for <code>getText(char[], int)</code> that provides
     * an offset of 0.
     * @param fillIn an array of chars to fill with the underlying UTF-16 code 
     *         units.
     * @return the number of code units added to fillIn, as a convenience
     * @exception IndexOutOfBoundsException exception if there is not enough
     *            room in the array.
     * @stable ICU 2.4  
     */
    public final int getText(char[] fillIn) {
        return getText(fillIn, 0);
    }
         
    /**
     * Convenience method for returning the underlying text storage as as string
     * @return the underlying text storage in the iterator as a string
     * @stable ICU 2.4
     */
    public String getText() {
        char[] text = new char[getLength()];
        getText(text);
        return new String(text);
    }
       
    /**
     * Moves the current position by the number of code units
     * specified, either forward or backward depending on the sign
     * of delta (positive or negative respectively).  If the resulting
     * index would be less than zero, the index is set to zero, and if
     * the resulting index would be greater than limit, the index is
     * set to limit.
     *
     * @param delta the number of code units to move the current
     *              index.
     * @return the new index.
     * @exception IndexOutOfBoundsException is thrown if an invalid index is 
     *            supplied 
     * @stable ICU 2.4 
     * 
     */
    public int moveIndex(int delta) {
        int x = Math.max(0, Math.min(getIndex() + delta, getLength()));
        setIndex(x);
        return x;
    }

    /**
     * Moves the current position by the number of code points
     * specified, either forward or backward depending on the sign of
     * delta (positive or negative respectively). If the current index
     * is at a trail surrogate then the first adjustment is by code
     * unit, and the remaining adjustments are by code points.  If the
     * resulting index would be less than zero, the index is set to
     * zero, and if the resulting index would be greater than limit,
     * the index is set to limit.
     * @param delta the number of code units to move the current index.
     * @return the new index  
     * @exception IndexOutOfBoundsException is thrown if an invalid delta is 
     *            supplied
     * @stable ICU 2.4
     */
    public int moveCodePointIndex(int delta){
        if(delta>0){
            while(delta>0 && nextCodePoint() != DONE){delta--;}
        }else{
            while(delta<0 && previousCodePoint() != DONE){delta++;}
        }
        if(delta!=0){
            throw new IndexOutOfBoundsException();
        }
          
        return getIndex();
    }

    /**
     * Creates a copy of this iterator, independent from other iterators.
     * If it is not possible to clone the iterator, returns null.
     * @return copy of this iterator
     * @stable ICU 2.4
     */
    public Object clone() throws CloneNotSupportedException{
        return super.clone();
    }   
    
}

