package com.ibm.icu.dev.test.iterator;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.impl.UCharacterIterator;
import com.ibm.icu.text.UTF16;
import com.ibm.icu.impl.Utility;

/**
 * @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");
            }
         }
    }
    
    /**
     * 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;
    };
    /*
    public void TestPreviousNext() {
        // src and expect strings
        char src[]={
            UTF16.getLeadSurrogate(0x2f999), UTF16.getTrailSurrogate(0x2f999),
            UTF16.getLeadSurrogate(0x1d15f), UTF16.getTrailSurrogate(0x1d15f),
            0xc4,
            0x1ed0
        };
        int expect[]={
            0x2f999,
            0x1d15f,
            0xc4,
            0x1ed0
        };
    
        // expected src indexes corresponding to expect indexes
        int expectIndex[]={
            0,0,
            1,1,
            2,
            3,
            3
        };
    
        // 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--------";
    
        // iterators
        UCharacterIterator iter = UCharacterIterator.getInstance(new String(src));
        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;
            }
        }
    }*/
    

    // private data members ---------------------------------------------
    
    private static final String ITERATION_STRING_ =
                                        "Testing 1 2 3 \ud800\udc00 456";
    private static final int ITERATION_SUPPLEMENTARY_INDEX = 14;
        
}
