
////////////////////////////////////////////////////////
//
//  PHPh_Zoom (c) 2009-2010 Bill Heller all rights reserved
//	BH@BillHeller.com
//
//  USAGE:
//	JS:   
//  	window.addEvent('domready', function() { PHPh_Zoom.init(); }
//
//  	HTML:
//	<a href="SomeImage.jpg"><img src="SomeImageThumb.jpg" alt="myImage" />
//
//  You can also optionally pass an array of anchor tags to init() 
//  for speed or to limit the effect to only those tags
//

var PHPh_clsZoom = new Class({
  	Implements: [Options, Events],
	elements:[],
	shade:false,
	initialized:false,
	zoomers:2, 
	zoom:[], 
	setup_complete:false,
	currentEl:false,
	currentZoomIndex:-1,
	options: {
   		image_directory : '/images/PHPh_Zoom',
		width: null,
		height: null,
		startOpacity: null,
		max: 1024
	},
	init: function(links, options){
		this.setOptions(options);
		if(links && !is_array(links))links=[links];
		if(!this.initialized) {
			if(!$chk(links)) //No Links provided, find ancor tags pointing directly to images
				links = $$('a').filter(function(el){return el.get('href').test(/\.(gif|jpe?g|png)/);});
			this.setup();
		}
		links.each(function(el){
			el.addEvent('mouseover',PHPh_Zoom.loadImg.bindWithEvent(PHPh_Zoom));
			el.addEvent('click',PHPh_Zoom.show.bindWithEvent(PHPh_Zoom));
		});
		if(links)this.elements.combine(links);
		this.initialized=true;
	},
	setup: function (){
		if(this.setup_complete) return true;
		$(document.body).adopt(
			$$(
				this.shade = new Element("div", {id: "PHPh_Shade"}).addEvent("click", close)
			).setStyle("display", "none")
		);
		
		// Create multiple zoomers so one can zoom out wile the next one is zooming in.
		for(x=0;x<this.zoomers;x++) {
			this.zoom[x]=new PHPh_clsZoomer();
			this.zoom[x].init(x,this.options);
		}
		this.setup_complete=true;
	},
	loadImg:function(e){
		e.stop();
		var el=$($(e.target).match('a')?e.target:e.target.getParent('a'));
  		//if(PHPh_Debug) PHPh_Debug.debug('PHPh_Zoom.loadImg: el',el);
		if(!$chk(el.retrieve('loader'))) {
			el.store('loader',new PHPh_clsLoader())
			el.retrieve('loader').load(el);
		}
	},
	show:function(e){
  		e.stop();
  		var el=$(e.target).match('a')?e.target:e.target.getParent('a');
		if(!el.retrieve('loader'))
			this.loadImg(e);
		//if(PHPh_Debug) PHPh_Debug.debug('PHPh_Zoom.show: el.retrieve(\'loader\').thumb',el.retrieve('loader').thumb);
  		//if(PHPh_Debug) PHPh_Debug.debug('PHPh_Zoom.show: el.retrieve(\'loader\').img',el.retrieve('loader').img);
  		//if(PHPh_Debug) PHPh_Debug.debug('PHPh_Zoom.show: el.retrieve(\'loader\').el',el.retrieve('loader').el);
  		var i=this.currentZoomIndex;
		//alert('i = '+i);
  		if(this.currentZoomIndex>-1 && !this.zoom[i].hidden) {
			this.zoom[i].hide();
		}
		if(++i==this.zoom.length) i=0;
		//alert('current zoom index = '+i);
		//alert('this.zoom = '+this.zoom);
		//alert('this.zoom[i] = '+this.zoom[i]);
		this.currentZoomIndex=i;
		this.zoom[i].hidefast();
		this.currentEl=el;
		this.zoom[i].show(el);
		return false;
	},
	hide:function(){
	
	}
});

var PHPh_clsLoader = new Class({
	el:false,
	loaded:false,
	loading:false,
	href:'',
	img:false,
	thumb:false,
	onload:false,
	load:function(a){
		this.img=$(new Image());
		if(a&&a!=this.el){
			this.el=$(a);
			if(this.el)this.el=a;
			this.loading=this.loaded=false;
			this.thumb=this.el.getElement('img');
		}
		if(!this.loaded && !this.loading) {
			this.loading=true;
			this.img.onload = this.loadComplete.bind(this);
			this.img.src = this.el.get('href');
		}
	},
	loadComplete:function(){
		this.loading=false;
		this.loaded=true;
		if(this.onload)this.onload();
	}
});

// simple box class
var PHPh_Box = new Class({
	top:-1,
	left:-1,
	width:-1,
	height:-1,
	box:function(t,l,w,h){
		this.top=t;
		this.left=l;
		this.width=w;
		this.height=h;
	}
});

