/**
 *******************************************************************************
 * Copyright (C) 2001-2003, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/iterator/TestUCharacterIterator.java,v $
 * $Date: 2003/06/03 18:49:29 $
 * $Revision: 1.11 $
 *
 *******************************************************************************
 */
package com.ibm.icu.dev.test.iterator;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.text.UCharacterIterator;
import com.ibm.icu.text.UTF16;
import com.ibm.icu.text.ReplaceableString;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;

/**
 * @author ram
 *
 * To change this generated comment edit the template variable "typecomment":
 * Window>Preferences>Java>Templates.
 * To enable and disable the creation of type comments go to
 * Window>Preferences>Java>Code Generation.
 */
public class TestUCharacterIterator extends TestFmwk{

    // constructor -----------------------------------------------------
  
    /**
     * Constructor
     */
    public TestUCharacterIterator()
    {
    }
  
    // public methods --------------------------------------------------
  
    /**
    * Testing cloning
    */
    public void TestClone() throws CloneNotSupportedException
    {
         UCharacterIterator iterator = UCharacterIterator.getInstance("testing");
         UCharacterIterator cloned = (UCharacterIterator)iterator.clone();
         int completed = 0;
         while (completed != UCharacterIterator.DONE) {
            completed = iterator.next();
            if (completed != cloned.next()) {
                errln("Cloned operation failed");
            }
         }
    }
    public void getText(UCharacterIterator iterator, String result){
        /* test getText */
        char[] buf= new char[1];
		for(;;){
		    try{
		        iterator.getText(buf);
		        break;
		    }catch(IndexOutOfBoundsException e){
		        buf = new char[iterator.getLength()];
		    }
		}
        if(result.compareTo(new String(buf,0,iterator.getLength()))!=0){
            errln("getText failed for iterator");
        }
    }
    
    /**
     * Testing iteration
     */
    public void TestIteration()
    {
        UCharacterIterator iterator  = UCharacterIterator.getInstance(
                                                       ITERATION_STRING_);
        UCharacterIterator iterator2 = UCharacterIterator.getInstance(
                                                       ITERATION_STRING_);
        iterator.setToStart();                                               
        if (iterator.current() != ITERATION_STRING_.charAt(0)) {
            errln("Iterator failed retrieving first character");
        }
        iterator.setToLimit(); 
        if (iterator.previous() != ITERATION_STRING_.charAt(
                                       ITERATION_STRING_.length() - 1)) {
            errln("Iterator failed retrieving last character");
        }                                               
        if (iterator.getLength() != ITERATION_STRING_.length()) {
            errln("Iterator failed determining begin and end index");
        }  
        iterator2.setIndex(0);
        iterator.setIndex(0);
        int ch = 0;
        while (ch != UCharacterIterator.DONE) {
            int index = iterator2.getIndex();
            ch = iterator2.nextCodePoint();
            if (index != ITERATION_SUPPLEMENTARY_INDEX) {
                if (ch != (int)iterator.next() && 
                    ch != UCharacterIterator.DONE) {
                    errln("Error mismatch in next() and nextCodePoint()"); 
                }
            }
            else {
                if (UTF16.getLeadSurrogate(ch) != iterator.next() ||
                    UTF16.getTrailSurrogate(ch) != iterator.next()) {
                    errln("Error mismatch in next and nextCodePoint for " +
                          "supplementary characters");
                }
            }
        }
        iterator.setIndex(ITERATION_STRING_.length());
        iterator2.setIndex(ITERATION_STRING_.length());
        while (ch != UCharacterIterator.DONE) {
            int index = iterator2.getIndex();
            ch = iterator2.previousCodePoint();
            if (index != ITERATION_SUPPLEMENTARY_INDEX) {
                if (ch != (int)iterator.previous() && 
                    ch != UCharacterIterator.DONE) {
                    errln("Error mismatch in previous() and " +
                          "previousCodePoint()"); 
                }
            }
            else {
                if (UTF16.getLeadSurrogate(ch) != iterator.previous() || 
                    UTF16.getTrailSurrogate(ch) != iterator.previous()) {
                    errln("Error mismatch in previous and " +
                          "previousCodePoint for supplementary characters");
                }
            }
        }
    }
    
