/*
 *******************************************************************************
 * Copyright (C) 1996-2010, 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
     */
    public Object clone(){
        try {
          return super.clone();
        } catch (CloneNotSupportedException e) {
            return null; // never invoked
        }
    }
    
    /**
     * Returns the current UTF16 character.
     * @return current UTF16 character
     */
    public int current(){
        if (currentIndex < replaceable.length()) {
            return replaceable.charAt(currentIndex);
        }
        return DONE;
    }
    
    /**
     * Returns the current codepoint
     * @return current codepoint
     */
    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 UCharacterProperty.getRawSupplementary(
                                                         (char)ch,(char)ch2
                                                             );
            }
        }
        return ch;
    }
    
    /**
     * Returns the length of the text
     * @return length of the text
     */
    public int getLength(){
        return replaceable.length();
    }
    
    /**
     * Gets the current currentIndex in text.
     * @return current currentIndex in text.
     */
    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.
     */
    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.
     */
    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.
     */
    public void setIndex(int currentIndex) throws IndexOutOfBoundsException{
        if (currentIndex < 0 || currentIndex > replaceable.length()) {
            throw new IndexOutOfBoundsException();
        }
        this.currentIndex = currentIndex;
    }
    
    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;

}
