// ControlDepo Widget Commonent
// @date 29.08.2008
// @version 0.1
// @todo -> keyboard access, track mousewheel

if (!CD3) var CD3 = {};

CD3.Lightbox = Class.create({
	initialize: function(images){
		this.build();
		this.images			= images;
		this.activeImage	= -1;
		this.loading		= null;
		
		this.images.invoke('observe', 'click', function(e){
			var image = e.findElement('a');
			this.activeImage = this.images.indexOf(image);
			if (this.activeImage == -1){
				this.activeImage = this.images.length;
				this.images.push(image);
			}
			this.show(image);
			e.stop();
		}.bind(this));
	},
	build: function(){
		if (!$('lightbox'))
			$$('body')[0].insert([
				'<div id="lightbox">',
					'<div class="bkg"></div>',
					'<div class="content">',
						'<h1 class="header"><span></span></h1>',
						'<a href="javascript:;" class="close"></a>',
						'<p class="pic"><span></span></p>',
						'<div class="navigation">',
							'<ul>',
								'<li class="prev"><a href="javascript:;">Previous</a></li>',
								'<li class="next"><a href="javascript:;">Next</a></li>',
							'</ul>',
						'</div>',
						'<div class="footer">',
							'<div></div>',
						'</div>',
					'</div>',
				'</div>'
			].join(''));
		
		var box =  $('lightbox');
		
		this.offset				= 24;
		this.titleMinHeight		= 12;
		this.titleMaxHeight		= 48;
		this.navigationHeight	= 48;
		
		this.background = box.down('.bkg').hide().observe('click', this.hide.bind(this));
		this.title		= box.down('.header span').setStyle({height : this.titleMinHeight + 'px'});
		this.close		= box.down('.close').hide().observe('click', this.hide.bind(this));
		this.pic		= box.down('.pic span');
		this.content	= box.down('.content').hide();
		this.navigation	= box.down('.navigation').setStyle({height : '0px'});
		
		box.down('.prev').observe('click', this.gotoImage.bind(this, -1));
		box.down('.next').observe('click', this.gotoImage.bind(this, 1));	
	},
	gotoImage: function(pos){
		if (pos > 0)	this.activeImage = this.images.length > this.activeImage + 1 ? this.activeImage + 1 : 0;
		else			this.activeImage = this.activeImage > 0 ? this.activeImage - 1 : this.images.length - 1;
			
		this.show(this.images[this.activeImage]);	
	},
	hide: function(e){
		if (e && e.stop()) e.stop();
		
		this.clearLoader();
		
		this.background.hide();
		this.content.hide();
		this.close.hide();
		this.navigation.setStyle({height : '0px'});
		this.title.setStyle({height : this.titleMinHeight + 'px'}).innerHTML = '';
		
		$$('select', 'object', 'embed').each(function(node){ 
			if (node.style){
				node.style.visibility = node._visibility;
				delete node._visibility;
			}
		});
	},
	show: function(image){
		this[this.background.visible() ? 'pack' : 'start'](image);
	},
	start: function(image){
		$$('select', 'object', 'embed').each(function(node){ 
			if (node.style){
				node._visibility = node.style.visibility;
				node.style.visibility = 'hidden';
			}
		});

		this.overlay();
		this.background.appear();
		
		var offset = this.offset;
		
		this.content.clonePosition(image, {setHeight: false, offsetTop: 27}).appear();
		this.pic.style.height = image.offsetHeight - offset + 'px';
		this.pic.innerHTML = '';
		this.loadImage(image.href, this.flyIn.bind(this, {width: image.offsetWidth - offset, height: image.offsetHeight - offset}));
	},
	pack: function(image){
		this.pic.style.height	= this.pic.offsetHeight + 'px';
		this.pic.style.width	= this.pic.offsetWidth + 'px';
		this.pic.innerHTML		= '';
		this.title.innerHTML	= '';
		this.close.hide();
			
		new Effect.Parallel([
			new Effect.Morph(this.navigation, {sync: true,style: {height: '0px'}}),
			new Effect.Morph(this.title, {sync: true,style: {height: this.titleMinHeight + 'px'}})
		],{
			duration: 0.7,
			afterFinish: this.loadImage.bind(this, image.href, this.expand.bind(this))
		});
	},	
	expand: function(){		
		new Effect.Parallel([
			this.resizePanelEffect(),
			this.resizeImageEffect(this.pic)
		],{ afterFinish: function () {
			this.pic.innerHTML = '<img src="' + this.loading.src + '" />';
			this.finish();
		}.bind(this) });
	},
	flyIn: function(start){
		this.pic.style.height = null;
		this.pic.innerHTML = '<img src="' + this.loading.src + '"style="width: ' + start.width + 'px; height: ' + start.height + 'px;" />';
		new Effect.Parallel([
			this.resizePanelEffect(),
			this.resizeImageEffect(this.pic.down('img'))
		],{ afterFinish: this.finish.bind(this) });
	},
	finish: function(){
		var img = this.pic.down('img');

		img.style.width = img.style.height = null;
		this.pic.style.height = this.pic.style.width = null;
		
		this.clearLoader();
		
		new Effect.Parallel([
			new Effect.Morph(this.navigation, {sync: true,style: {height: this.navigationHeight + 'px'}}),
			new Effect.Morph(this.title, {sync: true,style: {height: this.titleMaxHeight + 'px'}})
		],{
			duration: 0.7,
			afterFinish: function () {
				var image = this.images[this.activeImage];
				this.title.innerHTML = image.getAttribute('title') || image.getAttribute('alt');
				this.close.appear();
				this.overlay();
			}.bind(this)
		});
	},
	resizePanelEffect: function(){
		var dim		= document.viewport.getDimensions(), 
			scroll	= document.viewport.getScrollOffsets(),
			width	= this.loading.width + this.offset,
			height	= this.loading.height + this.offset;

		return new Effect.Morph(this.content, {
			sync: true,
			style: {
				top:	parseInt(scroll.top  + (dim.height - (height))/2) + 'px',
				left:	parseInt(scroll.left + (dim.width - width)/2 ) + 'px',
				width:	width + 'px',
				height:	height + 'px'
			}
		});
	},
	resizeImageEffect: function(conatiner){
		return new Effect.Morph(conatiner, {
			sync: true,
			style: {
				width:	this.loading.width + 'px',
				height:	this.loading.height + 'px'
			}
		});
	},
	loadImage: function(src, callback){
		this.clearLoader();
		this.loading		= new Image();	
		this.loading.onload	= callback;
		this.loading.src	= src;
	},
	clearLoader: function(){
		if (this.loading != null){
			this.loading.onload = null;
			this.loading = null;
		}
	},
	overlay: function(){
		var xScroll, yScroll, dim = document.viewport.getDimensions();
		
		if (window.innerHeight && window.scrollMaxY) {	
			xScroll = window.innerWidth + window.scrollMaxX;
			yScroll = window.innerHeight + window.scrollMaxY;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
			xScroll = document.body.scrollWidth;
			yScroll = document.body.scrollHeight;
		} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}
				
		this.background.setStyle({
			width: Math.min(xScroll, dim.width) + 'px',
			height: Math.max(dim.height, yScroll) + 'px'
		});
	}
});