    public static void main(String[] arg)
    {
        try
        {
            TestUCharacterIterator test = new TestUCharacterIterator();
            test.run(arg);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
    //Tests for new API for utf-16 support 
	public void TestIterationUChar32() {
	    String text="\u0061\u0062\ud841\udc02\u20ac\ud7ff\ud842\udc06\ud801\udc00\u0061";
	    int c;
	    int i;
	    {
	        UCharacterIterator iter = UCharacterIterator.getInstance(text);
	
	        String iterText = iter.getText();
	        if (!iterText.equals(text))
	          errln("iter.getText() failed");
	        
            iter.setIndex(1);
	        if (iter.currentCodePoint() != UTF16.charAt(text,1))
	            errln("Iterator didn't start out in the right place.");
	
	        iter.setToStart();
	        c=iter.currentCodePoint();
            i=0;
	        i=iter.moveCodePointIndex(1);
	        c=iter.currentCodePoint();
	        if(c != UTF16.charAt(text,1) || i!=1)
	            errln("moveCodePointIndex(1) didn't work correctly expected "+ hex(c) +" got "+hex(UTF16.charAt(text,1)) + " i= " + i);
	
	        i=iter.moveCodePointIndex(2);
	        c=iter.currentCodePoint();
	        if(c != UTF16.charAt(text,4) || i!=4)
	            errln("moveCodePointIndex(2) didn't work correctly expected "+ hex(c) +" got "+hex(UTF16.charAt(text,4)) + " i= " + i);
                
	        i=iter.moveCodePointIndex(-2);
	        c=iter.currentCodePoint();
	        if(c != UTF16.charAt(text,1) || i!=1)
                 errln("moveCodePointIndex(-2) didn't work correctly expected "+ hex(c) +" got "+hex(UTF16.charAt(text,1)) + " i= " + i);

	        iter.setToLimit();
	        i=iter.moveCodePointIndex(-2);
	        c=iter.currentCodePoint();
	        if(c != UTF16.charAt(text,(text.length()-3)) || i!=(text.length()-3))
                errln("moveCodePointIndex(-2) didn't work correctly expected "+ hex(c) +" got "+hex(UTF16.charAt(text,(text.length()-3)) ) + " i= " + i);
	        
	        iter.setToStart();
	        c = iter.currentCodePoint();
	        i = 0;
	
	        //testing first32PostInc, nextCodePointPostInc, setTostart
	        i = 0;
	        iter.setToStart();
	        c =iter.next();
            if(c != UTF16.charAt(text,i))
	            errln("first32PostInc failed.  Expected->"+hex(UTF16.charAt(text,i))+" Got-> "+hex(c));
	        if(iter.getIndex() != UTF16.getCharCount(c) + i)
	            errln("getIndex() after first32PostInc() failed");
	
	        iter.setToStart();
	        i=0;
	        if (iter.getIndex() != 0)
	            errln("setToStart failed");
	       
	        logln("Testing forward iteration...");
	        do {
	            if (c != UCharacterIterator.DONE)
	                c = iter.nextCodePoint();
	
	            if(c != UTF16.charAt(text,i))
	                errln("Character mismatch at position "+i+", iterator has "+hex(c)+", string has "+hex(UTF16.charAt(text,i)));
    
	            i+=UTF16.getCharCount(c);
	            if(iter.getIndex() != i)
	                errln("getIndex() aftr nextCodePointPostInc() isn't working right");
                c = iter.currentCodePoint();                   
                if( c!=UCharacterIterator.DONE && c != UTF16.charAt(text,i))
                    errln("current() after nextCodePointPostInc() isn't working right");

	        } while (c!=UCharacterIterator.DONE);
	        c=iter.nextCodePoint();
	        if(c!= UCharacterIterator.DONE)
	            errln("nextCodePointPostInc() didn't return DONE at the beginning");
	
	
	    }
	}  
    
    class UCharIterator {
    
       public UCharIterator(int[] src, int len, int index){
            
            s=src;
            length=len;
            i=index;
       }
    
        public int current() {
            if(i<length) {
                return s[i];
            } else {
                return -1;
            }
        }
    
        public int next() {
            if(i<length) {
                return s[i++];
            } else {
                return -1;
            }
        }
    
        public int previous() {
            if(i>0) {
                return s[--i];
            } else {
                return -1;
            }
        }
    
        public int getIndex() {
            return i;
        }
    
        private int[] s;
        private int length, i;
    };
    // src and expect strings
    private final char src[]={
        UTF16.getLeadSurrogate(0x2f999), UTF16.getTrailSurrogate(0x2f999),
        UTF16.getLeadSurrogate(0x1d15f), UTF16.getTrailSurrogate(0x1d15f),
        0xc4,
        0x1ed0
    };
    public void TestPreviousNext(){
        // iterators
        UCharacterIterator iter1 = UCharacterIterator.getInstance(new ReplaceableString(new String(src)));
        UCharacterIterator iter2 = UCharacterIterator.getInstance(src/*char array*/);
        UCharacterIterator iter3 = UCharacterIterator.getInstance(new StringCharacterIterator(new String(src)));
        UCharacterIterator iter4 = UCharacterIterator.getInstance(new StringBuffer(new String(src)));
        previousNext(iter1);
        previousNext(iter2);
        previousNext(iter3);
        previousNext(iter4);
        getText(iter1,new String(src));
        getText(iter2,new String(src));
        getText(iter3,new String(src));
        /* getCharacterIterator */
        CharacterIterator citer1 = iter1.getCharacterIterator();
        CharacterIterator citer2 = iter2.getCharacterIterator();
        CharacterIterator citer3 = iter3.getCharacterIterator();
        if(citer1.first() !=iter1.current()){
            errln("getCharacterIterator for iter1 failed");
        }
        if(citer2.first() !=iter2.current()){
            errln("getCharacterIterator for iter2 failed");
        }
        if(citer3.first() !=iter3.current()){
            errln("getCharacterIterator for iter3 failed");
        }
        /* Test clone()  && moveIndex()*/
        try{
	        UCharacterIterator clone1 = (UCharacterIterator)iter1.clone();
	        UCharacterIterator clone2 = (UCharacterIterator)iter2.clone();
	        UCharacterIterator clone3 = (UCharacterIterator)iter3.clone();
	        if(clone1.moveIndex(3)!=iter1.moveIndex(3)){
	            errln("moveIndex for iter1 failed");
	        }
	        if(clone2.moveIndex(3)!=iter2.moveIndex(3)){
	            errln("moveIndex for iter2 failed");
	        }
	        if(clone3.moveIndex(3)!=iter3.moveIndex(3)){
	            errln("moveIndex for iter1 failed");
	        }
        }catch (Exception e){
            errln("could not clone the iterator");
        }
    }
    public void previousNext(UCharacterIterator iter) {

        int expect[]={
            0x2f999,
            0x1d15f,
            0xc4,
            0x1ed0
        };
    
        // expected src indexes corresponding to expect indexes
        int expectIndex[]={
            0,0,
            1,1,
            2,
            3,
            4 //needed 
        };
    
        // initial indexes into the src and expect strings
        
        final int SRC_MIDDLE=4;
        final int EXPECT_MIDDLE=2;
        
    
        // movement vector
        // - for previous(), 0 for current(), + for next()
        // not const so that we can terminate it below for the error message
        String moves="0+0+0--0-0-+++0--+++++++0--------";
    
        
        UCharIterator iter32 = new UCharIterator(expect, expect.length, 
                                                     EXPECT_MIDDLE);
    
        int c1, c2;
        char m;
    
        // initially set the indexes into the middle of the strings
        iter.setIndex(SRC_MIDDLE);
    
        // move around and compare the iteration code points with
        // the expected ones
        int movesIndex =0;
        while(movesIndex<moves.length()) {
            m=moves.charAt(movesIndex++);
            if(m=='-') {
                c1=iter.previousCodePoint();
                c2=iter32.previous();
            } else if(m=='0') {
                c1=iter.currentCodePoint();
                c2=iter32.current();
            } else  {// m=='+' 
                c1=iter.nextCodePoint();
                c2=iter32.next();
            }
    
            // compare results
            if(c1!=c2) {
                // copy the moves until the current (m) move, and terminate
                String history = moves.substring(0,movesIndex);
                errln("error: mismatch in Normalizer iteration at "+history+": "
                      +"got c1= " + hex(c1) +" != expected c2= "+ hex(c2));
                break;
            }
    
            // compare indexes
            if(expectIndex[iter.getIndex()]!=iter32.getIndex()) {
                // copy the moves until the current (m) move, and terminate
                String history = moves.substring(0,movesIndex);
                errln("error: index mismatch in Normalizer iteration at "
                      +history+ " : "+ "Normalizer index " +iter.getIndex()
                      +" expected "+ expectIndex[iter32.getIndex()]);
                break;
            }
        }
    }
    public void TestUCharacterIteratorWrapper(){
        String source ="asdfasdfjoiuyoiuy2341235679886765";
        UCharacterIterator it = UCharacterIterator.getInstance(source);
        CharacterIterator wrap_ci = it.getCharacterIterator();
        CharacterIterator ci = new StringCharacterIterator(source);
        wrap_ci.setIndex(10);
        ci.setIndex(10);
        String moves="0+0+0--0-0-+++0--+++++++0--------++++0000----0-";
        int c1, c2;
        char m;
        int movesIndex =0;
        
        while(movesIndex<moves.length()) {
            m=moves.charAt(movesIndex++);
            if(m=='-') {
                c1=wrap_ci.previous();
                c2=ci.previous();
            } else if(m=='0') {
                c1=wrap_ci.current();
                c2=ci.current();
            } else  {// m=='+' 
                c1=wrap_ci.next();
                c2=ci.next();
            }
    
            // compare results
            if(c1!=c2) {
                // copy the moves until the current (m) move, and terminate
                String history = moves.substring(0,movesIndex);
                errln("error: mismatch in Normalizer iteration at "+history+": "
                      +"got c1= " + hex(c1) +" != expected c2= "+ hex(c2));
                break;
            }
    
            // compare indexes
            if(wrap_ci.getIndex()!=ci.getIndex()) {
                // copy the moves until the current (m) move, and terminate
                String history = moves.substring(0,movesIndex);
                errln("error: index mismatch in Normalizer iteration at "
                      +history+ " : "+ "Normalizer index " +wrap_ci.getIndex()
                      +" expected "+ ci.getIndex());
                break;
            }
        }
        if(ci.first()!=wrap_ci.first()){
            errln("CharacterIteratorWrapper.first() failed. expected: " + ci.first() + " got: " +wrap_ci.first());
        }
        if(ci.last()!=wrap_ci.last()){
            errln("CharacterIteratorWrapper.last() failed expected: " + ci.last() + " got: " +wrap_ci.last());
        }
        if(ci.getBeginIndex()!=wrap_ci.getBeginIndex()){
            errln("CharacterIteratorWrapper.getBeginIndex() failed expected: " + ci.getBeginIndex() + " got: " +wrap_ci.getBeginIndex());
        }
        if(ci.getEndIndex()!=wrap_ci.getEndIndex()){
            errln("CharacterIteratorWrapper.getEndIndex() failed expected: " + ci.getEndIndex() + " got: " +wrap_ci.getEndIndex());
        }
        try{
            CharacterIterator cloneWCI = (CharacterIterator) wrap_ci.clone();
            if(wrap_ci.getIndex()!=cloneWCI.getIndex()){
                errln("CharacterIteratorWrapper.clone() failed expected: " +wrap_ci.getIndex() + " got: " + cloneWCI.getIndex());
            }
        }catch(Exception e){
             errln("CharacterIterator.clone() failed");
        }
    }
    // private data members ---------------------------------------------
    
    private static final String ITERATION_STRING_ =
                                        "Testing 1 2 3 \ud800\udc00 456";
    private static final int ITERATION_SUPPLEMENTARY_INDEX = 14;
    
    public void TestJitterbug1952(){
        //test previous code point
        char[] src = new char[]{ '\uDC00','\uD800','\uDC01','\uD802','\uDC02','\uDC03'};
        UCharacterIterator iter = UCharacterIterator.getInstance(src);
        iter.setIndex(1);
        int ch;
        // this should never go into a infinite loop
        // if it does then we have a problem
        while((ch=iter.previousCodePoint())!=UCharacterIterator.DONE){
	        if(ch!=0xDc00){
	            errln("iter.previousCodePoint() failed");
	        }
        }
        iter.setIndex(5);
        while((ch=iter.nextCodePoint()) !=UCharacterIterator.DONE){
	        if(ch!= 0xDC03){
	            errln("iter.nextCodePoint() failed");
	        } 
        }      
    }
        
}
