﻿
/// <reference name="MicrosoftAjax.debug.js" />
/// <reference name="MicrosoftAjaxTimer.debug.js" />
/// <reference name="MicrosoftAjaxWebForms.debug.js" />
/// <reference name="AjaxControlToolkit.ExtenderBase.BaseScripts.js" assembly="AjaxControlToolkit" />
/// <reference name="AjaxControlToolkit.Common.Common.js" assembly="AjaxControlToolkit" />
/// <reference name="AjaxControlToolkit.HoverExtender.HoverBehavior.js" assembly="AjaxControlToolkit" />
/// <reference name="AjaxControlToolkit.Compat.Timer.Timer.js" assembly="AjaxControlToolkit" />
/// <reference name="AjaxControlToolkit.Animation.Animations.js" assembly="AjaxControlToolkit" />
/// <reference name="AjaxControlToolkit.Animation.AnimationBehavior.js" assembly="AjaxControlToolkit" />
/// <reference name="AjaxControlToolkit.PopupExtender.PopupBehavior.js" assembly="AjaxControlToolkit" />

Type.registerNamespace('CustomControls.Common.ExtenderControls');

CustomControls.Common.ExtenderControls.ZoomImageBehavior = function(element) 
{
    /// <summary>
    /// Constructor
    /// </summary>
    
    CustomControls.Common.ExtenderControls.ZoomImageBehavior.initializeBase(this, [element]);

    // Encapsulated behaviors
    this._popupBehavior = null;
    
    // Handler delegates    
    this._unhoverHandler = null;
    this._hoverHandler = null;
    this._moveHandler = null;
    this._zoomImageLoadHandler = null;
    this._clickHandler = null;
    
    //Properties
    this._popupElement = null;
    this._zoomBox = null;
    this._zoomBoxImage = null;
    this._zoomImage = null;
    this._zoomImageSrc = null;
    this._opacity = null;
    this._offsetX = 0;
    this._offsetY = 0;
    this._popupPosition = null;
    this._fixedZoomBoxSize = true;
    this._onClickScript = null;
    this._relative = false;
    this._suspended = false;
    
    // internal
    this._inHover = false;
    this._active = false;
    this._elementBounds = null;
    this._zoomImageBounds = null;
    this._zoomBoxBounds = null;
    this._scale = null;
    this._zoomBoxOffsetX = null;
    this._zoomBoxOffsetY = null;
    this._dragArea = null;
    this._zbBorderLeft = null;
    this._zbBorderTop = null;
}