// Until Prototype 1.6.1 arives
if (Prototype.Browser.IE) {
	(function(){
		function proceed(element) {
			element = $(element);
			var op = element.offsetParent;
			if (op && op != document.documentElement) return $(op);
			
			while ((element = element.parentNode) && element.tagName.toUpperCase() != 'HTML')
				if (Element.getStyle(element, 'position') != 'static')
					return $(element);
			
					return $(document.body);
		}
		// IE doesn't report offsets correctly for static elements, so we change them
		// to "relative" to get the values, then change them back. 
		Element.addMethods({
			getOffsetParent: function(element) {
				element = $(element);
				// IE throws an error if element is not in document
				try { element.offsetParent; } catch(e) { return $(document.body); }
	
				if (element.getStyle('position') !== 'static') return proceed(element);
				
				element.style.position ='relative';
				var value = proceed(element);
				element.style.position = 'static';
				return value;
			}
		});
	})();
} else if (Prototype.Browser.Opera){
	document.viewport.getDimensions= function(){
		var dimensions = { }, B = Prototype.Browser;
		$w('width height').each(function(d) {
			var D = d.capitalize();
			if (B.WebKit && !document.evaluate) {
				// Safari <3.0 needs self.innerWidth/Height
				dimensions[d] = self['inner' + D];
			} else if (B.Opera && parseFloat(window.opera.version()) < 9.5) {
				// Opera <9.5 needs document.body.clientWidth/Height
				dimensions[d] = document.body['client' + D];
			} else {
        		dimensions[d] = document.documentElement['client' + D];
      		}
    	});
		return dimensions;
	};
}
