<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx"
         alpha="0">
    
    <fx:Metadata>
        [DefaultProperty("children")]
    </fx:Metadata>
    
    <fx:Declarations>
        <mx:Fade id="showEffect" duration=".2" alphaFrom="0" alphaTo="1"/>
        <mx:Fade id="hideEffect" duration=".2" alphaFrom="1" alphaTo="0" effectEnd="hideEffectEnd()"/>
    </fx:Declarations>
    
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.core.IFlexDisplayObject;
            import mx.core.IVisualElement;
            import mx.core.UIComponent;
            import mx.events.FlexEvent;
            import mx.managers.PopUpManager;
            
            public var anchor:DisplayObject;
            
            public static var X_ALIGN_CENTER:Object = 
                {getAnchorPoint : globalAnchorCenter,
                    getToolTipShift : getXShiftCenter};
            
            [Bindable]public static var X_ALIGN_LEFT:Object = 
                {getAnchorPoint : globalAnchorLeft,
                    getToolTipShift : getXShiftLeft};
            
            [Bindable]public static var X_ALIGN_RIGHT:Object = 
                {getAnchorPoint : globalAnchorRight,
                    getToolTipShift : getXShiftRight};
            
            public static var Y_ALIGN_CENTER:Object = 
                {getToolTipShift : getYShiftCenter};
            
            public static var Y_ALIGN_ABOVE:Object = 
                {getToolTipShift : getYShiftAbove};
            
            public static var Y_ALIGN_BELOW:Object = 
                {getToolTipShift : getYShiftBelow};
            
            [Bindable]public var xAlignment:Object = X_ALIGN_CENTER;
            
            [Bindable]public var yAlignment:Object = Y_ALIGN_ABOVE;
            
            // For tooltips that just need a single label property
            [Bindable]public var label:String;
            
            // For TitleListTooltip
            [Bindable]public var title:String;
            
            // For TitleListTooltip
            [Bindable]public var list:ArrayCollection;
            
            // Amount of padding between anchor and element
            public var padding:int = 10;
            
            private function hideEffectEnd():void {
                PopUpManager.removePopUp(this as IFlexDisplayObject);
            }
            
            public function remove():void {
                hideEffect.alphaFrom = alpha;
                hideEffect.play([this]);
            }
            
            public function init():void {
                updatePosition();
                showEffect.play([this]);
            }
            
            private function updatePosition():void {
                var p:Point = xAlignment.getAnchorPoint(anchor);
                x = p.x + xAlignment.getToolTipShift(this, padding);
                y = p.y + yAlignment.getToolTipShift(this, padding);
            }
            
            public function setPointerLocation(p:Point):void
            {
                
            }
            
            private static function calcGlobalPoint(anchor:UIComponent, x:int, y:int):Point {
                return UIComponent(anchor.parent).contentToGlobal(new Point(x, y));
            }
            
            private static function globalAnchorCenter(anchor:UIComponent):Point {
                return calcGlobalPoint(anchor, anchor.x + (anchor.width / 2), anchor.y);
            }
            
            private static function globalAnchorLeft(anchor:UIComponent):Point {
                return calcGlobalPoint(anchor, anchor.x, anchor.y);
            }
            
            private static function globalAnchorRight(anchor:UIComponent):Point {
                return calcGlobalPoint(anchor, anchor.x + anchor.width, anchor.y);
            }
            
            private static function getXShiftCenter(tt:AdvancedToolTip, padding:int):int {
                return -tt.width / 2;
            }
            
            private static function getXShiftRight(tt:AdvancedToolTip, padding:int):int {
                return padding;
            }
            
            private static function getXShiftLeft(tt:AdvancedToolTip, padding:int):int {
                return -tt.width - padding;
            }
            
            private static function getYShiftCenter(tt:AdvancedToolTip, padding:int):int {
                return (tt.anchor.height / 2) - (tt.height / 2);
            }
            
            private static function getYShiftAbove(tt:AdvancedToolTip, padding:int):int {
                return -tt.height - padding;
            }
            
            private static function getYShiftBelow(tt:AdvancedToolTip, padding:int):int {
                return tt.anchor.height + padding;
            }
            
            private var _children:Array = [];
            private var _childrenChanged:Boolean = false;
            
            public function get children():Array {
                return _children;
            }
            
            public function set children(value:*):void {
                if(value is DisplayObject)
                    _children = [value];
                else
                    _children = value;
                
                _childrenChanged = true;
                invalidateProperties();
            }
            
            protected override function commitProperties():void {
                super.commitProperties();
                
                if(_childrenChanged) {
                    _children.map(function(child:IVisualElement,...rest):void {
                        addElement(child);
                    });
                    _childrenChanged = false;
                }
            }
            
            override protected function updateDisplayList(w:Number, h:Number):void {
                super.updateDisplayList(w,h);
                updatePosition();
            }
        ]]>
    </fx:Script>
</s:Group>