package com.lafabrick.uigfx.geom
{
    import flash.geom.Point;
    
    import spark.core.DisplayObjectSharingMode;
    import spark.primitives.supportClasses.GraphicElement;
    
    /**
     * Point with associated constraint values
     * 
     * @description
     * <p>The constraint values are not taken into account directly in the couple of properties x/y.<br />
     * The method getConstraintPoint() calculates and returns the point x/y, according to constraint values, compared to a target GraphicElement.</p>
     * 
     * @author Fabien Bizot
     * 
     * @langversion 3.0
     * @playerversion Flash 10
     * @playerversion AIR 1.5
     * @productversion Flex 4
     * 
     */
    public class ConstraintPoint extends Point
    {
        /**
         * Constructor
         */
        public function ConstraintPoint(x:Number=0, y:Number=0)
        {
            super(x, y);
        }
        
        /**
         * @private
         */
        private var _top : Number;
        /**
         * @private
         */
        private var _bottom : Number;
        /**
         * @private
         */
        private var _left : Number;        
        /**
         * @private
         */
        private var _right : Number;
        /**
         * @private
         */
        private var _horizontalCenter: Number;    
        /**
         * @private
         */
        private var _verticalCenter: Number;
        
        /**
         * HorizontalCenter constraint value
         */
        public function get horizontalCenter():Number
        {
            return _horizontalCenter;
        }
        /**
         * @private
         */
        public function set horizontalCenter(value:Number):void
        {
            _horizontalCenter = value;
        }
        /**
         * VerticalCenter constraint value
         */
        public function get verticalCenter():Number
        {
            return _verticalCenter;
        }
        /**
         * @private
         */
        public function set verticalCenter(value:Number):void
        {
            _verticalCenter = value;
        }
        /**
         * Top constraint value
         */
        public function get top():Number
        {
            return _top;
        }
        /**
         * @private
         */
        public function set top(value:Number):void
        {
            _top = value;
        }
        /**
         * Bottom constraint value
         */
        public function get bottom():Number
        {
            return _bottom;
        }
        /**
         * @private
         */
        public function set bottom(value:Number):void
        {
            _bottom = value;
        }
        /**
         * Left constraint value
         */
        public function get left():Number
        {
            return _left;
        }
        /**
         * @private
         */
        public function set left(value:Number):void
        {
            _left = value;
        }
        /**
         * Right constraint value
         */
        public function get right():Number
        {
            return _right;
        }
        /**
         * @private
         */
        public function set right(value:Number):void
        {
            _right = value;
        }
        
        /**
         * Calculates and returns the point x/y, according to constraint values, compared to a target GraphicElement.
         */
        public function getConstraintPoint( graphicElement : GraphicElement ) : Point
        {
            var px : Number = 0;
            var py : Number = 0;
            
            var xOffset : Number;
            var yOffset : Number;
            
            if (graphicElement.displayObjectSharingMode == DisplayObjectSharingMode.OWNS_UNSHARED_OBJECT) {
                xOffset = 0;
                yOffset = 0;
            }
            else {
                xOffset = graphicElement.postLayoutTransformOffsets ? graphicElement.x + graphicElement.postLayoutTransformOffsets.x : graphicElement.x;
                yOffset = graphicElement.postLayoutTransformOffsets ? graphicElement.y + graphicElement.postLayoutTransformOffsets.y : graphicElement.y;
            }
            
            // Calcutates y position
            if( !isNaN( top ) ) {
                py = yOffset + top;
            }
            else if( !isNaN( bottom ) ) {
                py = yOffset + graphicElement.height - bottom;
            }
            else if( !isNaN( verticalCenter ) ) {
                py = ( yOffset + graphicElement.height ) / 2 + verticalCenter;
            }
            else {
                py = yOffset + y;
            }
            
            // Calcutates x position
            if( !isNaN( left ) ) {
                px = xOffset + left;
            }
            else if( !isNaN( right ) ) {
                px = xOffset + graphicElement.width - right;
            }
            else if( !isNaN( horizontalCenter ) ) {
                px = ( xOffset + graphicElement.width ) / 2 + horizontalCenter;
            }
            else {
                px = xOffset + x;
            }
            
            return new Point( px, py );
        }
    }
}