/*
Overlay Albums 1.0
Copyright © Giorgio A. Schwarz (gio@idiosuite.com)
No distribution/usage allowed without written permission
*/

var OverlayAlbums = Class.create();
OverlayAlbums.prototype = {
	//*** Options ***//
	options: Object.extend({
		loadingImg:'_img/loading.gif',
		overlayOpacity: '0.9', // from 0.0 to 1.0
		hideFlash: true,
		hidePaging: false,
		pagingLayout: "right", // "top" || "bottom" || "right" || "left"
		framePadding: {top:5, right: 5, bottom: 5, left: 5}, // integers (px)
		QT: {autoplay: 'true', controller: 'true', playlist: 'true'} // ***STRINGS*** true or false
	}),
	//*** Albums ***//
	albums: { ids: [], items: [] },
	//*** Status Variables ***//
	animating: false,
	active: false,
	ready: false,
	//*** Markup Elements ***//
	overlay: new Element('div', {'id': 'oa_overlay'}),
	frame: new Element('div', {'id': 'oa_frame'}),
	container: new Element('div', {'id': 'oa_container'}),
	display: new Element('div', {'id': 'oa_display'}).update(""),
	paging: new Element('div', {'id': 'oa_paging'}),
	innerPaging: new Element('div').update("No items"),
	loading: new Element('div', {'id': 'oa_loading'}).update('Loading&hellip;'),
	//*** Element Dimensions ***//
	dims : {
		page : { w : null, h : null, scrollx : 0, scrolly : 0 },
		viewport : { h : null, w : null, offsetTop : null, offsetLeft : null },
		frame : { ow: 450, oh: 350, w: 450, h: 350 }
	},
	//*** File Types ***//
	fileTypes : {
		page : ['asp','aspx','cgi','htm','html','php','txt'],
		quicktime : ['mov','mp3'],
		image : ['bmp','gif','jpg', 'jpeg' ,'png','tiff']
	},
	initialize: function() {
		this._getPageDimensions();
		this._getScroll();
		this._getBrowserDimensions();
		this._addMarkup();
		this._setupDimensions();
	},
	activate: function(albumId, albumItem){
		if(!this.ready) return;
		if(!albumItem) albumItem = 0;
		
		this._setupOverlay();
		this._setupDimensions();
		
		this.active=true;
		this._togglePaging();
		this._toggleTroubleElements('hidden', false);
		// update paging
		var i, items = new Array();
		var album=this._getAlbumById(albumId);
		if(album.length<1) return false;
		if(album.length==1) this._togglePaging(false);
		this.innerPaging.update("");
		var cssclass, a;
		for(i=0; i<album.length; i++){
			cssclass = (albumItem == i) ? "sel" : "go";
			if(album[i].media=='menuitem') {
				a = new Element('a', {'class': cssclass, 'href': album[i].url}).update(album[i].title);
			} else {
				a = new Element('a', {'class': cssclass, 'href':'javascript:;'}).update(album[i].title);
				Event.observe(a, 'click', this._browse.bindAsEventListener(this, a, album, i));
			}
			Element.insert(this.innerPaging, {bottom: a});
		}
		// showOverlayAlbum
		this._showOverlayAlbum(true);
		// update frame
		this._addObject(album, albumItem);
	},
	addAlbum: function(id, arr){
		for(i=0; i<arr.length; i++){
			if(!arr[i].media)
				arr[i].media=this._getMedia(arr[i].url);
		}
		var exists = this.albums.ids.indexOf(id);
		if(exists > -1) {
			this.albums.items[exists] = arr;
			return;
		}
		this.albums.ids.push(id);
		this.albums.items.push(arr);
	},
	deactivate: function(){
		// reset frame original dimensions
		this.dims.frame.w=this.dims.frame.ow;
		this.dims.frame.h=this.dims.frame.oh;
		// Kill the animation
		this.animating = false;
		// make OverlayAlbum dissappear
		this._showOverlayAlbum(false);
		// Clear our container
		this.display.update("");
		// Clear out paging
		this.innerPaging.update("");
		// Undo the setup
		this._setupDimensions();
		this._toggleTroubleElements('visible', false);	
		//
		this.active=false;
	},
	//
	// *** START SCRIPT FUNCTIONS *** //
	//
	_addMarkup: function(){
		// hide all elements before inserting
		this.overlay.hide();
		this.frame.hide();
		// insert html
		var b = document.getElementsByTagName("body")[0];
		Element.insert(this.paging, {bottom: this.innerPaging});
		Element.insert(this.container, {bottom:this.loading});
		Element.insert(this.container, {bottom: this.display});
		Element.insert(this.container, {bottom: this.paging});
		Element.insert(this.frame, {bottom: this.container});
		Element.insert(b, {bottom:this.overlay});	
		Element.insert(b, {bottom:this.frame});

		if (this.options.loadingImg != '') this.loading.update('<img src="'+this.options.loadingImg+'" />');
		
		Event.observe(this.overlay, 'click', this.deactivate.bindAsEventListener(this));

		// Because we use position absolute, kill the scroll Wheel on animations
		if (Prototype.Browser.IE) {
			Event.observe(document, 'mousewheel', this._stopScrolling.bindAsEventListener(this), false);
		} else {
			Event.observe(window, 'DOMMouseScroll', this._stopScrolling.bindAsEventListener(this), false);
		}
	},
	image: null,
	_addObject: function(album, itemIndex){
		var obj = album[itemIndex];
		this._toggleLoading(true);
		switch(obj.media){
			case "image":
				var myImage = new Image();
				myImage.onload = function(e, myImage){
					this.display.update(myImage);
					myImage = this.display.down('img');
					var maxd = this._getMaxDimensions(myImage.width, myImage.height);
					myImage.hide();
					myImage.setStyle({ 'width': maxd.w+'px', 'height': maxd.h+'px' });
					this._animationResize(maxd.w, maxd.h, true);
				}.bindAsEventListener(this, myImage);
				myImage.src = obj.url;
				myImage.alt = obj.title;
				break;
			case "quicktime":
				var playlist = this._getSameMediaItems(album, itemIndex);
				var plstr = "";
				if(this.options.QT.playlist=='true') {
					for(i=0; i<playlist.length; i++)
						plstr += '  <param name="qtnext'+(i+1)+'" value="<'+album[playlist[i]].url+'>T<myself>" /> ';
				}
				var code='<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" '
					+'  codebase="http://www.apple.com/qtactivex/qtplugin.cab" '
					+'  width="'+obj.width+'" height="'+obj.height+'"> '
					+'  <param name="src" value="'+obj.url+'" /> '
					+'  <param name="controller" value="'+this.options.QT.controller+'" /> '
					+'  <param name="autoplay" value="'+this.options.QT.autoplay+'" /> '
					+'  <param name="wmode" value="transparent" /> '
					+ plstr
					+'  <!--[if !IE]>--> '
					+'  <object type="video/quicktime"  '
					+'	data="'+obj.url+'"  '
					+'	width="'+obj.width+'" height="'+obj.height+'" style="z-index: 9999;"> '
					+'	<param name="autoplay" value="'+this.options.QT.autoplay+'" /> '
					+'	<param name="controller" value="'+this.options.QT.controller+'" /> '
					+ plstr
					+'  <param name="wmode" value="transparent" /> '
					+'  </object> '
					+'  <!--<![endif]--> '
					+'</object>';
				// as quicktime version < 7.5 does not positionate correctly in ie6/7, we have to execute the animation FIRST, and then update this.display
				this._animationResize(obj.width, obj.height, false, code);
				break;
			case "page":
				var wrap = new Element('div', {'class': 'page'})
				this.display.update(wrap);
				var ajax = new Ajax.Request(obj.url, {method: 'get', onComplete:function(response){
					var content = new Element('div', {'class': 'page'});
					content.update(response.responseText);
					wrap.update(content);
					var dim = content.getDimensions();
					if (obj.width>dim.width) dim.width = obj.width; 
					if (obj.height>dim.height) dim.height = obj.height; 

					var maxd = this._getMaxDimensions(dim.width, dim.height);

					if(!obj.height || obj.height>maxd.h) obj.height = maxd.h;
					if(!obj.width || obj.width>maxd.w) obj.width = maxd.w;
					Element.setStyle(wrap, {'width':obj.width+'px', 'height':obj.height+'px', 'overflow': 'auto'});
					
					wrap.hide();
					this._animationResize(obj.width, obj.height, true);
				}.bind(this)});
				break;
		}
	},
	_animationResize:function(w, h, animateObj, append){
		w = parseInt(w); h = parseInt(h);
		var dim = this._getResizeDimensions(w, h);
		var w = dim.w;
		var h = dim.h;
		if(w==this.dims.frame.w && h==this.dims.frame.h) {
			this._toggleLoading(false);
			if(append) this.display.update(append);
			if (animateObj)
				new Effect.Appear(this.display.down(), {queue:'end', afterFinish: function(){ this.animating=false; }.bind(this)});
			else
				this.display.down().show();
		} else {
			this.animating=true;
			var margin = this._getFrameMargin(w, h);
			
			if(this.options.pagingLayout == "left" || this.options.pagingLayout == "right")
				new Effect.Morph(this.paging, {style: 'height:'+h+'px'});
			if(this.options.pagingLayout == "top" || this.options.pagingLayout == "bottom")
				new Effect.Morph(this.paging, {style: 'width:'+w+'px'});
				
			new Effect.Morph(this.container, {style: 'width:'+w+'px; height:'+h+'px'});
			new Effect.Morph(this.frame, {style: 'width:'+w+'px; height:'+h+'px; top:'+margin.top+'px; left:'+margin.left+'px;', afterFinish: function(){
				this.dims.frame.w = w;
				this.dims.frame.h = h;
				this._toggleLoading(false);
				if(append) this.display.update(append);
				if (animateObj) {
					new Effect.Appear(this.display.down(), {queue:'end', afterFinish: function(){ this.animating=false; }.bind(this)});
				} else {
					this.display.down().show();
					this.animating=false;
				}
			}.bind(this)});
		}
	},
	_browse: function(e, a, album, albumItem){
		var prev = this.innerPaging.down('a.sel');
		if(prev) prev.className = "go";
		a.className="sel";
		this._addObject(album, albumItem);
	},
	_fileExtension : function(url) {
		if (url.indexOf('?') > -1)
			url = url.substring(0, url.indexOf('?'));
		var ext = '';
		for (var x = (url.length-1); x > -1; x--) {
			if (url.charAt(x) == '.') return ext;
			ext = url.charAt(x)+ext;
		}
	},
	_getAlbumById: function(id){
		var indice = this.albums.ids.indexOf(id);
		if(indice>-1) return this.albums.items[indice];
		return [];
	},
	_getBrowserDimensions: function(){
		var dim=document.viewport.getDimensions();
		this.dims.viewport.w=dim['width'];
		this.dims.viewport.h=dim['height'];
	},
	_getFrameMargin: function(w, h){
		this._getScroll();
		if(w==undefined) w = this.dims.frame.w;
		if(h==undefined) h = this.dims.frame.h;
		w = parseInt(w);  h = parseInt(h);
		var fp = this.options.framePadding;
		var ml = ((this.dims.viewport.w-w-(fp.left+fp.right))/2)+this.dims.page.scrollx;
		var mt = ((this.dims.viewport.h-h-(fp.top+fp.bottom))/2)+this.dims.page.scrolly;
		ml = parseInt(ml);  mt = parseInt(mt);
		return {'top':mt, 'left':ml};
	},
	_getMaxDimensions: function(itemw, itemh){
		var fp = this.options.framePadding;
		var pl = this.options.pagingLayout;
		var maxw = this.dims.viewport.w-(fp.left+fp.right)*4;
		var maxh = this.dims.viewport.h-(fp.top+fp.bottom)*4;
		if(pl == "left" || pl == "right") maxw-=this.paging.getWidth();
		if(pl == "top" || pl == "bottom") maxh-=this.paging.getHeight();
		var div = 1;
		if(itemw>itemh){
			if(itemw>maxw) {
				div = maxw / itemw;
				itemw = parseInt(maxw);
				itemh = parseInt(itemh*div);
				if(itemh>maxh) {
					div = maxh / itemh;
					itemw = parseInt(itemw*div);
					itemh = parseInt(maxh);
				}
			}
		} else {
			if(itemh>maxh) {
				div = maxh / itemh;
				itemw = parseInt(itemw*div);
				itemh = parseInt(maxh);
				if(itemw>maxw) {
					div = maxw / itemw;
					itemw = parseInt(maxw);
					itemh = parseInt(itemh*div);
				}
			}
		}
		return {w:itemw, h:itemh};
	},
	_getMedia : function(url) {
		var ext = this._fileExtension(url);
		if(this.fileTypes.image.indexOf(ext)>-1) return "image";
		if(this.fileTypes.quicktime.indexOf(ext)>-1) return "quicktime";
		if(this.fileTypes.page.indexOf(ext)>-1) return "page";
		return "unknown";
	},
	_getPageDimensions : function() {
		var xScroll, yScroll;
		if (window.innerHeight && window.scrollMaxY) {	
			xScroll = document.body.scrollWidth;
			yScroll = window.innerHeight + window.scrollMaxY;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ 
			xScroll = document.body.scrollWidth;
			yScroll = document.body.scrollHeight;
		} else { 
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}
		var windowWidth, windowHeight;
		if (self.innerHeight) {	
			windowWidth = self.innerWidth;
			windowHeight = self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) { 
			windowWidth = document.documentElement.clientWidth;
			windowHeight = document.documentElement.clientHeight;
		} else if (document.body) { 
			windowWidth = document.body.clientWidth;
			windowHeight = document.body.clientHeight;
		}
		this.dims.page.h = (yScroll < windowHeight) ? windowHeight : yScroll;
		this.dims.page.w = (xScroll < windowWidth) ? windowWidth : xScroll;
	},
	_getResizeDimensions: function(itemW, itemH){
		var pd = (!this.options.hidePaging) ? this.innerPaging.getDimensions() : {width: 0, height: 0};
		var ld = this.loading.getDimensions();
		switch(this.options.pagingLayout){
			case "left":
			case "right":
				if(itemW<ld.width) itemW = ld.width;
				if(itemH<ld.height) itemH = ld.height;
				itemW += pd.width;
				if(itemH<pd.height) itemH=pd.height;
				return {w: itemW, h: itemH};
				break;
			case "top":
			case "bottom":
				if(itemW<ld.width) itemW = ld.width;
				if(itemH<ld.height) itemH = ld.height;
				itemH += pd.height;
				if(itemW<pd.width) itemW=pd.width;
				return {w: itemW, h: itemH};
				break;
		}
	},
	_getSameMediaItems: function(album, itemIndex){
		var obj = album[itemIndex];
		var media = obj.media;
		var arr=[];
		for(i=0; i<album.length; i++) 
			if (i!=itemIndex && album[i].media==media) arr.push(i);
		return arr;
	},
	_getScroll : function(){
		var so = document.viewport.getScrollOffsets();
		this.dims.page.scrollx = so.left;
		this.dims.page.scrolly = so.top;
	},
	_setupDimensions : function() {
		// Frame
		var margin = this._getFrameMargin();
		var frame = this._getResizeDimensions(this.dims.frame.w, this.dims.frame.h);
		this.frame.setStyle({
			position: 'absolute',
			width: frame.w+'px',
			height: frame.h+'px',
			top: margin.top+'px',
			left: margin.left+'px',
			padding: this.options.framePadding.top+'px '+this.options.framePadding.right+'px '+this.options.framePadding.bottom+'px '+this.options.framePadding.left+'px'
		});
		// container
		this.container.setStyle({
			width: frame.w+'px',
			height: frame.h+'px'
		});
		// paging
		var obj = (this.options.pagingLayout == "left" || this.options.pagingLayout == "right") ? {height:frame.h+'px'} : {width: frame.w+'px'};
		this.paging.setStyle(obj);
		
		this.ready = true;
	},
	_setupOverlay: function (){
		this._getPageDimensions();
		this.overlay.setStyle({
			'width': "100%",
			'height': this.dims.page.h+"px",
			'opacity': this.options.overlayOpacity,
			'position': 'absolute',
			'top': '0',
			'left': '0'
		});
	},
	_showOverlayAlbum: function(visible){
		if(visible){
			this.frame.show();
			this.overlay.show();
		} else {
			this.frame.hide();
			this.overlay.hide();
		}
	},
	_stopScrolling : function(e) {
		if (this.active) {
			if (e.preventDefault) {
				e.preventDefault();
			}
			e.returnValue = false;		
		}
	},
	_toggleLoading: function(visible){
		if(visible) 
			this.loading.show();
		else
			this.loading.hide();
	},
	_togglePaging: function(visible){
		if(visible!=undefined){
			if(!visible) 
				this.paging.hide();
			else
				this.paging.show();
			return;
		}
		if(this.options.hidePaging) 
			this.paging.hide();
		else 
			this.paging.show();
	},
	_toggleTroubleElements : function(visibility, content){
		if (content) {
			var selects = $('lightwindow_contents').getElementsByTagName('select');
		} else {
			var selects = document.getElementsByTagName('select');
		}
		
		for(var i = 0; i < selects.length; i++) {
			selects[i].style.visibility = visibility;
		}
		
		if (!content) {
			if (this.options.hideFlash){
				var objects = document.getElementsByTagName('object');
				for (i = 0; i != objects.length; i++) {
					objects[i].style.visibility = visibility;
				}
				var embeds = document.getElementsByTagName('embed');
				for (i = 0; i != embeds.length; i++) {
					embeds[i].style.visibility = visibility;
				}
			}
			var iframes = document.getElementsByTagName('iframe');
			for (i = 0; i != iframes.length; i++) {
				iframes[i].style.visibility = visibility;
			}
		}
	}
}