CustomControls.Common.ExtenderControls.ZoomImageBehavior.prototype = 
{
    initialize : function() 
    {
        /// <summary>
        /// Initializer
        /// </summary>
        CustomControls.Common.ExtenderControls.ZoomImageBehavior.callBaseMethod(this, 'initialize');

        // set up our delegates and handlers
        this._hoverHandler = Function.createDelegate(this, this._onItemHover);
        this._unhoverHandler = Function.createDelegate(this, this._onItemOut);
        this._moveHandler = Function.createDelegate(this, this._onMove);
        this._zoomImageLoadHandler = Function.createDelegate(this, this._onZoomImageLoad);
        this._clickHandler = Function.createDelegate(this, this._onClick);

        $addHandler(this.get_element(), "mouseover", this._hoverHandler);
        if(this._zoomBox)
        {
            $addHandler(this._zoomBox, "mouseover", this._hoverHandler);
            $addHandler(this._zoomBox, "mouseout", this._unhoverHandler);
            $addHandler(this._zoomBox, "click", this._clickHandler);
            
            // AddZoomBoxImage
            this._zoomBoxImage = document.createElement('img');
            this._zoomBox.appendChild(this._zoomBoxImage);
        
            this._zoomBoxImage.style.border = '';
            this._zoomBoxImage.style.margin = '';
            this._zoomBoxImage.style.padding = '';
            this._zoomBoxImage.style.position = 'absolute';
        }

        if (this._popupElement) 
        {
            // setup the popup behavior
            this._popupBehavior = $create(AjaxControlToolkit.PopupBehavior, { "id":this.get_id()+"_PopupBehavior" }, null, null, this._popupElement);
            if (this._popupPosition) 
                this._popupBehavior.set_positioningMode(CustomControls.Common.ExtenderControls.ZoomImagePopupPosition.Absolute);
            else 
                this._popupBehavior.set_positioningMode(CustomControls.Common.ExtenderControls.ZoomImagePopupPosition.Center);

            if(!this._zoomImage)
            {
                // AddZoomImage
                this._zoomImage = document.createElement('img');
                this._popupElement.appendChild(this._zoomImage);
                
                this._zoomImage.style.border = '';
                this._zoomImage.style.margin = '';
                this._zoomImage.style.padding = '';
                this._zoomImage.style.position = 'absolute';
            }
            $addHandler(this._zoomImage, "load", this._zoomImageLoadHandler);                
        }
    },

    dispose : function() 
    {
        /// <summary>
        /// Dispose
        /// </summary>
        if (this._popupBehavior) 
        {
            this._popupBehavior.dispose();
            this._popupBehavior = null;
        }

        if (this._popupElement) 
        {
            if(this._zoomImage)
            {
                $removeHandler(this._zoomImage, "load", this._zoomImageLoadHandler);
                this._zoomImage=null;
            }
            this._popupElement = null;
        }

        if (this._zoomBox)
        {     
            if(this._zoomBoxImage)
            {
                this._zoomBox.removeChild(this._zoomBoxImage);
                this._zoomBoxImage = null;
            }
            $removeHandler(this._zoomBox, "mouseover", this._hoverHandler);
            $removeHandler(this._zoomBox, "mouseout", this._unhoverHandler);  
            $removeHandler(this._zoomBox, "click", this._clickHandler); 
            this._zoomBox = null;
        }     

        if(this.get_element())
            $removeHandler(this.get_element(), "mouseover", this._hoverHandler);

        CustomControls.Common.ExtenderControls.ZoomImageBehavior.callBaseMethod(this, 'dispose');
    },

    _getLeftOffset : function() {
        /// <summary>
        /// Get the left offset of the popup
        /// </summary>
        /// <returns type="Number" integer="true">
        /// Left offset of the popup (in pixels)
        /// </returns>
 
        var defaultLeft = $common.getLocation(this.get_element()).x;
        var offsetLeft = $common.getLocation(this.get_popupElement().offsetParent).x;
        var delta = 0;
        
        // this offset is always relative to the left edge of the hover element.
        switch(this._popupPosition) {
            case CustomControls.Common.ExtenderControls.ZoomImagePopupPosition.Left:
                // if it's positioned left, it's the width of the popup plus the offset
                delta = (-1 * this._popupElement.offsetWidth);
                break;
            case CustomControls.Common.ExtenderControls.ZoomImagePopupPosition.Right:
                // if it's to the right, it's the width of the hover element plus the offset.
                delta = this.get_element().offsetWidth;
                break; 
        }
        return delta + defaultLeft - offsetLeft + this._offsetX;
    },
    
    _getTopOffset : function() {
        /// <summary>
        /// Get the top offset of the popup
        /// </summary>
        /// <returns type="Number" integer="true">
        /// Left offset of the popup (in pixels)
        /// </returns>

        var defaultTop = $common.getLocation(this.get_element()).y;
        var offsetTop = $common.getLocation(this.get_popupElement().offsetParent).y;
        var delta = 0;
    
        // this offset is always relative to the top edge of the hover element.
        switch(this._popupPosition) {
            case CustomControls.Common.ExtenderControls.ZoomImagePopupPosition.Top:
                // if it's Top positioned, it's the height of the popup plus the offset.
                delta = (-1 * this._popupElement.offsetHeight);
                break;
            case CustomControls.Common.ExtenderControls.ZoomImagePopupPosition.Bottom:
                // if it's bottom positioned it's the height of the hover element plus the offset
                delta = this.get_element().offsetHeight;
                break;
        }
        return defaultTop - offsetTop + delta + this._offsetY;       
    },
    
    _setZoomPosition : function(mouseX, mouseY)
    {
        /// <summary>
        /// Calculates and sets the zoomposition
        /// </summary>

        if(!this._active)
            return;
            
        var x = mouseX - this._zoomBoxOffsetX; 
        var y = mouseY - this._zoomBoxOffsetY;
        var left = x > this._dragArea.right ? this._dragArea.right : x < this._dragArea.left ? 0 : x;
        var top = y > this._dragArea.bottom ? this._dragArea.bottom : y < this._dragArea.top ? 0 : y;

        if(this._relative)
            $common.setStyle(this._zoomBox, {left:left+'px', top:top+'px'});
        else
            $common.setStyle(this._zoomBox, {left:left+this._elementBounds.x+'px', top:top+this._elementBounds.y+'px'});            
        $common.setStyle(this._zoomBoxImage, {left:-left-this._zbBorderLeft+'px', top:-top-this._zbBorderTop+'px'});                    
        $common.setStyle(this._zoomImage, {left:parseInt((-left-this._zbBorderLeft)*this._scale) + 'px', top:parseInt((-top-this._zbBorderTop)*this._scale) + 'px'});            
    },
        
    _onItemHover : function(e)
    {
		/// <summary>
        /// Display the popup when the target is hovered over
        /// </summary>
        if (this._suspended) return;

        if (this._inHover) return;

        this._inHover = true;

        this._elementBounds = $common.getBounds(this.get_element());
        this._zoomImageBounds = null;
        this._zoomBoxBounds = null;

        $addHandler(document.body, 'mousemove', this._moveHandler);
			
	    this._zoomBoxImage.src = this.get_element().src;	
	    if(Sys.Browser.Safari)
	        this._zoomImage.src = null;
        this._zoomImage.src = this._zoomImageSrc;
    },
    
    _onZoomImageLoad: function(e)
    {
        if (this._suspended) return;
        
        $common.setElementOpacity(this.get_element(), this._opacity);        		

		this._popupBehavior.show();
		if ($common.getCurrentStyle(this._popupElement, 'display') == 'none') 
			this._popupElement.style.display = 'block';

		this._popupBehavior.set_x(this._getLeftOffset());
        this._popupBehavior.set_y(this._getTopOffset());
        		
		$common.setVisible(this._zoomBox, true);
		
        this._zoomImageBounds = $common.getBounds(this._zoomImage);
        this._scale = this._zoomImageBounds.width / this._elementBounds.width;
        var newWidth = 0;
        var newHeight = 0;
        var elementToChange = null;
                
        if(this._fixedZoomBoxSize)
        {
            elementToChange = this._popupElement;
            this._zoomBoxBounds = $common.getBounds(this.get_zoomBox());
           
            newWidth = parseInt(this._zoomBoxBounds.width * this._scale);
            newHeight = parseInt(this._zoomBoxBounds.height * this._scale);
        }
        else
        {
            elementToChange = this.get_zoomBox()   
            var popupBounds = $common.getBounds(this._zoomImage.parentNode);
            
            newWidth = parseInt(popupBounds.width / this._scale);
            newHeight = parseInt(popupBounds.height / this._scale);
        }
        
        if(newWidth > 0 && newHeight > 0)
            $common.setContentSize(elementToChange, { 
                    width : newWidth,
                    height : newHeight});      
                      
        this._zoomBoxBounds = $common.getBounds(this.get_zoomBox()); 

        this._zoomBoxOffsetX = parseInt(this._zoomBoxBounds.width / 2) + this._elementBounds.x;
        this._zoomBoxOffsetY = parseInt(this._zoomBoxBounds.height / 2) + this._elementBounds.y;
        this._zbBorderLeft = $common.getBorderWidth(this._zoomBox, AjaxControlToolkit.BoxSide.Right);
        this._zbBorderTop = $common.getBorderWidth(this._zoomBox, AjaxControlToolkit.BoxSide.Top);

        this._dragArea = {left:0, right: this._elementBounds.width - this._zoomBoxBounds.width,
                            top: 0, bottom: this._elementBounds.height - this._zoomBoxBounds.height };
        
        this._active = true;                 
    },
    
    _onMove : function(e)
    {
        /// <summary>
        /// Move handler function
        /// </summary>
        if (this._suspended) return;
        
        if(!this._active)
            return;
        
        var offset = this._getScrollOffset(this.get_element(), true);
        
        if(!$common.containsPoint($common.getBounds(this.get_element()), e.clientX + offset.x, e.clientY + offset.y))
            this._onItemOut();
        else
            this._setZoomPosition(e.clientX + offset.x, e.clientY + offset.y);
    },
    
    _onItemOut : function()
    {
		/// <summary>
        /// Hide the popup when the target is no longer hovered
        /// </summary>
        if(this._inHover)
            $removeHandler(document.body, 'mousemove', this._moveHandler);
        this._active = false;
        this._inHover = false;
        this._zoomImageBounds = null;
        this._zoomBoxBounds = null;
        
        $common.setElementOpacity(this.get_element(), 1); 
        
        this._popupBehavior.hide();
        $common.setVisible(this._zoomBox, false);
    },
    
    _onClick : function()
    {
        if (this._suspended) return;
        
        if(this._onClickScript)
            eval(this._onClickScript);
    },
    
    _getScrollOffset : function(element, recursive) 
    {
        var left = element.scrollLeft;
        var top = element.scrollTop;
        if (recursive) 
        {
            var parent = element.parentNode;
            while (parent != null && parent.scrollLeft != null) 
            {
                left += parent.scrollLeft;
                top += parent.scrollTop;
                // Don't include anything below the body.
                if (parent == document.body && (left != 0 && top != 0))
                    break;
                parent = parent.parentNode;
            }
        }
        return { x: left, y: top };
    },
    
    get_popupElement : function() 
    {
        /// <param name="element" type="Object">Dom element associated with this behavior.</param>
        return this._popupElement;
    },
    
    set_popupElement : function(element) 
    {
        /// <param name="element" type="Object">Dom element associated with this behavior.</param>
        if (this._popupElement != element) 
        {
            this._popupElement = element;
            if (this.get_isInitialized() && this._hoverBehavior) 
					this._hoverBehavior.set_hoverElement(this._popupElement);
            this.raisePropertyChanged('popupElement');
        }
    },
    
    get_zoomImageSrc : function() 
    {
        /// <param name="value" type="string">Url to zoom image</param>
        return this._zoomImageSrc;
    },

    set_zoomImageSrc : function(value) 
    {
        /// <param name="value" type="string">Url to zoom image</param>
        if (this._zoomImageSrc != value) 
        {
            this._zoomImageSrc = value;
            this.raisePropertyChanged('zoomImageSrc');
        }
    },
    
    get_onClickScript : function() 
    {
        /// <param name="value" type="string">Script to run onclick</param>
        return this._onClickScript;
    },
    
    set_onClickScript : function(value)
    {
        /// <param name="value" type="string">Script to run onclick</param>
        if (this._onClickScript != value) 
        {
            this._onClickScript = value;
            this.raisePropertyChanged('onClickScript');
        }
    },
        
    get_opacity : function() 
    {
        /// <param name="value" type="double">Opacity outside zoombox</param>
        return this._opacity;
    },

    set_opacity : function(value) 
    {
        /// <param name="value" type="double">Opacity outside zoombox</param>
        if (this._opacity != value) 
        {
            this._opacity = value;
            this.raisePropertyChanged('opacity');
        }
    },
    
    get_zoomBox : function() 
    {
        /// <param name="element" type="Object">Dom element associated with this behavior.</param>   
        return this._zoomBox;
    },
    
    set_zoomBox : function(element) 
    {
        /// <param name="element" type="Object">Dom element associated with this behavior.</param>
        if (this._zoomBox != element) 
        {
            this._zoomBox = element;
            this.raisePropertyChanged('zoomBox');
        }
    },
    
    get_zoomImage : function() 
    {
        /// <param name="element" type="Object">Dom element associated with this behavior.</param>   
        return this._zoomBox;
    },
    
    set_zoomImage : function(element) 
    {
        /// <param name="element" type="Object">Dom element associated with this behavior.</param>
        if (this._zoomImage != element) 
        {
            this._zoomImage = element;
            this.raisePropertyChanged('zoomImage');
        }
    },
    
    get_offsetX : function() 
    {
        /// <value type="Number" integer="true">
        /// The number of pixels to offset the popup from it's default position horizontally
        /// </value>
        return this._offsetX;
    },
    
    set_offsetX : function(value) 
    {
        if (this._offsetX != value) 
        {
            this._offsetX = value;
            this.raisePropertyChanged('OffsetX');
        }
    },
    
    get_offsetY : function() 
    {
        /// <value type="Number" integer="true">
        /// The number of pixels to offset the popup from it's default position vertically
        /// </value>
        return this._offsetY;
    },
    
    set_offsetY : function(value) 
    {
        if (this._offsetY != value) 
        {
            this._offsetY = value;
            this.raisePropertyChanged('OffsetY');
        }
    },
    
    get_fixedZoomBoxSize : function() 
    {
        return this._fixedZoomBoxSize;
    },
    
    set_fixedZoomBoxSize : function(value) 
    {
        if (this._fixedZoomBoxSize != value) 
        {
            this._fixedZoomBoxSize = value;
            this.raisePropertyChanged('FixedZoomBoxSize');
        }
    },
    
    get_relative : function() 
    {
        return this._relative;
    },
    
    set_relative : function(value) 
    {
        if (this._relative != value) 
        {
            this._relative = value;
            this.raisePropertyChanged('Relative');
        }
    },
    
    get_popupPosition : function() 
    {
        /// <value type="CustomControls.Common.ExtenderControls.ZoomImagePopupPosition">
        /// Where the popup should be positioned relative to the target control.
        /// Can be Left (Default), Right, Top, Bottom, Center.
        /// </value>
        return this._popupPosition;
    },
    
    set_popupPosition : function(value) 
    {
        if (this._popupPosition != value) 
        {
            this._popupPosition = value;
            this.raisePropertyChanged('PopupPosition');
        }
    },
    
    get_suspended : function()
    {
        return this._suspended;
    },
    
    set_suspended : function(value)
    {
        if(this._suspended != value)
        {
            this._suspended = value;
            this.raisePropertyChanged('Suspended');
        }
    }
}

CustomControls.Common.ExtenderControls.ZoomImageBehavior.registerClass('CustomControls.Common.ExtenderControls.ZoomImageBehavior', AjaxControlToolkit.BehaviorBase);

CustomControls.Common.ExtenderControls.ZoomImagePopupPosition = function() {
    /// <summary>
    /// Where the popup should be positioned relative to the target control
    /// </summary>
    /// <field name="Center" type="Number" integer="true" />
    /// <field name="Top" type="Number" integer="true" />
    /// <field name="Left" type="Number" integer="true" />
    /// <field name="Bottom" type="Number" integer="true" />
    /// <field name="Right" type="Number" integer="true" />
    throw Error.invalidOperation();
}
CustomControls.Common.ExtenderControls.ZoomImagePopupPosition.prototype = {
    Center: 0,
    Top: 1,
    Left: 2,
    Bottom: 3,
    Right: 4
}
CustomControls.Common.ExtenderControls.ZoomImagePopupPosition.registerEnum('CustomControls.Common.ExtenderControls.ZoomImagePopupPosition');

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();