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

import flash.display.BitmapData;
import flash.display.DisplayObjectContainer;
import flash.events.Event;
import flash.geom.Point;
import flash.system.ApplicationDomain;

/**
 *  BitmapAsset is a subclass of the flash.display.Bitmap class
 *  which represents bitmap images that you embed in a Flex application.
 *  It implements the IFlexDisplayObject interface, which makes it
 *  possible for an embedded bitmap image to be displayed in an Image control,
 *  or to be used as a container background or a component skin.
 *
 *  <p>The bitmap image that you're embedding can be in a JPEG, GIF,
 *  or PNG file.
 *  You can also embed a bitmap symbol that is in a SWF file produced
 *  by Flash.
 *  In each of these cases, the MXML compiler autogenerates a class
 *  that extends BitmapAsset to represent the embedded bitmap image.</p>
 *
 *  <p>You don't generally have to use the BitmapAsset class directly
 *  when you write a Flex application.
 *  For example, you can embed a GIF file and display the image
 *  in an Image control by writing the gollowing:</p>
 *
 *  <pre>
 *  &lt;mx:Image id="logo" source="&#64;Embed(source='Logo.gif')"/&gt;</pre>
 *
 *  <p>or use it as the application's background image in CSS syntax
 *  by writing</p>
 *
 *  <pre>
 *  &lt;fx:Style&gt;
 *      &#64;namespace mx "library://ns.adobe.com/flex/mx"
 *      mx|Application {
 *          backgroundImage: Embed(source="Logo.gif")
 *      }
 *  &lt;fx:Style/&gt;</pre>
 *
 *  <p>without having to understand that the MXML compiler has created
 *  a subclass of BitmapAsset for you.</p>
 *
 *  <p>However, it may be useful to understand what is happening
 *  at the ActionScript level.
 *  To embed a bitmap image in ActionScript, you declare a variable
 *  of type Class, and put <code>[Embed]</code> metadata on it.
 *  For example, you embed a GIF file like this:</p>
 *
 *  <pre>
 *  [Bindable]
 *  [Embed(source="Logo.gif")]
 *  private var logoClass:Class;</pre>
 *
 *  <p>The MXML compiler sees the .gif extension, transcodes the GIF data
 *  into the bitmap format that the player uses, autogenerates
 *  a subclass of the BitmapAsset class, and sets your variable
 *  to be a reference to this autogenerated class.
 *  You can then use this class reference to create instances of the
 *  BitmapAsset using the <code>new</code> operator, and you can use
 *  APIs of the BitmapAsset class on them:</p>
 *
 *  <pre>
 *  var logo:BitmapAsset = BitmapAsset(new logoClass());
 *  logo.bitmapData.noise(4);</pre>
 *
 *  <p>However, you rarely need to create BitmapAsset instances yourself
 *  because image-related properties and styles can simply be set to an
 *  image-producing class, and components will create image instances
 *  as necessary.
 *  For example, to display this image in an Image control, you can 
 *  set the Image's <code>source</code> property to <code>logoClass</code>.
 *  In MXML you could do this as follows:</p>
 *
 *  <pre>
 *  &lt;mx:Image id="logo" source="{logoClass}"/&gt;</pre>
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class BitmapAsset extends FlexBitmap
                         implements IFlexAsset, IFlexDisplayObject, ILayoutDirectionElement
{
    include "../core/Version.as";

    // Softlink FlexVersion and MatrixUtil to remove dependencies of embeds on
    // framework classes. This helps to reduce swf size in AS-only projects.
    private static var FlexVersionClass:Class;
    private static var MatrixUtilClass:Class;
    
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor.
     *
     *  @param bitmapData The data for the bitmap image. 
     *
     *  @param pixelSnapping Whether or not the bitmap is snapped
     *  to the nearest pixel.
     *
     *  @param smoothing Whether or not the bitmap is smoothed when scaled. 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function BitmapAsset(bitmapData:BitmapData = null,
                                pixelSnapping:String = "auto",
                                smoothing:Boolean = false)
    {
        super(bitmapData, pixelSnapping, smoothing);
        
        if (FlexVersionClass == null)
        {
            var appDomain:ApplicationDomain = ApplicationDomain.currentDomain;
            if (appDomain.hasDefinition("mx.core::FlexVersion"))
                FlexVersionClass = Class(appDomain.getDefinition("mx.core::FlexVersion"));
        }
        
        if (FlexVersionClass && FlexVersionClass["compatibilityVersion"] >= FlexVersionClass["VERSION_4_0"])
            this.addEventListener(Event.ADDED, addedHandler);
    }

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

    // Softlink AdvancedLayoutFeatures to remove dependencies of embeds on
    // framework classes. This helps to reduce swf size in AS-only projects.
    private var layoutFeaturesClass:Class;
    private var layoutFeatures:IAssetLayoutFeatures;
    
    //--------------------------------------------------------------------------
    //
    //  Overridden Properties
    //
    //--------------------------------------------------------------------------
    
    //----------------------------------
    //  x
    //----------------------------------
    
    /**
     *  @private
     */
    override public function get x():Number
    {
        // TODO(hmuller): by default get x returns transform.matrix.tx rounded to the nearest 20th.
        // should do the same here, if we're returning layoutFeatures.layoutX.
        return (layoutFeatures == null) ? super.x : layoutFeatures.layoutX;
    }
    
    /**
     *  @private
     */
    override public function set x(value:Number):void
    {
        if (x == value)
            return;
        
        if (layoutFeatures == null)
        {
            super.x = value;
        }
        else
        {
            layoutFeatures.layoutX = value;
            validateTransformMatrix();
        }
    }
    
    //----------------------------------
    //  y
    //----------------------------------
    
    /**
     *  @private
     */
    override public function get y():Number
    {
        return (layoutFeatures == null) ? super.y : layoutFeatures.layoutY;
    }
    
    /**
     *  @private
     */
    override public function set y(value:Number):void
    {
        if (y == value)
            return;
        
        if (layoutFeatures == null)
        {
            super.y = value;
        }
        else
        {
            layoutFeatures.layoutY = value;
            validateTransformMatrix();
        }
    }
    
    //----------------------------------
    //  z
    //----------------------------------
    
    /**
     *  @private
     */
    override public function get z():Number
    {
        return (layoutFeatures == null) ? super.z : layoutFeatures.layoutZ;
    }
    
    /**
     *  @private
     */
    override public function set z(value:Number):void
    {
        if (z == value)
            return;
        
        if (layoutFeatures == null)
        {
            super.z = value;
        }
        else
        {
            layoutFeatures.layoutZ = value;
            validateTransformMatrix();
        }
    }
    
    //----------------------------------
    //  width
    //----------------------------------
    
    /**
     *  @private
     */
    override public function get width():Number
    {
        if (layoutFeatures == null)
            return super.width;
        
        // Return bounding box width in mirroring case
        var p:Point;
        if (MatrixUtilClass != null)
            p = MatrixUtilClass["transformSize"](layoutFeatures.layoutWidth, _height, transform.matrix);
        
        return p ? p.x : super.width;
    }
    
    /**
     *  @private
     */
    override public function set width(value:Number):void
    {
        if (width == value)
            return;
        
        if (layoutFeatures == null)
        {
            super.width = value;
        }
        else
        {
            layoutFeatures.layoutWidth = value;
            // Calculate scaleX based on initial width. We set scaleX
            // here because resizing a BitmapAsset normally would adjust
            // the scale to match.
            layoutFeatures.layoutScaleX = measuredWidth != 0 ? value / measuredWidth : 0;
            validateTransformMatrix();
        }
    }
    
    //----------------------------------
    //  height
    //----------------------------------
    
    private var _height:Number;
    
    /**
     *  @private
     */
    override public function get height():Number
    {
        
        if (layoutFeatures == null)
            return super.height;
        
        // Return bounding box height in mirroring case
        var p:Point;
        if (MatrixUtilClass != null)
            p = MatrixUtilClass["transformSize"](layoutFeatures.layoutWidth, _height, transform.matrix);
        
        return p ? p.y : super.height;
    }
    
    /**
     *  @private
     */
    override public function set height(value:Number):void  
    {
        if (height == value)
            return;
        
        if (layoutFeatures == null)
        {
            super.height = value;
        }
        else
        {
            _height = value;
            // Calculate scaleY based on initial height. We set scaleY
            // here because resizing a BitmapAsset normally would adjust
            // the scale to match.
            layoutFeatures.layoutScaleY = measuredHeight != 0 ? value / measuredHeight : 0;
            validateTransformMatrix();
        }
    }
    
    //----------------------------------
    //  rotation
    //----------------------------------
    
    /**
     *  @private
     */
    override public function get rotationX():Number
    {
        return (layoutFeatures == null) ? super.rotationX : layoutFeatures.layoutRotationX;
    }
    
    /**
     *  @private
     */
    override public function set rotationX(value:Number):void
    {
        if (rotationX == value)
            return;
        
        if (layoutFeatures == null)
        {
            super.rotationX = value;
        }
        else
        {
            layoutFeatures.layoutRotationX = value;
            validateTransformMatrix();
        }
    }
    /**
     *  @private
     */
    override public function get rotationY():Number
    {
        return (layoutFeatures == null) ? super.rotationY : layoutFeatures.layoutRotationY;
    }
    
    /**
     *  @private
     */
    override public function set rotationY(value:Number):void
    {
        if (rotationY == value)
            return;
        
        if (layoutFeatures == null)
        {
            super.rotationY = value;
        }
        else
        {
            layoutFeatures.layoutRotationY = value;
            validateTransformMatrix();
        }
    }
    
    /**
     *  @private
     */
    override public function get rotationZ():Number
    {
        return (layoutFeatures == null) ? super.rotationZ : layoutFeatures.layoutRotationZ;
    }
    
    /**
     *  @private
     */
    override public function set rotationZ(value:Number):void
    {
        if (rotationZ == value)
            return;
        
        if (layoutFeatures == null)
        {
            super.rotationZ = value;
        }
        else
        {
            layoutFeatures.layoutRotationZ = value;
            validateTransformMatrix();
        }
    }
    
    /**
     *  @private
     */
    override public function get rotation():Number
    {
        return (layoutFeatures == null) ? super.rotation : layoutFeatures.layoutRotationZ;
    }
    
    /**
     *  @private
     */
    override public function set rotation(value:Number):void
    {
        if (rotation == value)
            return;
        
        if (layoutFeatures == null)
        {
            super.rotation = value;
        }
        else
        {
            layoutFeatures.layoutRotationZ = value;
            validateTransformMatrix();
        }
    }
    
    //----------------------------------
    //  scaleX
    //----------------------------------
    
    /**
     *  @private
     */
    override public function get scaleX():Number
    {
        return (layoutFeatures == null) ? super.scaleX : layoutFeatures.layoutScaleX;
    }
    
    /**
     *  @private
     */
    override public function set scaleX(value:Number):void
    {
        if (scaleX == value)
            return;
        
        if (layoutFeatures == null)
        {
            super.scaleX = value;
        }
        else
        {
            layoutFeatures.layoutScaleX = value;
            layoutFeatures.layoutWidth = Math.abs(value) * measuredWidth;
            validateTransformMatrix();
        }
    }
    
    //----------------------------------
    //  scaleY
    //----------------------------------
    
    /**
     *  @private
     */
    override public function get scaleY():Number
    {
        return (layoutFeatures == null) ? super.scaleY : layoutFeatures.layoutScaleY;
    }
    
    /**
     *  @private
     */
    override public function set scaleY(value:Number):void
    {
        if (scaleY == value)
            return;
        
        if (layoutFeatures == null)
        {
            super.scaleY = value;
        }
        else
        {
            layoutFeatures.layoutScaleY = value;
            _height = Math.abs(value) * measuredHeight;
            validateTransformMatrix();
        }
    }

    //----------------------------------
    //  scaleZ
    //----------------------------------
    
    /**
     *  @private
     */
    override public function get scaleZ():Number
    {
        return (layoutFeatures == null) ? super.scaleZ : layoutFeatures.layoutScaleZ;
    }
    
    /**
     *  @private
     */
    override public function set scaleZ(value:Number):void
    {
        if (scaleZ == value)
            return;
        
        if (layoutFeatures == null)
        {
            super.scaleZ = value;
        }
        else
        {
            layoutFeatures.layoutScaleZ = value;
            validateTransformMatrix();
        }
    }

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

    //----------------------------------
    //  layoutDirection
    //----------------------------------
    
    // Use "ltr" instead of LayoutDirection.LTR to avoid depending
    // on that framework class.
    private var _layoutDirection:String = "ltr";
    
    [Inspectable(category="General", enumeration="ltr,rtl")]
    
    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4.1
     */
    public function get layoutDirection():String
    {
        return _layoutDirection;
    }
    
    public function set layoutDirection(value:String):void
    {
        if (value == _layoutDirection)
            return;
        
        _layoutDirection = value;
        invalidateLayoutDirection();
    }

    //----------------------------------
    //  measuredHeight
    //----------------------------------

    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get measuredHeight():Number
    {
        if (bitmapData)
            return bitmapData.height
        
        return 0;
    }

    //----------------------------------
    //  measuredWidth
    //----------------------------------

    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get measuredWidth():Number
    {
        if (bitmapData)
            return bitmapData.width;
        
        return 0;
    }

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4.1
     */
    public function invalidateLayoutDirection():void
    {
        var p:DisplayObjectContainer = parent;

        // We check the closest parent's layoutDirection property
        // to create or destroy layoutFeatures if needed.
        while (p)
        {
            if (p is ILayoutDirectionElement)
            {
                // mirror is true if our layoutDirection differs from our parent's.
                var mirror:Boolean = _layoutDirection != null && 
                    ILayoutDirectionElement(p).layoutDirection != null &&
                    (_layoutDirection != ILayoutDirectionElement(p).layoutDirection);
                
                // If our layoutDirection is different from our parent's and if it used to
                // be the same, create layoutFeatures to handle mirroring.
                if (mirror && layoutFeatures == null)
                {
                    initAdvancedLayoutFeatures();
                    if (layoutFeatures != null)
                    {
                        layoutFeatures.mirror = mirror;
                        validateTransformMatrix();
                    }
                }
                else if (!mirror && layoutFeatures)
                {
                    // If our layoutDirection is not different from our parent's and if
                    // it used to be different, then recover our matrix and remove layoutFeatures.
                    layoutFeatures.mirror = mirror;
                    validateTransformMatrix();
                    layoutFeatures = null;
                }
                
                break;
            }
            
            p = p.parent;
        }
    }

    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function move(x:Number, y:Number):void
    {
        this.x = x;
        this.y = y;
    }

    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function setActualSize(newWidth:Number, newHeight:Number):void
    {
        width = newWidth;
        height = newHeight;
    }
    
    /**
     *  @private
     */
    private function addedHandler(event:Event):void
    {
        invalidateLayoutDirection();
    }
    
    /**
     *  @private
     *  Initializes AdvancedLayoutFeatures for this asset when mirroring.
     */
    private function initAdvancedLayoutFeatures():void
    {
        // Get AdvancedLayoutFeatures if it exists.
        if (layoutFeaturesClass == null)
        {
            var appDomain:ApplicationDomain = ApplicationDomain.currentDomain;
            
            if (appDomain.hasDefinition("mx.core::AdvancedLayoutFeatures"))
                layoutFeaturesClass = Class(appDomain.getDefinition("mx.core::AdvancedLayoutFeatures"));
            
            // Get MatrixUtil class if it exists
            if (MatrixUtilClass == null)
            {
                if (appDomain.hasDefinition("mx.utils::MatrixUtil"))
                    MatrixUtilClass = Class(appDomain.getDefinition("mx.utils::MatrixUtil"));
            }
        }
        
        if (layoutFeaturesClass != null)
        {
            var features:IAssetLayoutFeatures = new layoutFeaturesClass();
            
            features.layoutScaleX = scaleX;
            features.layoutScaleY = scaleY;
            features.layoutScaleZ = scaleZ;
            features.layoutRotationX = rotationX;
            features.layoutRotationY = rotationY;
            features.layoutRotationZ = rotation;
            features.layoutX = x;
            features.layoutY = y;
            features.layoutZ = z;
            features.layoutWidth = width;  // for the mirror transform
            _height = height;  // for backing storage
            layoutFeatures = features;
        }
    }
    
    /**
     *  @private
     *  Applies the transform matrix calculated by AdvancedLayoutFeatures 
     *  so that this bitmap will not be mirrored if a parent is mirrored.
     */
    private function validateTransformMatrix():void
    {
        if (layoutFeatures != null)
        {
            if (layoutFeatures.is3D)
                super.transform.matrix3D = layoutFeatures.computedMatrix3D;
            else
                super.transform.matrix = layoutFeatures.computedMatrix;
        }
    }
}

}
