////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package mx.utils
{

import flash.utils.ByteArray;


[ExcludeClass]

/**
 *  Documentation is not currently available.
 *  Ported to ActionScript from flex/messaging/util/Hex.java
 *  @private
 */
public class HexEncoder
{
    /**
     *  @private
     *  Set encodingStyle to this value to encode using upper case 'A'-'F'.
     */ 
    public static const UPPER_CASE:String = "upper";
    
    /**
     *  @private
     *  Set encodingStyle to this value to encode using lower case 'a'-'f'. 
     */
    public static const LOWER_CASE:String = "lower";
    
    /**
     *  @private
     *  The default encoding style for all HexEncoders.
     */
    public static var encodingStyle:String = UPPER_CASE;
    
    /**
     *  @private
     *  Constructor.
     */
    public function HexEncoder()
    {
        super();
        _buffers = [];
        _buffers.push([]);
    }

    /**
     *  @private
     *  The encoding style for this HexEncoder instance.
     *  If not set, the default static encodingStyle is used.
     */
    public var encodingStyle:String;

    /**
     *  @private
     */
    public function encode(data:ByteArray, offset:uint = 0, length:uint = 0):void
    {
        if (length == 0)
            length = data.length;

        if (offset < length)
        {
            data.position = offset;
        }
        
        var style:String = (this.encodingStyle != null) ? this.encodingStyle : HexEncoder.encodingStyle;
        // Validate style; coerce invalid values to UPPER.
        if (style != UPPER_CASE && style != LOWER_CASE)
            style = UPPER_CASE;

        var digits:Array = (style == UPPER_CASE) ? UPPER_CHAR_CODES : LOWER_CHAR_CODES;

        while (data.bytesAvailable > 0)
        {
            encodeBlock(data.readByte(), digits);
        } // while
    }

    /**
     *  @private
     */
    public function drain():String
    {
        var result:String = "";

        for (var i:uint = 0; i < _buffers.length; i++)
        {
            var buffer:Array = _buffers[i] as Array;
            result += String.fromCharCode.apply(null, buffer);
        }

        _buffers = [];
        _buffers.push([]);

        return result;
    }

    /**
     *  @private
     */
    public function flush():String
    {
        return drain();
    }

    /**
     *  @private
     */
    private function encodeBlock(_work:int, digits:Array):void
    {
        var currentBuffer:Array = _buffers[_buffers.length - 1] as Array;
        if (currentBuffer.length >= MAX_BUFFER_SIZE)
        {
            currentBuffer = [];
            _buffers.push(currentBuffer);
        }

        currentBuffer.push(digits[(_work & 0xF0) >>> 4]);
        currentBuffer.push(digits[(_work & 0x0F)]);
    }

    /**
     *  An Array of buffer Arrays. 
     *  @private
     */
    private var _buffers:Array;

    /**
     *  @private
     */
    private var _work:int = 0;

    /**
     * This value represents a safe number of characters (i.e. arguments) that
     * can be passed to String.fromCharCode.apply() without exceeding the AVM+
     * stack limit.
     * 
     * @private
     */
    public static const MAX_BUFFER_SIZE:uint = 32767;

    /*
        '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
     */
    private static const UPPER_CHAR_CODES:Array =
    [
        48, 49, 50, 51, 52, 53, 54, 55,
        56, 57, 65, 66, 67, 68, 69, 70,
    ];

    /*
        '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
     */
    private static const LOWER_CHAR_CODES:Array = 
    [
        48, 49, 50, 51, 52, 53, 54, 55,
        56, 57, 97, 98, 99, 100, 101, 102
    ];

}

}