// multiple zoomers are created to allow one to zoom in
// while the previous image is still on its way out
var PHPh_clsZoomer = new Class({
  	Implements: [Options, Events],
	index:-1,
	initialized:false,
	zoom_div:false,
	border_div:false,
	zoom_image:false,
	zoom_label:false,
	zooming:false,
	start_time:false,
	currentEl:false,
	options:{},
	startPos:false,
	targetPos:false,
	borderSize:15,
	cornerRadius:8,
	fx:false,
	img:false,
	thumb:false,
	hidden:true,
	init:function(index,options){
		this.index=index;
		this.setOptions(options);
		if(!this.initialized) {
			$(document.body).adopt(
				this.zoom_div = 
					new Element("div", {id: "PHPh_ZoomDiv_"+index, 
						styles:{'display':'none','z-index':'1000','position':'absolute'}})
								.addEvent("click", this.hide.bindWithEvent(this))
			);
			this.zoom_div.adopt(this.zoom_image = new Element("img", {id: "PHPh_ZoomImg_"+index,styles:{position:'relative','z-index':10002,'left':0,'top':0,'display':'none'}}).addEvent("click", this.hide.bindWithEvent(this)));
			this.zoom_div.adopt(this.border_div = new Element("div", {id: "PHPh_Zoom_BorderDiv_"+index,styles:{background:'white',opacity:.5,position:'absolute','z-index':10001,'display':'none'}}).addEvent("click", this.hide.bindWithEvent(this)));
			this.initialized=true;
		}
	},
	wait: function(){
		$$(this.zoom_image,this.border_div).setStyle('display','none');
		this.zoom_div.setStyles({
			display:'block',
			width:this.thumb.width,
			height:this.thumb.height,
			'background-color':'white',
			opacity:.2
		});
		this.hidden=false;
		this.zoom_div.position({relativeTo: this.thumb});
	},
	show: function(el){
		this.zoom_image.src=this.options['image_directory']+'/pixel.gif';
		if(el) this.currentEl=el;
		var l=this.currentEl.retrieve('loader');
		var theImage=this.img=l.img;
		var theThumb=this.thumb=l.thumb;
		if(!l.loaded) l.onload=this.show.bind(this);
		if(!l.loaded) {
			this.wait();
		} else {
			// full image is loaded, set up start position and zoomer div and image
			this.zoom_image.src=theImage.src;
			var scroll = window.getScroll()
			var targetL = ((window.getWidth()-theImage.width)/2)+scroll.x;
			var targetT = ((window.getHeight()-theImage.height)/2)+scroll.y;
			if(targetL<0)targetL=0;
			if(targetT<0)targetT=0;
			this.zoom_div.setStyles({
				display:'block',
				width:theThumb.width,
				height:theThumb.height,
				'background-color':'transparent',
				opacity:.2
			});
			
			// line up zoomer div in front of thumb 
			this.zoom_div.position({relativeTo: theThumb});
			// initial image size, same as thumb size
			this.zoom_image.setStyles({
				display:'',
				width:theThumb.width,
				height:theThumb.height
			});
			
			// border setup including some CSS3 items
			this.border_div.setStyles({
				display:'',
				left:0,
				top:0,
				opacity:0,
				width:theThumb.width,
				height:theThumb.width,
				'-moz-border-radius':this.cornerRadius,
				'border-radius':this.cornerRadius,
				'-webkit-border-radius':this.cornerRadius
			});
			
			this.hidden=false;
			this.fx = new Fx.Elements([$(this.zoom_div),$(this.zoom_image)],{'link':'chain',duration:600,transition: Fx.Transitions.Quint.easeInOut});
			this.fx_border = new Fx.Morph($(this.border_div),{'link':'chain',duration:600,transition: Fx.Transitions.Quint.easeInOut});
			this.fx.start({
				'0':{'left':targetL,'top':targetT,'width':theImage.width,'height':theImage.height,opacity:[.1,1]},
				'1':{'width':theImage.width,'height':theImage.height}
			}).chain(function(){
				//if(PHPh_Debug) PHPh_Debug.debug('PHPh_clsZoomer.show: this.border_div',this.border_div);
				//this.border_div.setStyle(display:'');
				this.fx_border.start({'width':[this.img.width,this.img.width+(this.borderSize*2)],
							'height':[this.img.height,this.img.height+(this.borderSize*2)],
							'left':(this.borderSize*-1),
							'top':(this.borderSize*-1),
							'opacity':[.2,.5]
				});
			}.bind(this));
		}
	},
	stop:function(){
		if(this.fx) this.fx.cancel();
		if(this.fx_border) this.fx_border.cancel();
	},
	
	// Hide normally with all effects
	hide:function(){
		//if(PHPh_Debug) PHPh_Debug.debug('PHPh_clsZoomer.hide: this.currentEl',this.currentEl);
		//var l=$(this.currentEl).retrieve('loader');
		this.stop();
		var theThumb=this.thumb;
		var loc=theThumb.getCoordinates();
		//alert('loc.left: '+loc.left+'  loc.top: '+loc.top);
		//alert('theThumb.height: '+theThumb.height+'  theThumb.width: '+theThumb.width);
		this.fx = new Fx.Elements([$(this.zoom_div),$(this.zoom_image),$(this.border_div)],{'link':'chain',duration:500,transition: Fx.Transitions.quadIn});
		this.fx.start({
			'0':{'left':loc.left,'top':loc.top,'width':theThumb.width,'height':theThumb.height,opacity:[1,.1]},
			'1':{'width':theThumb.width,'height':theThumb.height},
			'2':{'width':theThumb.width,'height':theThumb.height,'left':0,'top':0,'opacity':0}
		}).chain(this.hidefast.bind(this));
		this.currentEl=false;
	},
	
	// Abort animation and reset for next image
	hidefast: function(){
		this.stop();
		this.zoom_div.setStyle('display','none');
		this.currentEl=false;
		this.zoom_image.src=this.options['image_directory']+'/pixel.gif';
		this.hidden=true;
	},
	reset:function(){
		
	}
});

var PHPh_Zoom = new PHPh_clsZoom();




function GetElementLeftOffset(el){
   	var l = el.offsetLeft;
   	var p = el.offsetParent;
   	while(p != null){
       	if(p.scrollLeft)l-=p.scrollLeft;
		l += p.offsetLeft;
       	p = p.offsetParent;  
   	}
   	return l;
}

function GetElementTopOffset(el){
   	var t = el.offsetTop;
   	var p = el.offsetParent; 
	while (p != null){
		if(p.scrollTop)t-=p.scrollTop;
		t += p.offsetTop;
       	p = p.offsetParent;
   	}
	return t;
}

