////////////////////////////////////////////////////////////////////////////////
//
//  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.graphics
{

import flash.display.IBitmapDrawable;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Stage;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.system.Capabilities;
import flash.utils.ByteArray;
import flash.utils.getDefinitionByName;
import mx.core.IFlexDisplayObject;
import mx.core.IUIComponent;
import mx.core.UIComponent;
import mx.graphics.codec.IImageEncoder;
import mx.graphics.codec.PNGEncoder;
import mx.utils.Base64Encoder;

[RemoteClass(alias="flex.graphics.ImageSnapshot")]

/**
 *  A helper class used to capture a snapshot of any Flash component 
 *  that implements <code>flash.display.IBitmapDrawable</code>,
 *  including Flex UIComponents.
 *
 *  <p>An instance of this class can be sent as a RemoteObject
 *  to Adobe's LiveCycle Data Services to generate
 *  a PDF file of a client-side image.
 *  If you need to specify additional properties of the image
 *  beyond its <code>contentType</code>, <code>width</code>,
 *  and <code>height</code> properties, you should set name/value pairs
 *  on the <code>properties</code> object.</p>
 *
 *  <p>In earlier versions of Flex, you set these additional
 *  properties on the ImageSnapshot instance itself.
 *  This class is still dynamic in order to allow that,
 *  but in a future version of Flex it might no longer be dynamic.</p>
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public dynamic class ImageSnapshot
{
    include "../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Class constants
    // 
    //--------------------------------------------------------------------------

    /**
     *  The maximum width and height of a Bitmap.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public static const MAX_BITMAP_DIMENSION:int = 2880;
    
    //--------------------------------------------------------------------------
    //
    //  Class variables
    // 
    //--------------------------------------------------------------------------

    /**
     *  The default <code>mx.graphics.codec.IImageEncoder</code> implementation
     *  used to capture images. The two implementations are PNGEncoder and 
     *  JPEGEncoder. The default encoder uses the PNG format.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public static var defaultEncoder:Class = PNGEncoder;

    //--------------------------------------------------------------------------
    //
    //  Class methods
    // 
    //--------------------------------------------------------------------------

    /**
     *  A utility method to grab a raw snapshot of a UI component as BitmapData.
     * 
     *  @param source An object that implements the
     *    <code>flash.display.IBitmapDrawable</code> interface.
     *
     *  @param matrix A Matrix object used to scale, rotate, or translate
     *  the coordinates of the captured bitmap.
     *  If you do not want to apply a matrix transformation to the image,
     *  set this parameter to an identity matrix,
     *  created with the default new Matrix() constructor, or pass a null value.
     *
     *  @param colorTransform A ColorTransform 
     *  object that you use to adjust the color values of the bitmap. If no object 
     *  is supplied, the bitmap image's colors are not transformed. If you must pass 
     *  this parameter but you do not want to transform the image, set this parameter 
     *  to a ColorTransform object created with the default new ColorTransform() constructor.
     *
     *  @param blendMode A string value, from the flash.display.BlendMode 
     *  class, specifying the blend mode to be applied to the resulting bitmap.
     *
     *  @param clipRect A Rectangle object that defines the 
     *  area of the source object to draw. If you do not supply this value, no clipping 
     *  occurs and the entire source object is drawn.
     *
     *  @param smoothing A Boolean value that determines whether a 
     *  BitmapData object is smoothed when scaled.
     *
     *  @return A BitmapData object representing the captured snapshot or null if 
     *  the source has no visible bounds.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public static function captureBitmapData(
                                source:IBitmapDrawable, matrix:Matrix = null,
                                colorTransform:ColorTransform = null,
                                blendMode:String = null,
                                clipRect:Rectangle = null,
                                smoothing:Boolean = false):BitmapData
    {
        var data:BitmapData;
        var width:int;
        var height:int;

        var normalState:Array;
        if (source is IUIComponent)
            normalState = prepareToPrintObject(IUIComponent(source));

        try
        {
            if (source != null)
            {
                if (source is DisplayObject)
                {
                    width = DisplayObject(source).width;
                    height = DisplayObject(source).height;
                }
                else if (source is BitmapData)
                {
                    width = BitmapData(source).width;
                    height = BitmapData(source).height;
                }
                else if (source is IFlexDisplayObject)
                {
                    width = IFlexDisplayObject(source).width;
                    height = IFlexDisplayObject(source).height;
                }
            }

            // We default to an identity matrix
            // which will match screen resolution
            if (!matrix)
                matrix = new Matrix(1, 0, 0, 1);

            var scaledWidth:Number = width * matrix.a;
            var scaledHeight:Number = height * matrix.d;
            var reductionScale:Number = 1;

            // Cap width to BitmapData max of 2880 pixels
            if (scaledWidth > MAX_BITMAP_DIMENSION)
            {
                reductionScale = scaledWidth / MAX_BITMAP_DIMENSION;
                scaledWidth = MAX_BITMAP_DIMENSION;
                scaledHeight = scaledHeight / reductionScale;
    
                matrix.a = scaledWidth / width;
                matrix.d = scaledHeight / height;
            }

            // Cap height to BitmapData max of 2880 pixels
            if (scaledHeight > MAX_BITMAP_DIMENSION)
            {
                reductionScale = scaledHeight / MAX_BITMAP_DIMENSION;
                scaledHeight = MAX_BITMAP_DIMENSION;
                scaledWidth = scaledWidth / reductionScale;
    
                matrix.a = scaledWidth / width;
                matrix.d = scaledHeight / height;
            }

            // the fill should be transparent: 0xARGB -> 0x00000000
            // only explicitly drawn pixels will show up
            data = new BitmapData(scaledWidth, scaledHeight, true, 0x00000000);
            data.draw(source, matrix, colorTransform,
                      blendMode, clipRect, smoothing);
        }
        catch(e:Error)
        {
            data = null;
        }
        finally
        {
            if (source is IUIComponent)
                finishPrintObject(IUIComponent(source), normalState);
        }

        return data;
    }

    /**
     *  A utility method to grab a snapshot of a component, scaled to a specific
     *  resolution (in dpi) and encoded into a specific image format.
     * 
     *  @param source An object that implements the
     *  <code>flash.display.IBitmapDrawable</code> interface.
     *
     *  @param dpi The resolution in dots per inch.
     *  If a resolution is not provided,
     *  the current on-screen resolution is used by default.
     *
     *  @param encoder The image format used to encode the raw bitmap. The two 
     *  encoders are PNGEncoder and JPEGEncoder. If an encoder is not provided, 
     *  the default is PNGEncoder.
     *
     *  @param scaleLimited The maximum width or height of a bitmap in Flash
     *  is 2880 pixels - if scaleLimited is set to true the resolution will be
     *  reduced proportionately to fit within 2880 pixels, otherwise, if
     *  scaleLimited is false, smaller snapshot windows will be taken and
     *  stitched together to capture a larger image.
     *  The default is true.
     *
     *  @return An ImageSnapshot holding an encoded captured snapshot
     *  and associated image metadata.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public static function captureImage(
                                source:IBitmapDrawable, dpi:Number = 0,
                                encoder:IImageEncoder = null,
                                scaleLimited:Boolean = true):ImageSnapshot
    {
        var snapshot:ImageSnapshot;

        // Calculate scaling factor based on current screen resolution (dpi)
        var screenDPI:Number = Capabilities.screenDPI;
        if (dpi <= 0)
            dpi = screenDPI;

        // Create a transformation matrix to scale image to desired resolution
        var scale:Number = dpi / screenDPI;    
        var matrix:Matrix = new Matrix(scale, 0, 0, scale);

        var width:int;
        var height:int;

        var normalState:Array;
        if (source is IUIComponent)
            normalState = prepareToPrintObject(IUIComponent(source));

        try
        {
            if (source != null)
            {
                if (source is DisplayObject)
                {
                    width = DisplayObject(source).width;
                    height = DisplayObject(source).height;
                }
                else if (source is BitmapData)
                {
                    width = BitmapData(source).width;
                    height = BitmapData(source).height;
                }
                else if (source is IFlexDisplayObject)
                {
                    width = IFlexDisplayObject(source).width;
                    height = IFlexDisplayObject(source).height;
                }
            }

            // Use an image encoder on raw pixels to reduce size
            if (!encoder)
                encoder = new defaultEncoder();

            var bytes:ByteArray;
            width = width * matrix.a;
            height = height * matrix.d;

            // If scaleLimited, we limit snapshot to a maximum of 2880 x 2880
            // pixels irrespective of the requested dpi
            if (scaleLimited ||
                (width <= MAX_BITMAP_DIMENSION &&
                 height <= MAX_BITMAP_DIMENSION))
            {
                var data:BitmapData = captureBitmapData(source, matrix);
                var bitmap:Bitmap = new Bitmap(data);
                width = bitmap.width;
                height = bitmap.height;
                bytes = encoder.encode(data);
            }
            else
            {
                // We scale to the requested dpi and try to capture the
                // entire snapshot as a raw bitmap ByteArray
                var bounds:Rectangle = new Rectangle(0, 0, width, height);
                bytes = captureAll(source, bounds, matrix);
                bytes = encoder.encodeByteArray(bytes, width, height);
            }

            snapshot = new ImageSnapshot(width, height, bytes,
                                         encoder.contentType);
        }
        finally
        {
            if (source is IUIComponent)
                finishPrintObject(IUIComponent(source), normalState);
        }

        return snapshot;
    }

    /**
     *  A utility method to convert an ImageSnapshot into a Base-64 encoded
     *  String for transmission in text based serialization formats such as XML.
     *
     *  @param snapshot An image captured as an
     *  <code>mx.graphics.ImageSnapshot</code>.
     *
     *  @return A string representing the base64 encoded snapshot.
     * 
     *  @see #captureImage
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public static function encodeImageAsBase64(snapshot:ImageSnapshot):String
    {
        var bytes:ByteArray = snapshot.data;

        // Convert to Base64 encoded String
        var base64:Base64Encoder = new Base64Encoder();
        base64.encodeBytes(bytes);
        var base64Image:String = base64.drain();

        return base64Image;
    }

    /**
     *  @private
     *  Attempts to capture as much of an image for the requested bounds by
     *  splitting the scaled source into rectangular windows that fit inside
     *  the maximum size of a single BitmapData instance,
     *  i.e. 2880 x 2880 pixels, and stitching the windows together
     *  into a larger bitmap with the raw pixels returned as a ByteArray.
     *  This ByteArray is limited to around 256MB so scaled images with an area
     *  equivalent to about 8192 x 8192 will result in out-of-memory errors.
     */
    private static function captureAll(source:IBitmapDrawable, bounds:Rectangle,
                                       matrix:Matrix,
                                       colorTransform:ColorTransform = null,
                                       blendMode:String = null,
                                       clipRect:Rectangle = null,
                                       smoothing:Boolean = false):ByteArray
    {
        var currentMatrix:Matrix = matrix.clone();
        var topLeft:Rectangle = bounds.clone();
        var topRight:Rectangle;
        var bottomLeft:Rectangle;
        var bottomRight:Rectangle;

        // Check if the requested bounds exceeds the maximum width for 
        // a bitmap...
        if (bounds.width > MAX_BITMAP_DIMENSION)
        {
            topLeft.width = MAX_BITMAP_DIMENSION;

            topRight = new Rectangle();
            topRight.x = topLeft.width;
            topRight.y = bounds.y;
            topRight.width = bounds.width - topLeft.width;
            topRight.height = bounds.height;
        }

        // Check if the requested bounds exceeds the maximum height for 
        // a bitmap...
        if (bounds.height > MAX_BITMAP_DIMENSION)
        {
            topLeft.height = MAX_BITMAP_DIMENSION;
            if (topRight != null)
                topRight.height = topLeft.height;

            bottomLeft = new Rectangle();
            bottomLeft.x = bounds.x;
            bottomLeft.y = topLeft.height;
            bottomLeft.width = topLeft.width;
            bottomLeft.height = bounds.height - topLeft.height;

            if (bounds.width > MAX_BITMAP_DIMENSION)
            {
                bottomRight = new Rectangle();
                bottomRight.x = topLeft.width;
                bottomRight.y = topLeft.height;
                bottomRight.width = bounds.width - topLeft.width;
                bottomRight.height = bounds.height - topLeft.height;
            }
        }

        // Capture top-left window
        currentMatrix.translate(-topLeft.x, -topLeft.y);
        topLeft.x = 0;
        topLeft.y = 0;
        
        // the fill should be transparent: 0xARGB -> 0x00000000
        // only explicitly drawn pixels will show up
        var data:BitmapData = new BitmapData(topLeft.width, topLeft.height, true, 0x00000000);
        data.draw(source, currentMatrix, colorTransform,
                  blendMode, clipRect, smoothing);
        
        var pixels:ByteArray = data.getPixels(topLeft);
        pixels.position = 0;

        // If bounds width exceeded maximum dimensions for a bitmap, we 
        // also need to capture the top-right window (recursively, until we
        // have a window width less that the max). These right side rows have
        // to be merged to the right of each left side row.
        if (topRight != null)
        {
            currentMatrix = matrix.clone();
            currentMatrix.translate(-topRight.x, -topRight.y);
            topRight.x = 0;
            topRight.y = 0;
            var topRightPixels:ByteArray =
                captureAll(source, topRight, currentMatrix);
            pixels = mergePixelRows(pixels, topLeft.width, topRightPixels,
                                    topRight.width, topRight.height);
        }

        // If bounds height exceeded the maximum dimension for a bitmap, we
        // also need to capture the bottom-left window (recursively, until we
        // have a window height less than the max). These rows are appended 
        // to the end of the current 32-bit, 4 channel bitmap as a ByteArray.
        if (bottomLeft != null)
        {
            currentMatrix = matrix.clone();
            currentMatrix.translate(-bottomLeft.x, -bottomLeft.y);
            bottomLeft.x = 0;
            bottomLeft.y = 0;
            var bottomLeftPixels:ByteArray = captureAll(source, bottomLeft,
                                                        currentMatrix);

            // If both the bounds width and bounds height exceeded the maximum
            // dimensions for a bitmap, we now must to capture the bottom-right
            // window (recursively, until we have a window with less than the
            // max width and/or height). These right side rows have to be merged
            // to the right of each left side row.
            if (bottomRight != null)
            {
                currentMatrix = matrix.clone();
                currentMatrix.translate(-bottomRight.x, -bottomRight.y);
                bottomRight.x = 0;
                bottomRight.y = 0;
                var bottomRightPixels:ByteArray =
                    captureAll(source, bottomRight, currentMatrix);
                bottomLeftPixels = mergePixelRows(bottomLeftPixels,
                                                  bottomLeft.width,
                                                  bottomRightPixels,
                                                  bottomRight.width,
                                                  bottomRight.height);
            }

            // Append bottomLeft pixels to the end of the ByteArray of pixels
            pixels.position = pixels.length;
            pixels.writeBytes(bottomLeftPixels);
        }

        pixels.position = 0;

        return pixels;
    }

    /**
     *  @private
     *  Copies the rows of the right hand side of an image onto the ends of
     *  the rows of the left hand side of an image. The left and right hand
     *  sides must be of equal height.
     */
    private static function mergePixelRows(left:ByteArray, leftWidth:int,
                                           right:ByteArray, rightWidth:int,
                                           rightHeight:int):ByteArray
    {
        var merged:ByteArray = new ByteArray();
        var leftByteWidth:int = leftWidth * 4;
        var rightByteWidth:int = rightWidth * 4;

        for (var i:int = 0; i < rightHeight; i++)
        {
            merged.writeBytes(left, i * leftByteWidth, leftByteWidth); 
            merged.writeBytes(right, i * rightByteWidth, rightByteWidth);
        }

        merged.position = 0;
        return merged;
    }

    /**
     *  @private
     *  Prepare the target and its parents for image capture.
     */
    private static function prepareToPrintObject(target:IUIComponent):Array
    {
        var normalStates:Array = [];

        var obj:DisplayObject = target is DisplayObject ?
                                DisplayObject(target) :
                                null;
        var index:Number = 0;
        
        while (obj != null)
        {
            if (obj is UIComponent)
            {
                normalStates[index++] =
                    UIComponent(obj).prepareToPrint(UIComponent(target));
            }
            else if (obj is DisplayObject && !(obj is Stage))
            {
                normalStates[index++] = DisplayObject(obj).mask;
                DisplayObject(obj).mask = null;
            }

            obj = obj.parent is DisplayObject ?
                  DisplayObject(obj.parent) :
                  null;
        }

        return normalStates;
    }

    /**
     *  @private
     *  Reverts the target and its parents back to a pre-capture state.
     */
    private static function finishPrintObject(target:IUIComponent,
                                              normalStates:Array):void
    {
        var obj:DisplayObject = target is DisplayObject ?
                                DisplayObject(target) :
                                null;
        var index:Number = 0;
        while (obj != null)
        {
            if (obj is UIComponent)
            {
                UIComponent(obj).finishPrint(normalStates[index++], UIComponent(target));
            }
            else if (obj is DisplayObject && !(obj is Stage))
            {
                DisplayObject(obj).mask = normalStates[index++];
            }

            obj = (obj.parent is DisplayObject) ? DisplayObject(obj.parent) : null;
        }
    }

    //--------------------------------------------------------------------------
    //
    //  Constructor
    // 
    //--------------------------------------------------------------------------

    /**
     *  Constructor.
     *
     *  @param width Width of the image.
     *
     *  @param height Height of the image.
     *
     *  @param data A byte array to contain the image.
     *
     *  @param contentType The encoder format type for the image, 
     *  either PNGEncoder or JPEGEncoder.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function ImageSnapshot(width:int = 0, height:int = 0,
                                  data:ByteArray = null,
                                  contentType:String = null)
    {
        super();

        this.contentType = contentType;
        this.width = width;
        this.height = height;
        this.data = data;
    }


    //--------------------------------------------------------------------------
    //
    //  Properties
    // 
    //--------------------------------------------------------------------------

    //----------------------------------
    //  contentType
    //----------------------------------

    /**
     *  @private
     *  Storage for the contentType property.
     */
    private var _contentType:String;
    
    [Inspectable(category="General")]
    
    /**
     *  The MIME content type for the image encoding format
     *  that was used to capture this snapshot. For PNG format
     *  images, the MIME type is "image/png". For JPG or JPEG 
     *  images, the MIME type is "image/jpeg"
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get contentType():String
    {
        return _contentType;
    }

    /**
     *  @private
     */
    public function set contentType(value:String):void
    {
        _contentType = value;
    }

    //----------------------------------
    //  data
    //----------------------------------

    /**
     *  @private
     *  Storage for the data property.
     */
    private var _data:ByteArray;    
    
    [Inspectable(category="General")]
    
    /**
     *  The encoded data representing the image snapshot.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get data():ByteArray
    {
        return _data;
    }

    /**
     *  @private
     */
    public function set data(value:ByteArray):void
    {
        _data = value;
    }

    //----------------------------------
    //  height
    //----------------------------------

    /**
     *  @private
     *  Storage for the height property.
     */
    private var _height:int;
    
    [Inspectable(category="General")]
    
    /**
     *  The image height in pixels.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get height():int
    {
        return _height;
    }

    /**
     *  @private
     */
    public function set height(value:int):void
    {
        _height = value;
    }

    //----------------------------------
    //  properties
    //----------------------------------
    
    /**
     *  @private
     *  Storage for the properties property.
     */
    private var _properties:Object = {};

    /**
     *  An Object containing name/value pairs
     *  specifying additional properties of the image.
     *
     *  <p>You generally supply such information
     *  only when sending an ImageSnapshot instance
     *  to Adobe's LiveCycle Data Services
     *  in order to generate a PDF file.
     *  You can either set the entire object
     *  or set individual name/value pairs
     *  on the pre-existing empty Object.</p>
     *
     *  @default {}
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get properties():Object
    {
        return _properties;
    }

    /**
     *  @private
     */
    public function set properties(value:Object):void
    {
        _properties = value;
    }

    //----------------------------------
    //  width
    //----------------------------------

    /**
     *  @private
     *  Storage for the width property.
     */
    private var _width:int;

    [Inspectable(category="General")]

    /**
     * The image width in pixels.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get width():int
    {
        return _width;
    }

    /**
     *  @private
     */
    public function set width(value:int):void
    {
        _width = value;
    }
}

}
