var Overlay = Class.create({
	imageTemplate: new Template('<img class="funimg" src="#{imgSrc}" width="#{imgWidth}" height="#{imgHeight}"/>'),
	initialize: function(options) {
		this.options = {
			overlay: 'overlay',
			container: 'popup-container',
			content: 'popup-content',
			closeLink: 'popup-closelink',
			permaLink: 'popup-permalink',
			topRight: 'top-right',
			nextArrow: 'arrow-right',
			prevArrow: 'arrow-left',
			// bottomRight: 'bottom-right',
			// rightSide:'right-side',
			// topLeft: 'top-left',
			// bottomLeft:'bottom-left',
			spinner: 'spinner',
			title: 'popup-title',
			horizontalCenter: 703,
			widthMode: Overlay.FIXED
		};
		this.els = {};
		this.images = [];
		this.setOptions(options || {});
		// attach!
		var els = this.els;
		els.overlay.observe('click',this.cancel.bind(this));
		els.closeLink.observe('click',this.cancel.bind(this));
		if (els.prevArrow) {
			els.prevArrow.observe('click',this.advance.bindAsEventListener(this));
			els.nextArrow.observe('click',this.advance.bindAsEventListener(this));
		};
	},
	advance: function(event){
		var dir = 'left';
		var el = event.element();
		var which = false;
		if (el.id == 'arrow-left') {
			which = this.prev;
		} else {
			which = this.next;
		}
		if (which) {
			this.loadFunContent(which)
		} else {
			alert('nowhere');
		}
	},
	cancel: function() {
		var e = this.els;
		this.hideSpinner();
		this.hideOverlay();
		this.hideContainer();
	},
	showOverlay: function() {
		var o = this.els.overlay;
		var p = this.getPageSize();
		o.setStyle({ width: p[0] + 'px', height: p[1] + 'px', left: p[2]+'px', top: '0px' });
		o.setOpacity(Overlay.NO_OPACITY).show();
		new Effect.Tween(o,0.001, Overlay.HIGH_OPACITY, { duration:  Overlay.SHORT_INTERVAL, scope: 'overlay' }, o.setOpacity);
	},
	hideOverlay: function() {
		new Effect.Fade(this.els.overlay, { duration: Overlay.MEDIUM_INTERVAL, scope: 'overlay' });
	},
	showSpinner: function() { 
		var sp = this.els.spinner;
		sp.show();
	},
	hideSpinner: function(quick) { 
		quick = true;
		if (quick) {
			this.els.spinner.hide();
		} else {
			new Effect.Fade(this.els.spinner);
		}
	},
	clickHandler: function(e) {
		var el = Event.element(e);
		if (el.tagName != 'A') el = el.up('A');
		this.els.permaLink.href = el.href;
		this.els.permaLink.title = el.href;
		
		this.showOverlay();
		this.hideContent();
		this.loadContent(el.readAttribute('popuppath'),el.readAttribute('title'),el.readAttribute('img_list'));
	},
	funStuffClickHandler: function(e){
		var el = Event.element(e);
		if (el.tagName != 'A') el = el.up('A');
		this.els.permaLink.href = el.href;
		this.els.permaLink.title = el.href;
		this.showOverlay();
		this.hideContent();
		this.loadFunContent(el);
	},
	showContent: function() {
		var c = this.els.content;
		c.scrollTop = 0;
		// this.els.container.scrollTop = 0;
		c.setOpacity(Overlay.NO_OPACITY).show();
		new Effect.Tween(c, Overlay.NO_OPACITY, 1.0, { duration: Overlay.MEDIUM_INTERVAL, scope: 'content' }, c.setOpacity);
	},
	hideContent: function() {
		var c = this.els.content;
		var c = this.els.content;
		c.setOpacity(Overlay.NO_OPACITY).update('');
		// new Effect.Tween(c, 1.0, 0.0001, { duration: 0.1, scope: 'content' }, c.setOpacity);
	},
	showContainer: function(w,h) {
		var containerWidth = 690;
		var containerHeight = 620;
		w = parseInt(w);
		h = parseInt(h);
		var containerEl = this.els.container;
		if (w > 0) {
			containerWidth  = w;
			containerHeight = h;
			var contentWidth    = w;
			var contentHeight   = h;
		
			var container = this.els.container;
		
			var changes = $H({
				'content': { width: contentWidth+'px', height: contentHeight+'px' },
				'container': this.centeredCoords(containerWidth,containerHeight,1)
			});
		
			var els = this.els;
			changes.each(function (pair) {
				var el = els[pair.key];
				if (!el) return;
				el.setStyle(pair.value);
			});
		} else {
			var cel = this.els.container;
			var p = this.centeredCoords(690,620);
			cel.setStyle(p);
			this.showSpinner();
			new Effect.Appear(cel, { duration: Overlay.MEDIUM_INTERVAL, scope: 'container' });
		}

		this.showSpinner();
		new Effect.Appear(containerEl, { duration: Overlay.MEDIUM_INTERVAL, scope: 'container' });
	},
	hideContainer: function() {
		new Effect.Fade(this.els.container, { duration: Overlay.MEDIUM_INTERVAL, scope: 'container' });
	},
	centeredCoords: function(w,h,setDim) {
		var vp = document.viewport.getDimensions();
		var s = document.viewport.getScrollOffsets();
		
		w = parseInt(w);
		h = parseInt(h);
		
		var p = {
			'left': ((s.left || 0)+Math.round(this.options.horizontalCenter - (w/2))),
			'top':  ((s.top || 0)+Math.round((vp.height-h)/2))
		};
		
		if (setDim) {
			Object.extend(p,{
				'width': (w)+'px',
				'height':(h)+'px'
			});
			s.top += 65;
			s.left += 65;
		};

		// if top or left scrolled out of viewport:
		if (p.left < s.left) p.left = s.left;
		if (p.top < s.top)   p.top  = s.top;
		// pixels
		p.left = p.left+'px';
		p.top  = p.top +'px';
		return p;
	},
	setOptions: function(opts) {
		Object.extend(this.options,opts);
		var o = this.options;
		var els = this.els;
		// $w('overlay container permaLink topRight rightSide bottomRight topLeft bottomLeft closeLink spinner content title').each(function(el) {
		$w('overlay container permaLink closeLink spinner nextArrow prevArrow content title').each(function(el) {
			if ($(o[el])) {
				els[el] = $(o[el]);
			}
		});
		var cel = els.container;
		els.topLeft = cel.down('div.pb-tl');
		els.bottomLeft = cel.down('div.pb-bl');
		els.leftSide = cel.down('div.pb-ls');
		els.rightSide = cel.down('div.pb-rs');
		
		this.els = els;
	},
	loadFunContent: function(el) {
		// var cel = this.els.container;
			var path = el.readAttribute('popuppath');
			var title = el.readAttribute('caption');
			var imglist = el.readAttribute('img_list');
			var dims = el.readAttribute('window_size').split(',');
			var els = this.els;
		
			this.els.permaLink.href = el.href;
			this.els.permaLink.title = el.href;
		
			els.title.update(title);

			this.prev = el.previous('A');
			this.next = el.next('A');
			
			els.prevArrow[this.prev ? 'show' : 'hide']();
			els.nextArrow[this.next ? 'show' : 'hide']();
			
			this.showContainer(dims[0],dims[1]);
			var responseText = this.imageTemplate.evaluate({
				imgSrc: imglist,
				imgWidth: dims[0],
				imgHeight: dims[1]
			});
			this.handleImageText(responseText);
			// this.els.content.update('image would go here!');
			// cel.show();
	},
	loadContent: function(path,title,imglist) {
		// var cel = this.els.container;
		this.els.title.update(title);
		this.showContainer();
		new Ajax.Request(path,{
			onSuccess: this.onSuccess.bind(this), 
			onFailure: this.onFailure.bind(this)
		});
	},
	ImageFragment: '<img[^>]*?src="([^>"]*)"',
	extractImages: function(t) {
    var matchAll = new RegExp(this.ImageFragment, 'img');
    var matchOne = new RegExp(this.ImageFragment, 'im');

		var str = ''+t;

    return (str.match(matchAll) || []).map(function(imtag) {
      return (imtag.match(matchOne) || ['', ''])[1];
    });
	},
	onSuccess: function(t){
		this.handleImageText(t.responseText);
	},
	handleImageText: function(txt) {
		var tec = this.els.content;
		var imgs = this.extractImages(txt);		
		this.preloaded = $H();
		this.to_load = imgs.length;
		var self = this;
		tec.update("");
		
		imgs.each(function(img) {
			var i = new Image();
			var loadyfunc = function() {
				self.to_load--;
				if (self.to_load == 0) {
					self.hideSpinner();
					tec.update(txt);
					self.showContent();
				}

				// otherwise, nothing to do here...
			};
			i.onload  = loadyfunc;
			i.onerror = loadyfunc;
			self.preloaded[img] = i;			
		});
		imgs.each(function(img) {
			self.preloaded[img].src = img;
		});
		
		if (imgs.length == 0) {
			this.hideSpinner(true);
			tec.update(txt);
			self.showContent();
		}
	},
	onFailure: function(t) {
		var tec = this.els.content
		alert("some Error Occurred loading the popup.");
		
		tec.update('some Error occurred...');
		this.hideOverlay();
	},
	getPageSize: function() {
		var scrX,scrY;
		var bod = document.body;
		var del = document.documentElement;
		var w = (bod && bod.clientWidth) || 100;
		var h = (bod && bod.clientHeight) || 100;
		var scrX = window.pageXOffset || (bod && (bod.scrollLeft)) || (del && del.scrollLeft);
		var scrY = window.pageYOffset || (bod && (bod.scrollTop)) ||  (del && del.scrollTop);
		this.width = w;
		this.height = h;
		this.scrollX = scrX;
		this.scrollY = scrY;
		return [w,h,scrX,scrY];
	}
});
Overlay.FIXED = 1;
Overlay.VARIABLE = 2;
Overlay.HIGH_OPACITY = 0.85;
Overlay.NO_OPACITY = 0.001;
Overlay.SHORT_INTERVAL = 0.1;
Overlay.MEDIUM_INTERVAL = 0.31443;

document.observe("dom:loaded", function() {
  // initially hide all containers for tab content
	var overlay = new Overlay();
	
	$$('a.clientbox, a.funbox').each(function(box) {
		if (box.hasClassName('funbox')) {
			box.observe('click',overlay.funStuffClickHandler.bindAsEventListener(overlay));
		} else {
			box.observe('click',overlay.clickHandler.bindAsEventListener(overlay));
		};
	});
	window.overlay = overlay;
});

