/**
*******************************************************************************
* Copyright (C) 2006, International Business Machines Corporation and    *
* others. All Rights Reserved.                                                *
*******************************************************************************
*
*******************************************************************************
*/ 
package com.ibm.icu.charset;

import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.IntBuffer;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;

import com.ibm.icu.text.UTF16;
/**
 * @author Niti Hantaweepant
 */
class CharsetUTF32 extends CharsetICU {
    
    protected byte[] fromUSubstitution = new byte[]{(byte)0, (byte)0, (byte)0xff, (byte)0xfd};
    
    public CharsetUTF32(String icuCanonicalName, String javaCanonicalName, String[] aliases){
        super(icuCanonicalName, javaCanonicalName, aliases);
        maxBytesPerChar = 4;
        minBytesPerChar = 4;
        maxCharsPerByte = 1;
    }
    class CharsetDecoderUTF32 extends CharsetDecoderICU{

        public CharsetDecoderUTF32(CharsetICU cs) {
            super(cs);
        }

        protected CoderResult decodeLoop(ByteBuffer source, CharBuffer target, IntBuffer offsets, boolean flush){
            CoderResult cr = CoderResult.UNDERFLOW;
            
            int sourceArrayIndex = source.position();
            int ch, i;
            
            try{
                donefornow:
                {                    
                    /* UTF-8 returns here for only non-offset, this needs to change.*/
                    if (toUnicodeStatus != 0 && target.hasRemaining()) {
                        i = toULength;       /* restore # of bytes consumed */
                
                        ch = (int)(toUnicodeStatus - 1);/*Stores the previously calculated ch from a previous call*/
                        toUnicodeStatus = 0;
                        
                        while (i < 4) {
                            if (sourceArrayIndex < source.limit()) {
                                ch = (ch << 8) | ((byte)(source.get(sourceArrayIndex)) & UConverterConstants.UNSIGNED_BYTE_MASK);
                                toUBytesArray[i++] = (byte) source.get(sourceArrayIndex++);
                            }
                            else {
                                /* stores a partially calculated target*/
                                /* + 1 to make 0 a valid character */
                                toUnicodeStatus = ch + 1;
                                toULength = (byte) i;
                                break donefornow;
                            }
                        }
                
                        if (ch <= UConverterConstants.MAXIMUM_UTF && !UTF16.isSurrogate((char)ch)) {
                            /* Normal valid byte when the loop has not prematurely terminated (i < inBytes) */
                            if (ch <= UConverterConstants.MAXIMUM_UCS2) 
                            {
                                /* fits in 16 bits */
                                target.put((char)ch);
                            }
                            else {
                                /* write out the surrogates */
                                target.put(UTF16.getLeadSurrogate(ch));
                                ch = UTF16.getTrailSurrogate(ch);
                                if (target.hasRemaining()) {
                                    target.put((char)ch);
                                }
                                else {
                                    /* Put in overflow buffer (not handled here) */
                                    charErrorBufferArray[0] = (char) ch;
                                    charErrorBufferLength = 1;
                                    throw new BufferOverflowException();
                                }
                            }
                        }
                        else {
                            toULength = (byte)i;
                            cr = CoderResult.malformedForLength(sourceArrayIndex);
                            break donefornow;
                        }
                    }
                    
                    while (sourceArrayIndex < source.limit() && target.hasRemaining()) {
                        i = 0;
                        ch = 0;
                
                        while (i < 4) {
                            if (sourceArrayIndex < source.limit()) {
                                ch = (ch << 8) | ((byte)(source.get(sourceArrayIndex)) & UConverterConstants.UNSIGNED_BYTE_MASK);
                                toUBytesArray[i++] = (byte) source.get(sourceArrayIndex++);
                            }
                            else {
                                /* stores a partially calculated target*/
                                /* + 1 to make 0 a valid character */
                                toUnicodeStatus = ch + 1;
                                toULength = (byte) i;
                                break donefornow;
                            }
                        }
                
                        if (ch <= UConverterSharedData.MAXIMUM_UTF && !UTF16.isSurrogate((char)ch)) {
                            /* Normal valid byte when the loop has not prematurely terminated (i < inBytes) */
                            if (ch <= UConverterSharedData.MAXIMUM_UCS2) 
                            {
                                /* fits in 16 bits */
                                target.put((char) ch);
                            }
                            else {
                                /* write out the surrogates */
                                target.put(UTF16.getLeadSurrogate(ch));
                                ch = UTF16.getTrailSurrogate(ch);
                                if (target.hasRemaining()) {
                                    target.put((char)ch);
                                }
                                else {
                                    /* Put in overflow buffer (not handled here) */
                                    charErrorBufferArray[0] = (char) ch;
                                    charErrorBufferLength = 1;
                                    throw new BufferOverflowException();                                    
                                }
                            }
                        }
                        else {
                            toULength = (byte)i;
                            cr = CoderResult.malformedForLength(sourceArrayIndex);
                            break;
                        }
                    }
                }
                
                if (sourceArrayIndex < source.limit() && !target.hasRemaining()) {
                    /* End of target buffer */
                    cr = CoderResult.OVERFLOW;
                }                    
                
                source.position(sourceArrayIndex);
            }catch(BufferOverflowException ex){
                cr = CoderResult.OVERFLOW;
            }
            return cr;
        }        
    }
    
    class CharsetEncoderUTF32 extends CharsetEncoderICU{

        public CharsetEncoderUTF32(CharsetICU cs) {
            super(cs, fromUSubstitution);
            implReset();
        }

        private final static int NEED_TO_WRITE_BOM = 1;
        
