﻿/// <reference name="MicrosoftAjax.debug.js" />
/// <reference name="MicrosoftAjaxTimer.debug.js" />
/// <reference name="MicrosoftAjaxWebForms.debug.js" />

Type.registerNamespace("ZikBay.Web.UI.Controls");

// --------------------------------------------------------------
// HoverTooltip class, derived from Sys.Sys.UI.Control
// --------------------------------------------------------------

ZikBay.Web.UI.Controls.HoverTooltip = function(element) {
    //#region Constructor
    ZikBay.Web.UI.Controls.HoverTooltip.initializeBase(this, [element]);

    this._htmlTemplate = "";
    this._defaultTooltipText = "";
    this._defaultTooltipTitle = "";
    this._controls = [];
    this._offsetX = 15;
    this._offsetY = 15;
    
    this._moveDelegate = Function.createDelegate(this, this._move);
    this._cleanupInfo = {};
    this._activeWebControl = null;
    
    this._lastX = -5000;
    this._lastY = -5000;
    //#endregion
}

ZikBay.Web.UI.Controls.HoverTooltip.prototype = {
    // Overrides
    //#region
    //#region Initialize
    initialize: function() {
        ZikBay.Web.UI.Controls.HoverTooltip.callBaseMethod(this, 'initialize');
        // attach events to controls collection
        for(var i=0; i<this._controls.length; i++) {
            var webControl = $get(this._controls[i]);
            if(webControl) {
                this.addTooltipControl(webControl);
            }
        }
        // attach mousemove event handler for whole document
        $addHandler(document, "mousemove", this._moveDelegate);

        // show tooltip correctly in ie6
        if (Sys.Browser.agent == Sys.Browser.InternetExplorer && Sys.Browser.version < 7) 
        {
        
            var htIFrame = document.createElement("iframe");
            htIFrame.id="htIFrame"
            htIFrame.frameBorder = 0;
            htIFrame.src = "javascript:false;";
            htIFrame.style.display = "none";
            htIFrame.style.position = "absolute";
            htIFrame.style.filter = "progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)";
            htIFrame.style.zIndex = this.get_element().style.zIndex-1;
            this.get_element().htIFrame = this.get_element().parentNode.insertBefore(htIFrame, this.get_element());
        }
    },
    //#endregion

    //#region Dispose
    dispose: function() {
        var element = this.get_element();
        element.htIFrame = null;
        $removeHandler(document, "mousemove", this._moveDelegate);
        for(var key in this._cleanupInfo) {
            if(key && $get(key)) {
                var webControl = $get(key);
                this.removeTooltipControl(webControl);
            }
        }
        this._cleanupInfo = null;
        ZikBay.Web.UI.Controls.HoverTooltip.callBaseMethod(this, 'dispose');
    },
    //#endregion
    //#endregion
    
    // Properties
    //#region
    get_htmlTemplate: function() {
        return this._htmlTemplate;
    },
    set_htmlTemplate: function(value) {
        if (this._htmlTemplate !== value) {
            this._htmlTemplate = value;
            this.raisePropertyChanged('htmlTemplate');
        }
    },
    get_defaultTooltipText: function() {
        return this._defaultTooltipText;
    },
    set_defaultTooltipText: function(value) {
        if (this._defaultTooltipText !== value) {
            this._defaultTooltipText = value;
            this.raisePropertyChanged('defaultTooltipText');
        }
    },
    get_defaultTooltipTitle: function() {
        return this._defaultTooltipTitle;
    },
    set_defaultTooltipTitle: function(value) {
        if (this._defaultTooltipTitle !== value) {
            this._defaultTooltipTitle = value;
            this.raisePropertyChanged('defaultTooltipTitle');
        }
    },
    get_controls: function() {
        return this._controls;
    },
    set_controls: function(value) {
        if (this._controls !== value) {
            this._controls = value;
            this.raisePropertyChanged('controls');
        }
    },
    get_offsetX: function() {
        return this._offsetX;
    },
    set_offsetX: function(value) {
        if (this._offsetX !== value) {
            this._offsetX = value;
            this.raisePropertyChanged('offsetX');
        }
    },
    get_offsetY: function() {
        return this._offsetY;
    },
    set_offsetY: function(value) {
        if (this._offsetY !== value) {
            this._offsetY = value;
            this.raisePropertyChanged('offsetY');
        }
    },
    //#endregion
    
    // Private functions
    //#region
    _getClientBounds : function() {
        var clientWidth;
        var clientHeight;
        switch(Sys.Browser.agent) {
            case Sys.Browser.InternetExplorer:
                clientWidth = document.documentElement.clientWidth;
                clientHeight = document.documentElement.clientHeight;
                break;
            case Sys.Browser.Safari:
                clientWidth = window.innerWidth;
                clientHeight = window.innerHeight;
                break;
            case Sys.Browser.Opera:
                clientWidth = Math.min(window.innerWidth, document.body.clientWidth);
                clientHeight = Math.min(window.innerHeight, document.body.clientHeight);
                break;
            default:  // Sys.Browser.Firefox, etc.
                clientWidth = Math.min(window.innerWidth, document.documentElement.clientWidth);
                clientHeight = Math.min(window.innerHeight, document.documentElement.clientHeight);
                break;
        }
        var scrollLeft = (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
        var scrollTop = (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
        return new Sys.UI.Bounds(scrollLeft, scrollTop, clientWidth, clientHeight);
    },
    _constructShowDelegate : function(webControl) {
        var title = webControl.title;
        var tooltipTitle = "";
        if(!title || title.toString() == "") {
            if(webControl && webControl.attributes && webControl.attributes.getNamedItem("title")) {
                title = webControl.attributes.getNamedItem("title").value;
            }
        }
        if(webControl && webControl.attributes && webControl.attributes.getNamedItem("tooltiptitle")) {
            tooltipTitle = webControl.attributes.getNamedItem("tooltiptitle").value;
        }
        // pass control related values into handler
        var _showDelegate = Function.createDelegate(
            {
                tooltip:this,
                webControl:webControl,
                title:title,
                tooltipTitle:tooltipTitle
            }, 
            this._show
        );
        webControl.title = "";
        return _showDelegate;
    },
    //#endregion
    
    // Public functions
    //#region
    addTooltipControl : function(webControl) {
        var _showDelegate = this._constructShowDelegate(webControl);
        var _hideDelegate = Function.createDelegate(this, this._hide);
        $addHandler(webControl, "mouseover", _showDelegate);
        $addHandler(webControl, "mouseout", _hideDelegate);
        // remove existing info 
        if(this._cleanupInfo[webControl.id]) {
            this.removeTooltipControl(webControl);
        }
        this._cleanupInfo[webControl.id] =  
            {webControl:webControl,_showDelegate:_showDelegate,_hideDelegate:_hideDelegate}
    },
    removeTooltipControl : function(webControl) {
        if(webControl && webControl.id && this._cleanupInfo) {
            var key = webControl.id;
            var info = this._cleanupInfo[key];
            if(info) {
                try {
                    $removeHandler(info.webControl, "mouseover", info._showDelegate);
                    $removeHandler(info.webControl, "mouseout", info._hideDelegate);
                    info.webControl = null;
                    info._showDelegate = null;
                    info._hideDelegate = null;
                } catch(err) {;}
            }
        }
    },
    show : function(control, tooltipTitle, tooltipText) {
        var delegate = Function.createDelegate(
            {
                tooltip:this,
                webControl:control,
                title:tooltipText,
                tooltipTitle:tooltipTitle
            }, 
            this._show
        );
        delegate.call();
    },
    hide : function() {
        this._hide();
    },
    refresh : function(webControl) {
        if(webControl && webControl.id) {
            var info = this._cleanupInfo[webControl.id];
            if(info) {
                var _showDelegate = this._constructShowDelegate(webControl);
                $removeHandler(info.webControl, "mouseover", info._showDelegate);
                $addHandler(webControl, "mouseover", _showDelegate);
                info._showDelegate = _showDelegate;
                if(
                    this.get_element() && 
                    this.get_element().style.visibility=="visible" &&
                    this._activeWebControl &&
                    this._activeWebControl.id == webControl.id
                  ) {
                    _showDelegate.call();
                }
            }
        }
    },
    //#endregion
    
    // Event handlers
    //#region
    _show : function(args) {
        var webControl = this.webControl;
        var tooltip = this.tooltip;
        var tooltipTitle = this.tooltipTitle;
        var title = this.title;
 
        if(!webControl.disabled) {
            if(title.toString() == "") {
                title = tooltip._defaultTooltipText;
            }
            if(tooltipTitle.toString() == "") {
                tooltipTitle = tooltip._defaultTooltipTitle;
            }
            if(title != "") {
                var contents = String.format(
                    tooltip._htmlTemplate,
                    tooltipTitle,
                    title
                );
                tooltip.get_element().innerHTML = contents;
                tooltip.get_element().style.visibility = "visible";
            }
            tooltip._activeWebControl = webControl;
        }
    },
    _hide : function(args) {
        this.get_element().style.top = -5000 + "px";
        this.get_element().style.left = -5000 + "px";
        this.get_element().style.visibility = "hidden";
        
        //this.get_element().style.visibility = "visible";
        //this.get_element().innerHTML = "";
        if (this.get_element().htIFrame) {
            this.get_element().htIFrame.style.left = this.get_element().style.left;
            this.get_element().htIFrame.style.top  = this.get_element().style.top;
            this.get_element().htIFrame.style.display = "none";
        }
    },
    _move : function(args) {
        if(args && args.clientX && args.clientY) {
            this._lastX = args.clientX;
            this._lastY = args.clientY;
        }
        if(this.get_element() && this.get_element().style.visibility=="visible") {
            var bounds = this._getClientBounds();
            var scrollX = bounds.x;
            var scrollY = bounds.y;
            if(scrollX== undefined)
            {
             scrollX=0;
            }
            if(scrollY== undefined)
            {
             scrollY=0;
            }
            var x = -5000;
            var y = -5000;
            if(args) {
                x = args.clientX+scrollX;
                y = args.clientY+scrollY;
            } else if(this._lastX && this._lastY) {
                x = this._lastX+scrollX;
                y = this._lastY+scrollY;
            }
            var innerWidth = bounds.width;
            var innerHeight = bounds.height;
            if((x + this._offsetX+this.get_element().offsetWidth) >= innerWidth) {
                this.get_element().style.left = (x - 5 - this.get_element().offsetWidth) + "px";
            } else {
                this.get_element().style.left = (x + this._offsetX) + "px";
            }
            
            if(y + this._offsetY + this.get_element().offsetHeight >= innerHeight+scrollY) 
            {
                if((y + 5 - this.get_element().offsetHeight)<=scrollY)
                {
                    this.get_element().style.top =scrollY+ "px";
                }
                else
                {
                    this.get_element().style.top = (y + 5 - this.get_element().offsetHeight)+ "px";
                }
            } 
            else 
            {
                this.get_element().style.top = (y + this._offsetY) + "px";
            }
            
            
//            var mytop=0;
//            if(y + this._offsetY + this.get_element().offsetHeight >= innerHeight+scrollY) {
//                mytop = (y + 5 - this.get_element().offsetHeight) ;
//            } else {
//                mytop= (y + this._offsetY) ;
//            }
//            
//             if(mytop<0)
//            {
//                this.get_element().style.top=0;
//            }
//            else
//            {
//            this.get_element().style.top=mytop;
//            }
           
            
            
            if (this.get_element().htIFrame != null) {
                    this.get_element().htIFrame.style.left = this.get_element().style.left;
                    this.get_element().htIFrame.style.top  = this.get_element().style.top;
                    this.get_element().htIFrame.style.width  = this.get_element().offsetWidth + "px";
                    this.get_element().htIFrame.style.height = this.get_element().offsetHeight + "px";
                    this.get_element().htIFrame.style.display = "block";
            }
        }
    }
    //#endregion
}

ZikBay.Web.UI.Controls.HoverTooltip.registerClass('ZikBay.Web.UI.Controls.HoverTooltip', Sys.UI.Control);
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();