// ---------------------------------------------------------------------------
//    Copyright (c) 2006, LiquidPixels, Incorporated. All Rights Reserved.
//
//    This file represents Intellectual Property which is proprietary and
//  confidential to LiquidPixels, Incorporated. Any disclosure, in whole
//  or in part, is prohibited without express written permission.
//
//   $Id: liquidpixels.js 97 2008-12-11 23:32:06Z mspencer $
// ---------------------------------------------------------------------------

//import org.prototypejs.prototype.Prototype
//import com.liquidpixels.liquifire.Command
//import com.liquidpixels.liquifire.Chain

if(!com.liquidpixels.glass)
	com.liquidpixels.glass = {};
	


com.liquidpixels.glass.Glass = Class.create({
	revision: "$Revision: 95 $",
	Version: function() {
	  	return revision.substr(11).substr(0, -2);
	},

	element:		undefined,

	locked:			undefined,
	chain:			undefined,
	size:			undefined,

	smallImage:		undefined,
	glassDiv:		undefined,
	fullImage:		undefined,
	curtainImage:	undefined,
	cursorDiv:		undefined,
	cursorImage:	undefined,

	position:		undefined,
	options:		{
		focusColor:			'white',
		focusOpacity:		40,
		focusBorderColor:	'#b1b1b1',
		focusBorderWidth:	1
	},
	

	initialize: function(imageID, glassID, chain, size, options) {
		this.position = {x: 0, y: 0};
		this.scale = {x: 0.1, y: 0.1};
		
		this.locked = true;
		
		Object.extend(this.options, options);
		
		try {
			var foo = $(imageID);
			foo.setStyle({
				position: 'absolute',
				x: '0px',
				y: '0px'
			});
			this.element = new Element('div');
			foo.appendChild(this.element);
			this.element.setStyle({
				position: 'absolute',
				x: '0px',
				y: '0px'
			});
			
			this.smallImage = new Element('img');

			this.element.appendChild(this.smallImage);
		
			this.smallImage.absolutize();
			this.smallImage.relativize();
	
			this.fullImage = new Element('img');
			this.fullImage.observe('load', this.updateHandler.bindAsEventListener(this));
			this.glassDiv = $(glassID);
			this.glassDiv.appendChild(this.fullImage);
	
			this.size = size;
			
			this.curtainImage = new Element('img');

			if(chain && ! Object.isUndefined(chain))
				this.setImage(chain);
	
			this.smallImage.observe('load', this.imageLoadHandler.bindAsEventListener(this));
			this.fullImage.absolutize();
			this.fullImage.relativize();
			
			this.glassDiv.hide();

			if(chain && ! Object.isUndefined(chain))
				this.layout();
				
			this.element.appendChild(this.curtainImage);
			this.curtainImage.absolutize();
			this.curtainImage.hide();
	
			this.cursorDiv = new Element('div');
			this.element.appendChild(this.cursorDiv);
			this.cursorDiv.absolutize();
			this.cursorDiv.hide();
	
			this.cursorImage = new Element('img');
			this.cursorImage.src = this.smallImage.src; 
			this.cursorDiv.appendChild(this.cursorImage);
			this.cursorImage.absolutize();
	
			this.smallImage.observe('mouseover', this.mouseOverHandler.bindAsEventListener(this));
	
			window.onresize = this.imageLoadHandler.bindAsEventListener(this);
	
			this.cursorDiv.observe('mousemove', this.mouseMoveHandler.bindAsEventListener(this));
			this.cursorDiv.observe('mouseover', this.mouseOverHandler.bindAsEventListener(this));
			this.cursorDiv.observe('mouseout', this.mouseOutHandler.bindAsEventListener(this));		
	
			this.curtainImage.observe('mousemove', this.mouseMoveHandler.bindAsEventListener(this));
			this.curtainImage.observe('mouseover', this.mouseOverHandler.bindAsEventListener(this));
			this.curtainImage.observe('mouseout', this.mouseOutHandler.bindAsEventListener(this));		
		} catch(e) {
			document.write("com.liquidpixels.glass.Glass: " + e + "<BR>");
		}

	},

	
	layout: function() {
		var focusChain = new com.liquidpixels.liquifire.Chain(this.chain.getServer(), this.chain.getURI());
		focusChain.addCommand(new com.liquidpixels.liquifire.Command('blank', {
			width: 100,
			height: 100,
			color: this.options.focusColor
		}));
		focusChain.addCommand(new com.liquidpixels.liquifire.Command('sink', {
			format: 'gif'
		}));
		this.curtainImage.src =  focusChain.asURL();
	},


	setImage: function(chain) {
		this.chain = chain;
		
		if(! Object.isUndefined(this.smallImage)) this.smallImage.hide();
		if(! Object.isUndefined(this.fullImage)) 	this.fullImage.hide();
		if(! Object.isUndefined(this.cursorDiv)) 	this.cursorDiv.hide();
		
		this.locked = true;

		this.fullImage.src = this.chain.asURL()

		this.chain.insertCommand(chain.findCommand('sink'), 
			new com.liquidpixels.liquifire.Command('scale', {size: this.size})
		);
	
		this.smallImage.setStyle({
			left: 0 + 'px',
			top: 0 + 'px',
			width: '',
			height: '',
			zIndex: '1'
		});

		this.smallImage.src = chain.asURL();

		if(! Object.isUndefined(this.cursorImage))
			this.cursorImage.src = this.smallImage.src; 

		if(chain && ! Object.isUndefined(chain))
			this.layout();
	},
	
	
	imageLoadHandler: function(e) {
		this.position = {
			x: this.element.cumulativeOffset()[0],
			y: this.element.cumulativeOffset()[1]
		};

		this.smallImage.setStyle({
			left: 0 + 'px',
			top: 0 + 'px',
			width: this.smallImage.getDimensions().width + 'px',
			height: this.smallImage.getDimensions().height + 'px',
			zIndex: '1'
		});

		this.curtainImage.setStyle({
			left: 0 + 'px',
			top: 0 + 'px',
			width: this.smallImage.getDimensions().width + 'px',
			height: this.smallImage.getDimensions().height + 'px',
			opacity: this.options.focusOpacity/100,
			zIndex: '2'
		});

		this.cursorImage.setStyle({
			left: 0 + 'px',
			top: 0 + 'px',
			width: this.smallImage.getDimensions().width + 'px',
			height: this.smallImage.getDimensions().height + 'px'
		});

		var aspect = this.glassDiv.getDimensions().width / this.glassDiv.getDimensions().height;
		
		this.cursorDiv.setStyle({
			left: 0 + 'px',
			top: 0 + 'px',
			borderWidth: this.options.focusBorderWidth + 'px',
			borderStyle: 'solid',
			borderColor: this.options.focusBorderColor,
			overflow: 'hidden',
			zIndex: '10',
			width: '100px',
			height: (100 / aspect) + 'px'
		});
	},


	updateHandler: function(e) {
		this.smallImage.show();
		this.fullImage.show();
		this.cursorDiv.hide();
		
		this.locked = false;
	},


	panTo: function(point) {
		cpoint = Object.clone(point);
		
		var dGlass = this.glassDiv.getDimensions();
		var dImage = this.fullImage.getDimensions();
		var dCursor = this.cursorDiv.getDimensions();
		var dE = this.smallImage.getDimensions();

		cpoint.x -= dCursor.width/2;
		cpoint.y -= dCursor.height/2;

		if(cpoint.x < 0) cpoint.x = 0;
		if(cpoint.y < 00) cpoint.y = 0;
		if(cpoint.x > 0 + dE.width - dCursor.width) cpoint.x = dE.width - dCursor.width;
		if(cpoint.y > 00 + dE.height - dCursor.height) cpoint.y = dE.height - dCursor.height;

		this.cursorDiv.setStyle({
			left: cpoint.x + 'px',
			top: cpoint.y + 'px'
		});
		
		this.cursorImage.setStyle({
			left: -cpoint.x - this.options.focusBorderWidth + 'px',
			top: -cpoint.y - this.options.focusBorderWidth + 'px'
		});


		var xScale = (dImage.width - dGlass.width) / (dE.width - dCursor.width);
		var yScale = (dImage.height - dGlass.height) / (dE.height - dCursor.height);
	
		if(point.x < 0) point.x = 0;
		if(point.y < 0) point.y = 0;
		if(point.x > dImage.width) point.x = dImage.width - dGlass.width;
		if(point.y > dImage.height) point.y = dImage.height - dGlass.height;
		
		point.x = cpoint.x * xScale;
		point.y = cpoint.y * yScale;

		if(!isNaN(point.x) && !isNaN(point.y)) {
			this.fullImage.setStyle({
				left: -point.x + 'px',
				top: -point.y + 'px'
			});
		}
	},

	
	mouseMoveHandler: function(e) {
		if(this.locked)
			return;
		
		var x = e.pointerX() - this.position.x;
		var y = e.pointerY() - this.position.y;

		this.panTo({x: x, y: y});
	},


	mouseOverHandler: function(e) {
		this.glassDiv.show();
		this.curtainImage.show();
		this.cursorDiv.show();
	},


	mouseOutHandler: function() {
		this.glassDiv.hide();
		this.curtainImage.hide();
		this.cursorDiv.hide();
	}
});