        protected void implReset() {
            super.implReset();
            fromUnicodeStatus = NEED_TO_WRITE_BOM;
        }
        
        protected CoderResult encodeLoop(CharBuffer source, ByteBuffer target, IntBuffer offsets, boolean flush){
            CoderResult cr = CoderResult.UNDERFLOW;
            if(!source.hasRemaining()) {
                /* no input, nothing to do */
                return cr;
            }
            
            /* write the BOM if necessary */
            if(fromUnicodeStatus==NEED_TO_WRITE_BOM) {
                byte[] bom={ 0, 0, (byte)0xfe, (byte)0xff };
                cr = fromUWriteBytes(this, bom, 0, bom.length, target, offsets, -1);
                if(cr.isError()){
                    return cr;
                }
                fromUnicodeStatus=0;
            }
            
            int ch, ch2;
            int indexToWrite;
            byte temp[] = new byte[4];
            temp[0] = 0;
            int sourceArrayIndex = source.position();
            
            try{
                boolean doloop = true;
                if (fromUChar32 != 0) {
                    ch = fromUChar32;
                    fromUChar32 = 0;
                    //lowsurogate:
                    if (sourceArrayIndex < source.limit()) {
                        ch2 = source.get(sourceArrayIndex);
                        if (UTF16.isTrailSurrogate((char)ch2)) {
                            ch = ((ch - UConverterConstants.SURROGATE_HIGH_START) << UConverterSharedData.HALF_SHIFT) + ch2 + UConverterSharedData.SURROGATE_LOW_BASE;
                            sourceArrayIndex++;
                        }
                        else {
                            /* this is an unmatched trail code unit (2nd surrogate) */
                            /* callback(illegal) */
                            fromUChar32 = ch;
                            cr = CoderResult.malformedForLength(sourceArrayIndex);
                            doloop = false;
                        }
                    }
                    else {
                        /* ran out of source */
                        fromUChar32 = ch;
                        if (flush) {
                            /* this is an unmatched trail code unit (2nd surrogate) */
                            /* callback(illegal) */
                            cr = CoderResult.malformedForLength(sourceArrayIndex);
                        }
                        doloop = false;
                    }
                    
                    /* We cannot get any larger than 10FFFF because we are coming from UTF-16 */
                    temp[1] = (byte) (ch >>> 16 & 0x1F);
                    temp[2] = (byte) (ch >>> 8);  /* unsigned cast implicitly does (ch & FF) */
                    temp[3] = (byte) (ch);       /* unsigned cast implicitly does (ch & FF) */
            
                    for (indexToWrite = 0; indexToWrite <= 3; indexToWrite++) {
                        if (target.hasRemaining()) {
                            target.put(temp[indexToWrite]);
                        }
                        else {
                            errorBuffer[errorBufferLength++] = temp[indexToWrite];
                            cr = CoderResult.OVERFLOW;
                        }
                    }
                }
            
                if(doloop) {
                    while (sourceArrayIndex < source.limit() && target.hasRemaining()) {
                        ch = source.get(sourceArrayIndex++);
                
                        if (UTF16.isSurrogate((char)ch)) {
                            if (UTF16.isLeadSurrogate((char)ch)) {
                                //lowsurogate:
                                if (sourceArrayIndex < source.limit()) {
                                    ch2 = source.get(sourceArrayIndex);
                                    if (UTF16.isTrailSurrogate((char)ch2)) {
                                        ch = ((ch - UConverterSharedData.SURROGATE_HIGH_START) << UConverterSharedData.HALF_SHIFT) + ch2 + UConverterSharedData.SURROGATE_LOW_BASE;
                                        sourceArrayIndex++;
                                    }
                                    else {
                                        /* this is an unmatched trail code unit (2nd surrogate) */
                                        /* callback(illegal) */
                                        fromUChar32 = ch;
                                        cr = CoderResult.OVERFLOW;
                                        break;
                                    }
                                }
                                else {
                                    /* ran out of source */
                                    fromUChar32 = ch;
                                    if (flush) {
                                        /* this is an unmatched trail code unit (2nd surrogate) */
                                        /* callback(illegal) */
                                        cr = CoderResult.malformedForLength(sourceArrayIndex);
                                    }
                                    break;
                                }
                            }
                            else {
                                fromUChar32 = ch;
                                cr = CoderResult.malformedForLength(sourceArrayIndex);
                                break;
                            }
                        }
                
                        /* We cannot get any larger than 10FFFF because we are coming from UTF-16 */
                        temp[1] = (byte) (ch >>> 16 & 0x1F);
                        temp[2] = (byte) (ch >>> 8);  /* unsigned cast implicitly does (ch & FF) */
                        temp[3] = (byte) (ch);       /* unsigned cast implicitly does (ch & FF) */
                
                        for (indexToWrite = 0; indexToWrite <= 3; indexToWrite++) {
                            if (target.hasRemaining()) {
                                target.put(temp[indexToWrite]);
                            }
                            else {
                                errorBuffer[errorBufferLength++] = temp[indexToWrite];
                                cr = CoderResult.OVERFLOW;
                            }
                        }
                    }
                }
            
                if (sourceArrayIndex < source.limit() && !target.hasRemaining()) {
                    cr = CoderResult.OVERFLOW;
                }
                source.position(sourceArrayIndex);
                
            }catch(BufferOverflowException ex){
                cr = CoderResult.OVERFLOW;
            }
            return cr;
        }
    }
    public CharsetDecoder newDecoder() {
        return new CharsetDecoderUTF32(this);
    }

    public CharsetEncoder newEncoder() {
        return new CharsetEncoderUTF32(this);
    }
}
