/**
 * @author ryans
 */
(function()
{
    function wheel(event)
    {
        var realDelta;
        
        // normalize the delta
        if (event.wheelDelta) // IE & Opera
            realDelta = event.wheelDelta / 120;
        else if (event.detail) // W3C
			realDelta = -event.detail / 3;
        
        if (!realDelta) {
            return;}
        
        var customEvent = event.element().fire("mouse:wheel", {
            delta: realDelta
        });
        if (customEvent.stopped) event.stop();
    }
    
    document.observe("mousewheel", wheel);
    document.observe("DOMMouseScroll", wheel);
})();

var RsZoomer = Class.create({
    initialize: function(element)
    {
        var defaults = {
            ZoomerWidth: 70,
            ZoomerHeight: 50,
            ZoomWindow: 5,
            MinZoomFactor: 1.5,
            ZoomFactor: 4
        };

        this.options = Object.extend(defaults, arguments[1] ||
        {});
		
        this.displayImg = $(element);
		this.id = 'RsZoomer_'+this.displayImg.id;
		InstanceContainer.RegisterInstance(this);
		this.displayImg.setAttribute('alt', '');
        this.imageHeight = 320;
        this.imageWidth = 320;
        this.container = this.displayImg.up();
        
        this.floaterElement = document.createElement('div');
        Element.setStyle(this.floaterElement, {
            width: this.options.ZoomerWidth + 'px',
            height: this.options.ZoomerHeight + 'px',
            zIndex: Number(this.displayImg.style.zIndex) + 2,
            position: 'absolute',
            borderStyle: 'solid',
            overflow: 'hidden',
            borderWidth: '1px',
            cursor: 'pointer',
            borderColor: '#C1C1C1',
            display: 'none'
        });
        
        this.container.appendChild(this.floaterElement);
        
        this.floaterWidth = this.options.ZoomerWidth;
        this.floaterHeight = this.options.ZoomerHeight;
        
        this.layeredImg = document.createElement('img');
        this.layeredImg.src = ""+this.displayImg.src;
        this.layeredImg.style.position = 'absolute';
        this.floaterElement.appendChild(this.layeredImg);
        
        this.zoomedDiv = document.createElement('div');
		var zoomedStyle = {
            width: (this.options.ZoomerWidth * this.options.ZoomWindow) + 'px',
            height: (this.options.ZoomerHeight * this.options.ZoomWindow) + 'px',
            zIndex: 11,
            backgroundColor: 'white',
            position: 'absolute',
            borderStyle: 'solid',
            overflow: 'hidden',
            borderWidth: '1px',
            borderColor: 'lightgrey',
            cursor: 'pointer',
            display: 'none',
            top: (this.imageHeight - (this.options.ZoomerHeight * this.options.ZoomWindow)) + 'px',
            left: this.imageWidth+3 + 'px'
        };
        Element.setStyle(this.zoomedDiv, zoomedStyle);
        this.container.appendChild(this.zoomedDiv);
        
        this.bgMask = document.createElement('img');
        this.bgMask.src = 'http://mirror.altrec.com/new_includes/images/maskBG.png';
        Element.setStyle(this.bgMask, {
            width: this.imageWidth + 'px',
            height: this.imageHeight + 'px',
			top:'0px',
			left:'0px',
            cursor: 'pointer',
            display: 'none',
            position: 'absolute',
            zIndex: Number(this.displayImg.style.zIndex) + 1
        });
        this.bgMask.setOpacity(.55);
        this.container.appendChild(this.bgMask);
        
		this.loadingDiv = document.createElement('img');
		Element.setStyle(this.loadingDiv, {
			left: ((this.options.ZoomerWidth * this.options.ZoomWindow)/2)-16+'px',
            top: ((this.options.ZoomerHeight * this.options.ZoomWindow)/2)-16 + 'px',
	        zIndex : 1,
            position: 'absolute',
            zIndex: Number(this.displayImg.style.zIndex) + 1
        });
		this.loadingDiv.src = 'http://mirror.altrec.com/images/bigrotation2.gif';
        this.zoomedDiv.appendChild(this.loadingDiv);
		
        this.zoomedImg = document.createElement('img');
		this.validZoom = true;
		if (this.options.largeImgSrc && this.options.largeImgSrc!='') {
	        this.zoomedImg.src = this.options.largeImgSrc;}
		else {
			this.validZoom = false;}
        this.zoomedImg.style.position = 'absolute';
		this.zoomedImg.style.zIndex = 2;
        this.zoomedDiv.appendChild(this.zoomedImg);
        
        this.eventDispalyImgMouseMove = this.moveFloater.bindAsEventListener(this, {
            zooming: false
        });
        Event.observe(this.bgMask, "mousemove", this.eventDispalyImgMouseMove);
        Event.observe(this.displayImg, "mousemove", this.eventDispalyImgMouseMove);
        
        this.mouseOutEvent = this.hideFloater.bindAsEventListener(this, null);
        Event.observe(this.bgMask, "mouseout", this.mouseOutEvent);
        Event.observe(this.floaterElement, "mouseout", this.mouseOutEvent);
        
        this.eventFloaterElement = this.moveFloater.bindAsEventListener(this, {
            zooming: false
        });
        Event.observe(this.floaterElement, "mousemove", this.eventFloaterElement);
        
        
        this.zoomWheelEvent = this.zoomWheel.bindAsEventListener(this, null);
        Event.observe(this.floaterElement, "mouse:wheel", this.zoomWheelEvent);
        
        this.mouseX = -10;
        this.mouseY = -10;
        
    },
	
	RegisterHider : function(element, event)
	{
        Event.observe(element, event, this.mouseOutEvent);
	},
	
	
	SetAssets : function(element, imageSrc, largeImgSrc)
	{
		if (!imageSrc || imageSrc=='' || !largeImgSrc || largeImgSrc == '') 
		{
			this.validZoom = false;
			this.displayImg.style.cursor = "default";
			if (this.SetAssetsComplete) {
				this.SetAssetsComplete(false);}
			return false;
		}
		this.validZoom = true;
		this.floaterElement.style.display = 'none';
        this.zoomedDiv.style.display = 'none';
		this.layeredImg.style.display = 'none';
		
        this.zoomedDiv.removeChild(this.zoomedImg);
		this.zoomedImg = document.createElement('img');
		this.zoomedImg.style.position = 'absolute';
		this.zoomedImg.style.visibility = 'hidden';
		this.zoomedImg.style.zIndex = 2;
		this.options.largeImgSrc = largeImgSrc;
		this.needToSetZoomSrc = true;
        this.zoomedDiv.appendChild(this.zoomedImg);
		
		this.layeredImg.src = imageSrc;
		this.displayImg.style.cursor = "pointer";
		
		if (this.SetAssetsComplete) {
			this.SetAssetsComplete(true);}
		return true;
	},
	
	getZoomUrl : function()
	{
		if (this.options.largeImgSrc) {
			return true;}
		else {
			return false;}
	},
    
    zoomWheel: function(event)
    {
        var delta = 0;
        if (event.memo.delta > 0) 
        {
            if (event.memo.delta < 1) {
                delta = .25;}
            else { 
            	delta = .5;}
        }
        else 
        {
            if (event.memo.delta > -1) {
                delta = -.25;}
            else {
            	delta = -.5;}
        }
        this.options.ZoomFactor += delta;
        if (this.options.ZoomFactor > this.maxZoomFactor) this.options.ZoomFactor = this.maxZoomFactor;
        if (this.options.ZoomFactor < this.options.MinZoomFactor) this.options.ZoomFactor = this.options.MinZoomFactor;
        this.moveFloater(event, {
            zooming: true
        });
        event.stop();
    },
    
    hideFloater: function(event, args)
    {
        var mouseX = Event.pointerX(event);
        var mouseY = Event.pointerY(event);
        var displayImgX = Element.cumulativeOffset(this.displayImg)[0];
        var displayImgY = Element.cumulativeOffset(this.displayImg)[1];
        
        var x = mouseX - displayImgX;
        var y = mouseY - displayImgY;
        
        if (y > 0 && y < this.imageHeight && x > 0 && x < this.imageWidth) 
        {
            this.moveFloater(event, {
                zooming: false
            });
            return;
        }
        
        this.zooming = false;
        this.floaterElement.style.display = 'none';
        this.zoomedDiv.style.display = 'none';
        this.bgMask.style.display = 'none';
        this.displayImg.setOpacity(1);
    },
    
    moveFloater: function(event, args)
    {
		if (!this.validZoom) {
			return;}
			
        this.zooming = true;
		
		if (this.needToSetZoomSrc) 
		{
			this.needToSetZoomSrc = false;
			this.zoomedImg.src = this.options.largeImgSrc;
		}
		
        var mouseX = Event.pointerX(event);
        var mouseY = Event.pointerY(event);
        if (!args.zooming && mouseX == this.mouseX && mouseY == this.mouseY) {
            return;}
        
        if (!isNaN(mouseX) && !isNaN(mouseY)) 
        {
            this.mouseX = mouseX;
            this.mouseY = mouseY;
        }
        
        var floater = this.floaterElement;
        var displayImg = this.displayImg;
        this.bgMask.style.display = 'block';
        this.displayImg.setOpacity(.55);
        
        floater.style.display = 'block';
		this.layeredImg.style.display = 'block';
        
		
        var displayImgX = displayImg.cumulativeOffset().left;// Element.cumulativeOffset(displayImg)[0];
        var displayImgY = displayImg.cumulativeOffset().top;// Element.cumulativeOffset(displayImg)[1];
        
        var x = this.mouseX - displayImgX;
        var y = this.mouseY - displayImgY;
        
        var ySet = true;
        var xSet = true;
        var buffer = 2;
        if (y - (this.floaterHeight / 2) < 0) 
        {
            floater.style.top = '0px';
        }
        else if (y + (this.floaterHeight / 2) > (this.imageHeight - buffer)) 
        {
            floater.style.top = this.imageHeight - buffer - (this.floaterHeight) + 'px';
        }
        else if (y - (this.floaterHeight / 2) >= 0 && y + (this.floaterHeight / 2) <= this.imageHeight) {
            floater.style.top = y - (this.floaterHeight / 2) + 'px';}
        else {
        	ySet = false;}
        
        if (x - (this.floaterWidth / 2) < 0) 
        {
            floater.style.left = '0px';
        }
        else if (x + (this.floaterWidth / 2) > (this.imageWidth - buffer)) 
        {
            floater.style.left = this.imageWidth - buffer - (this.floaterWidth) + 'px';
        }
        else if (x - (this.floaterWidth / 2) >= 0 && x + (this.floaterWidth / 2) <= this.imageWidth) 
        {
            floater.style.left = x - (this.floaterWidth / 2) + 'px';
        }
        else xSet = false;
        
        if (!xSet && !ySet && !args.zooming) 
        { return; }
        
        this.layeredImg.style.left = "-" + floater.style.left;
        this.layeredImg.style.top = "-" + floater.style.top;
        
        if (this.zooming) 
        {
			this._displayZoomedImg();
        }
        else 
        {
            this.hideFloater(event, args);
        }
    },
	
	_displayZoomedImg : function()
	{
		if (!this.zooming) 
        {
			this.zoomedDiv.style.display = 'none';
			return;
        }
		
		if (this.zoomedDiv.style.display == 'none') 
        {
            Effect.Appear(this.zoomedDiv, {
                duration: .5
            });
        }
        if (this.zoomedImg.complete) 
        {
        	var displayImg = this.displayImg;
			var displayImgX = Element.cumulativeOffset(displayImg)[0];
	        var displayImgY = Element.cumulativeOffset(displayImg)[1];
	        
	        var x = this.mouseX - displayImgX;
	        var y = this.mouseY - displayImgY;
			
			if (this.spinning)
			{
				this.spinning = false;
				Effect.Appear(this.zoomedImg, {
                    duration: .25
                });
			}
			this.zoomedImg.style.visibility = 'visible';
            this.currentLargeImgWidth = Element.getWidth(this.zoomedImg);
            this.currentLargeImgHeight = Element.getHeight(this.zoomedImg);
            
            if (this.currentLargeImgWidth == 0 && this.currentLargeImgHeight == 0)
                return;
            
            if (this.maxZoomFactor == null || this.maxZoomFactor == 'undefined') 
            {
                this.originalLargeImgWidth = this.currentLargeImgWidth;
                this.originalLargeImgHeight = this.currentLargeImgHeight;
                
                this.optimalZoomFactor = this.originalLargeImgWidth / (this.options.ZoomerWidth * this.options.ZoomWindow);
                if (this.options.ZoomFactor == 0) this.options.ZoomFactor = this.optimalZoomFactor;
                
                this.maxZoomFactor = this.originalLargeImgWidth / this.imageWidth;
                
                if (this.options.ZoomFactor > this.maxZoomFactor) this.options.ZoomFactor = this.maxZoomFactor;
            }
            
            var newWidth = this.imageWidth * this.options.ZoomFactor;
            var newHeight = this.imageHeight * this.options.ZoomFactor;
            this.zoomedImg.style.width = newWidth + 'px';
            this.zoomedImg.style.height = newHeight + 'px';
            
            var xPercent = x / this.imageWidth;
            var yPercent = y / this.imageHeight;
            
            var largeImageX = ((newWidth - ((this.floaterWidth) * this.options.ZoomWindow)) * xPercent);
            var largeImageY = ((newHeight - ((this.floaterHeight) * this.options.ZoomWindow)) * yPercent);
            
            this.zoomedImg.style.left = (-1 * (largeImageX)) + 'px';
            this.zoomedImg.style.top = (-1 * (largeImageY)) + 'px';
        }
        else 
        {
        	this.spinning = true;
			this.zoomedImg.style.display = 'none';
			InstanceContainer.FireEventAsync(this.id, '_displayZoomedImg', 100);
        }
	}
	
});
