/**
 * $Id: include.js,v 1.40 2010/08/24 17:34:58 cvs Exp $
 *
 * @author Frederick J Richart
 * @copyright Copyright © 2006-2010, Useful Media Planet, LLC, All rights reserved.
 */
 function AnimatedImage(id, delay, info, images, trans_option) {
 	this.id = id;
 	this.delay = delay;
 	this.info = info;
 	this.images = images;
 	this.trans_option = trans_option;
 	this.pan_easing = '';
 	Utilities.onload(this);
 }
 AnimatedImage.prototype = {
 	onPageLoad : function() {
		var i, t = this, src, img, e, w, h, o, alt, p, v, info = t.info, images = t.images, thumbsDiv = null;
		img = t.image = document.getElementById(t.id);
		if (info.thumbs) {
			thumbsDiv = document.getElementById(info.thumbs);
		}
		t.div = img.parentNode;
		t.anchor = t.div.parentNode;
		p = img.parentNode;
		if (info instanceof Object) {
			t.path = '';
			for(i in info) t[i] = info[i];
			t.cleft = Math.round((t.width = info.width) / 2) + 'px';
			t.ctop = Math.round((t.height = info.height) / 2) + 'px';
		} else {
			t.path = info;
		}
		if (t.paging_div) t.paging_div = document.getElementById(t.paging_div);
		alt = img.getAttribute("alt");
		t.imgs = new Array();
		t.index = t.trans_effect == 'flashy' ? images.length : 0;
		t.flipping = true;
		for(var i=0; i<images.length; i++) {
			img = new Image();
			o = images[i];
			if (o instanceof Object) {
				src = o.src;
			} else {
				src = o;
				o = new Object();
				o.src = src;
			}
			o.index = i;
			img.info = o;
			if (t.path) src = t.path + (src.substr(0,1) == '/' ? '' : '/') + src;
			o.src = img.src = src;
			if (w = o.width) {
				img.setAttribute("width", w);
				img.setAttribute("height", h = o.height);
				img.setAttribute("alt", alt);
				if (t.trans_effect != 'jflip') {
					o.left = img.style.left = (v = Math.max(0, Math.round((t.width - w) / 2))) + 'px';
					o.right = (v + w) + 'px';
					o.top = img.style.top = (v = Math.max(0, Math.round((t.height - h) / 2))) + 'px';
					o.bottom = (v + h) + 'px';
					img.style.position = "absolute";
				}
				/*
				 * Here we either add the image to the end or in the case of the first
				 * image we replace the one that was loaded with the page with the
				 * one we just generated (they should be the same).
				 */
				if (i) {
					img.style.display = "none";
					p.appendChild(img);
				} else {
					p.replaceChild(img, t.image);
					t.image = img;
				}
			}
			//If we are generating thumb indicators, it is done here.
			if (thumbsDiv) {
				thumbsDiv.appendChild(e = document.createElement("div"));
				e.className = i ? "AnimatedImageThumbContainer" : "AnimatedImageSelectedThumbContainer";
				o.thumb = e;
				e.info = o;
				e.onclick = function(e){t.click(e)};
			}
			o.panorama = (o.width > t.width);
			o.img = img;
			t.imgs[i] = o;		
		}
		// Add thumbs ending element
		if (thumbsDiv) {
			e = document.createElement("div");
			e.className = "AnimatedImageThumbEnd";
			thumbsDiv.appendChild(e);
		}
		t.current = t.imgs[0];
		switch (t.trans_effect){
			case 'flashy':
				t.flip(null);
				break;
			case 'jflip':
				t.imgarray = new Array();
				t.allLoaded = false;
				t.checkTimerID = setInterval(function(){t.checkLoaded();}, 1000);
				$(t.imgs).each(function(){
					var i = this.img;
					t.imgarray.push(i); 
				});
				t.flip(null);
				break;
			default:
				t.display(t.imgs[0]);
		}
	},
	click : function(event) {
		var t = this, e, evt = window.event || event;
		e = evt.target ? evt.target : evt.srcElement;
		if (e && e.info) {
			if (t.flipTimerID) clearInterval(t.flipTimerID);
			t.flipping = false;
			t.flip(e.info.index);
		}
	},
	checkLoaded : function() {
		var t = this, i;
		if (!t.allLoaded) {
			for(i in t.imgs) {
				if (!t.imgs[i].loaded) return;
			}
			t.allLoaded = true;
			t.flip(null);
		}
		clearInterval(t.checkTimerID);
	},
	start : function() {
		var t = this;
		if (!t.image) return;
		t.flipTimerID = setInterval(function(){t.flip(null);}, this.delay);
	},
	flip : function(newIndex) {
		var t = this, i, v, o, img, time,sop,eop, opt;
		if (newIndex === null) {
			i = ++t.index
			if (i >= t.images.length) i = t.index = 0;
		} else {
			i = t.index = newIndex;
		}
		t.last = ((i+1) == t.images.length);
		o = t.imgs[i];
		/*
		 * We seem to have wierdness with IE where randomly the image ends up much larger
		 * here than what we set above.  Rather than trying to figure out why this 
		 * piece of junk does this (none of the other browsers do), we'll just keep 
		 * resetting the size here.
		 */
		if (o.width) {
			o.img.setAttribute("width", o.width);
			o.img.setAttribute("height", o.height);
		}
		opt = t.trans_option ? t.trans_option : new Object();
		// Hide panorama overflow if new image a panorama but don't change if not (last image could be panorama)
		if (o.panorama) $(t.anchor).css({overflow:'hidden'});
		switch(t.trans_effect) {
		case "fade":
			clearInterval(t.flipTimerID);
			time = t.trans_time / 2;
			$(t.image).css({opacity:1});
			$(t.image).animate({opacity:0}, time, t.easing, function(){				
				t.image.style.display = 'none';
				$(o.img).css({opacity:0,display:'inline'});
				$(o.img).animate({opacity:1}, time, t.easing, function(){
					t.endTrans(o);
				});
			});
			break;
		case "fadeover":
			clearInterval(t.flipTimerID);
			$(t.image).css({'z-index':2000});
			$(o.img).css({'z-index':1000,opacity:0,display:'inline'});
			$(t.image).animate({opacity:0},{queue:false, duration:t.trans_time, easing:t.easing});
			$(o.img).animate({opacity:1}, t.trans_time, t.easing, function(){
				t.endTrans(o);
			});
			break;
		case "growover":
			clearInterval(t.flipTimerID);
			$(t.image).css({'z-index':1000});
			$(o.img).css({'z-index':2000,display:'inline',width:'0px',height:'0px',left:t.cleft,top:t.ctop});
			$(o.img).animate({width:o.width,height:o.height,top:o.top,left:o.left}, t.trans_time, t.easing, function(){
				t.endTrans(o);
			});
			break;
		case "flashy":
			clearInterval(t.flipTimerID);
			$(t.image).css({display:'none'});
			if (t.last) {
				v = [t.cleft,t.ctop];
				sop = 0.4; eop = 1;
			} else {
				v = t.rndSelect([[o.left,o.top],[t.cleft,o.top],[o.right,o.top],[o.left,o.bottom],[t.cleft,o.bottom],[o.right,o.bottom]]);
				sop = 1; eop = 0.4;
			}
			$(o.img).css({display:'inline',width:'0px',height:'0px',left:v[0],top:v[1],opacity:sop});
			$(o.img).animate({width:o.width,height:o.height,top:o.top,left:o.left,opacity:eop}, t.trans_time, t.easing, function(){
				t.endTrans(o);
			});
			break;
		case "explode":
		case "puff":
		case "fold":
		case "clip":
			v = t.rndSelect(['horizontal','vertical']);
		case "drop":
		case "slide":
			if (!v) v = t.rndSelect(['left','right','up','down']);
			clearInterval(t.flipTimerID);
			$(t.image).css({'z-index':2000});
			$(o.img).css({'z-index':1000,display:'inline'});
			$(t.image).hide(t.trans_effect, jQuery.extend({pieces:25, easing:t.easing, size:t.height/3, direction:v}, opt), t.trans_time, function(){
				t.endTrans(o);
			});
			break;
		case "flip":
			clearInterval(t.flipTimerID);
			if (t.current.panorama) $(t.image).css({width:t.width,left:t.current.left});
			$(t.image).flip(jQuery.extend({easing:t.easing, direction:t.rndSelect(['rl','lr','tb','bt']), color:t.trans_color, content:$(o.img), onEnd:function(){
				if (t.current.panorama) $(t.image).css({width:t.current.width});
				$(o.img).css({display:'inline'});
				t.endTrans(o);
			}}, opt));
			break;
		case "cube":
			clearInterval(t.flipTimerID);
			var r = t.width / 5;
			var e = t.width / 12;
			var s = t.width / 10;
			$(t.div).imagecube(jQuery.extend({speed:t.trans_time, easing:t.easing, repeat:t.repeat, pause:t.delay,reduction:r,expansion:e,segments:s, beforeRotate:function(current, next){
				var xx,yy;
				if ((xx = current.src.indexOf(".cube"))>0) 
					$(current).css({border:'2px solid black'});
				if ((yy = next.src.indexOf(".cube"))>0) 
					$(next).css({border:'2px solid black'});
				var x =1;
			}, afterRotate:function(current, next){
				var o = next.info;
				$(next).css({width:o.width+'px', height:o.height+'px'});
			}}, opt));
			break;
		case "jflip":
			clearInterval(t.flipTimerID);
			$(t.div).jFlip(t.width, t.height, jQuery.extend({background:'#fff', cornersTop:false, curlSize:0.15, circular:false}, opt), $(t.imgarray)).bind("flip.jflip",function(event,index,total){
				if(t.paging_div) {
					$(t.paging_div).html($t.paging + " " + (index+1) + " of " + total)
				}
			});
			break;
		default:
			if (o.width) {
				// Disable current and enable new
				img = o.img;
				t.image.style.display = "none";
				img.style.display = 'inline';
				t.image = img;
			} else {
				// Old style - just replace src attribute
				t.image.src = o.src;
			}
		}
	},
	endTrans : function(o) {
		var t = this;
		$(t.image).css({display:'none',left:t.current.left});
		t.image = o.img;
		if (t.last && (!t.repeat || t.trans_effect == 'flashy' )) return;
		t.display(o);
	},
	display : function(o) {
		var t = this, thumb;
		// Handle thumb display
		if (thumb = t.current.thumb) thumb.className = "AnimatedImageThumbContainer";
		if (thumb = o.thumb) thumb.className = "AnimatedImageSelectedThumbContainer";
		t.current = o;
		$(t.anchor).css({overflow: (o.panorama) ? 'hidden' : 'visible'});
		$(o.img).css({left:o.left});
		if (o.panorama) {
			// Panorama
			$(o.img).animate({left:-(o.width-t.width)}, t.pan_time, t.pan_easing, function(){
				if (t.flipping) t.flipTimerID = setInterval(function(){t.flip(null);}, t.delay);
			});
		} else {
			if (t.flipping) t.flipTimerID = setInterval(function(){t.flip(null);}, t.delay);
		}		
	},
	rndSelect : function(a) {
		var i = Math.min(Math.floor((Math.random() * a.length)), a.length-1);
		return a[i];
	}
}
 
 Number.prototype.NaN0=function(){return isNaN(this)?0:this;}
 function UtilitiesEngine() {
 	var t = this;
	var agent = navigator.userAgent;
	t.Opera = window.opera && opera.buildNumber;
	t.WebKit = /WebKit/.test(agent);
	t.IE = !this.WebKit && !this.Opera && (/MSIE/gi).test(agent) && (/Explorer/gi).test(navigator.appName);
	t.IE6 = this.IE && /MSIE [56]/.test(agent);
	t.IE7 = this.IE && /MSIE [7]/.test(agent);
	t.IE67 = this.IE && /MSIE [567]/.test(agent);
	t.IE8 = this.IE && /MSIE [8]/.test(agent);
	t.Gecko = !this.WebKit && /Gecko/.test(agent);
	t.Chrome = t.WebKit && /Chrome/.test(agent);
	t.Safari = t.WebKit && !/Chrome/.test(agent);
	t.Mac = agent.indexOf("Mac") != -1;
	t.Registry = new Array();
	t.otherOnLoad = window.onload;
	t.analytics_user = null;
	if (typeof jQuery != "undefined") {
		$(document).ready(function(){t.onDocumentReady()});
	}
	window.onload = function() {t.onPageLoad()};
	t.otherOnUnload = window.onunload;
	window.onunload = function(){t.onPageUnload()};
	t.otherOnResize = window.onresize;
	window.onresize = function(){t.onPageResize();t.onPageUpdate()};
	t.loaded = false;
}
UtilitiesEngine.prototype = {
 	/**
 	 * This method is called whenever the browser calls the window.onunload()
 	 * method.  Any registered objects will have their onPageUnload method
 	 * called if that method exists.  This also handles other potential functions
 	 * that may have set windows.onunload
 	 */
	onPageUnload : function() {
		try {
			if (this.otherOnUnload) this.otherOnUnload();
		}
		catch(e) {
			// IE nonsense (can't use a standalone finally block
		}
		finally {
			for(var i=0; i<this.Registry.length; i++) {
				var r = this.Registry[i];
				if (r.onPageUnload) {
					try {r.onPageUnload();}
					catch(e) {
						// Don't let failures impact others
					}
				}
			}
		}
	},
	/**
	 * This method is called whenever the browser has finished loading the page and
	 * calls the window.onload() method.  Any registered objects that have an onPageLoad
	 * method will have that method called.  This also handles other potential functions
	 * that may have set windows.onload.
	 */
	onPageLoad : function() {
		// Don't let others cause crash
		try {
			if (this.otherOnLoad) this.otherOnLoad();
		}
		catch(e) {
			// More IE nonsense (can't use a standalone finally block)
		}
		finally {
			for(var i=0; i<this.Registry.length; i++) {
				var r = this.Registry[i];
				if (r.onPageLoad) {
					try {r.onPageLoad();}
					catch(e) {
						// Don't let failures impact others
					}
				}
			}
			this.loaded = true;
		}
	},
	/**
	 * This method is called if jQuery is loaded and the DOM is loaded and ready. 
	 * Any registered objects that have an onDocumentReady method will have that 
	 * method called.  Since we might not have jQuery loaded, procedures will need
	 * to handle both onDocumentReady and onPageLoad and deal with the potential 
	 * of having both called or just onPageLoad.
	 */
	onDocumentReady : function() {
		for(var i=0; i<this.Registry.length; i++) {
			var r = this.Registry[i];
			if (r.onDocumentReady) {
				try {r.onDocumentReady();}
				catch(e) {
					// Don't let failures impact others
				}
			}
		}
	},	
	/**
	 * This method is called whenever the browser has resized the page and calls the 
	 * window.onresize() method.  Any registered objects that have an onPageResize
	 * method will have that method called.  This also handles other potential functions
	 * that may have set windows.onresize.
	 */
	onPageResize : function() {
		// Don't let others cause crash
		try {
			if (this.otherOnLoad) this.otherOnLoad();
		}
		catch(e) {
			// More IE nonsense (can't use a standalone finally block)
		}
		finally {
			for(var i=0; i<this.Registry.length; i++) {
				var r = this.Registry[i];
				if (r.onPageResize) {
					try {r.onPageResize();}
					catch(e) {
						// Don't let failures impact others
					}
				}
			}
		}
	},
	/**
	 * Use this method to register an object to be called on load, unload, and page update
	 * It is identical to register() and you should use register() as the name is more
	 * meaningful.
	 * @param obj
	 */
	onload : function(obj) {
		if (this.loaded) {
			if (obj.onPageLoad) obj.onPageLoad();
			return;
		}
		this.Registry.push(obj);
	},
	/**
	 * Use this method to register an object to be called on load, unload, and page update.
	 * It is identical to onload() but the name is more meaningful
	 * @param obj
	 */
	register : function(obj) {
		this.Registry.push(obj);
	},
	/**
	 * This method can be called if the page has been altered and you want to inform
	 * registered objects of that event.  Any registered objects that have an onPageUpdate
	 * method will be invoked.  This does not correspond with any browser generated
	 * event.
	 */
	onPageUpdate : function() {
		for(var i=0; i<this.Registry.length; i++) {
			var r = this.Registry[i];
			if (r.onPageUpdate)
				r.onPageUpdate();
		}
	},
	doResizeIframe : function(t, iframe, body) {
		var h, w;
		h = t.IE ? body.offsetHeight : body.scrollHeight;
		w = t.IE ? body.offsetWidth : body.scrollWidth;
		if (h && w) {
			iframe.style.width = w + 30 + "px";
			iframe.style.height = h + 30 + "px";
		}
	},
	resizeIframe : function(id, iframe) {
		var t = this, body, interval, frame;
		// IE has a bizzarre setup where the iframe element isn't really the iframe jeeze louise.
		frame = t.IE ? window.frames[id] : iframe;
		body = frame.contentDocument ? frame.contentDocument.body :frame.document.body;
		t.doResizeIframe(t, iframe, body);
		// interval = window.setInterval(function(){t.doResizeIframe(t, iframe, body);}, 200);
	},
	getStyle : function(element, style) {
		if (!element) return null;
		if (document.defaultView) {
			// Remove camelcase
			style = style.replace(/[A-Z]/g, function(a){
				return '-' + a;
			});
			try {
				return document.defaultView.getComputedStyle(element, null).getPropertyValue(style);
			} catch (ex) {
				// Old safari might fail
				return null;
			}
		}
		// Camelcase it, if needed
		style = style.replace(/-(\D)/g, function(a, b){
			return b.toUpperCase();
		});

		if (style == 'float')
			style = this.IE ? 'styleFloat' : 'cssFloat';

		// IE & Opera
		if (element.currentStyle) return element.currentStyle[style];
		return element.style[style];		
	},
	getStylePixelValue : function(element, style) {
		var v, px;
		if (!element) return 0;
		v = this.getStyle(element, style);
		px = v.indexOf('px');
		if (px == -1) return 0;
		return (parseInt(v)).NaN0();
	},
	isContainingBlock : function(element) {
		if (!element) return false;
		var pos = this.getStyle(element, "position");
		return pos != "static";
	},
	getAbsPosition : function(element, className, pageAbs){
		var left = 0, top = 0, e = element, boxModel = !this.IE || document.compatMode == 'CSS1Compat',
			pl = this.getStylePixelValue(element, 'padding-left'),
			pr = this.getStylePixelValue(element, 'padding-right'),
			pt = this.getStylePixelValue(element, 'padding-top'),
			pb = this.getStylePixelValue(element, 'padding-bottom'),
			bl = this.getStylePixelValue(element, 'border-left-width'),
			bt = this.getStylePixelValue(element, 'border-top-width');
		
		if (this.IE && false) {
			e = e.getBoundingClientRect();
			var bodyElement = boxModel ? document.documentElement : document.body;
			// Skipping this for now
			// x = t.getStyle(t.select('html')[0], 'borderWidth'); // Remove border
			// x = (x == 'medium' || boxModel && !t.isIE6) && 2 || x;
			// e.top += t.win.self != t.win.top ? 2 : 0; // IE adds some strange extra cord if used in a frameset
			left = e.left + bodyElement.scrollLeft; // - x;
			top = e.top + bodyElement.scrollTop; // - x;
			element.absPosition = {
				left   : left, 
				top    : top,
				right  : parseInt(e.offsetWidth) + left + pl + pr,
				bottom : parseInt(e.offsetHeight) + top + pt + pb
			};
			return element.absPosition;
		}
		
		while (e){
			left += (e.offsetLeft || 0) + this.getStylePixelValue(e, 'border-left-width');
			top += (e.offsetTop || 0) + this.getStylePixelValue(e, 'border-top-width');
			e = e.offsetParent;
			if (!pageAbs && this.isContainingBlock(e)) {
				if (this.IE8 || this.Opera) break;
				// It seems IE & Opera count border width on this element and the others don't.
				left += this.getStylePixelValue(e, 'border-left-width');
				top += this.getStylePixelValue(e, 'border-top-width');
				break;
			}
		}
		element.absPosition = {
			left   : left, 
			top    : top, 
			right  : parseInt(element.offsetWidth) + left + pl + pr, 
			bottom : parseInt(element.offsetHeight) + top + pt + pb
		};
		return element.absPosition;
	},
	/**
	 * Special purpose method to "open" the expandable login form by
	 * enabling all the rows following the row this element is placed.
	 */
	openLoginForm : function(e) {
		var t = this, row, form = e.form;
		if (!e || e.formOpened) return;
		if (t.openElement) t.closeLoginForm(t.openElement);
		t.openElement = e;
		e.formOpened = true;
		e.savedValue = e.value;
		e.value='';
		e.style.color='#000';
		for (row = e.parentNode.parentNode; row; row = row.nextSibling) {
			if (row.nodeType != 1) continue;
			row.style.display = "block";
		}
		form.style.border = "2px solid";
		form.style.padding = "5px";
		
		/**
		 * Yet another convoluted workaround for this piece of junk!  In IE6/7 the
		 * submit click does nothing.  This is probably related to the fact that
		 * the buttons and some other parts of the form were in table rows that were
		 * hidden (display:none).  I can figure no other way to make this damn thing
		 * work.  NOTE: the button name must be "submit_button" or thise code needs
		 * to change to reflect another name.
		 */
		if (Utilities.IE67) {
			form.submit_button.onclick = function(e){
				if (form.SecureLogin) form.SecureLogin.submit();
				else form.submit();
			};
		}
	},
	/**
	 * Special purpose method to "close" an expandable login form "opened"
	 * by openLoginForm.  It disables all but the first row.
	 */
	closeLoginForm : function(e) {
		var t = this, row;
		if (!(e = t.openElement)) return;
		t.openElement = null;
		e.formOpened = false;
		e.value = e.savedValue;
		e.style.color = '#777'
		for (row = e.parentNode.parentNode.nextSibling; row; row = row.nextSibling) {
			if (row.nodeType != 1) continue;
			row.style.display = "none";
		}
		e.form.style.border = "0px";
		e.form.style.padding = '0px';
	},
	setupAnalytics : function(domain, tracker_id) {
		var t = this;
		$(document).ready(function(){  
			var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");  
			$.getScript(gaJsHost + "google-analytics.com/ga.js", function(){  
				try {  
					var pageTracker = window.pageTracker = _gat._getTracker(tracker_id);
					pageTracker._setDomainName(domain);
					pageTracker._initData();
					pageTracker._trackPageview();
					if (t.analytics_user) pageTracker._setVar(t.analytics_user);
				} catch(err) {}
				
				var filetypes = /\.(zip|exe|pdf|doc*|xls*|ppt*|mp3)$/i;  
				$('a').each(function(){  
					var href = $(this).attr('href');  
					if ((href.match(/^https?\:/i)) && (!href.match(document.domain))){  
						$(this).click(function() {  
							var extLink = href.replace(/^https?\:\/\//i, '');  
							pageTracker._trackEvent('External', 'Click', extLink);  
						});  
					}  
					else if (href.match(/^mailto\:/i)){  
						$(this).click(function() {  
							var mailLink = href.replace(/^mailto\:/i, '');  
							pageTracker._trackEvent('Email', 'Click', mailLink);  
						});  
					}  
					else if (href.match(filetypes)){  
						$(this).click(function() {  
							var extension = (/[.]/.exec(href)) ? /[^.]+$/.exec(href) : undefined;  
							var filePath = href.replace(/^https?\:\/\/(www.)mydomain\.com\//i, '');  
							pageTracker._trackEvent('Download', 'Click - ' + extension, filePath);  
						});  
					}  
				});  
			});  
		});  	
	},
	setupAnalyticsUser : function(user) {
		this.analytics_user = user;
	},
	/**
	 * The loadJavascript method dynamically loads javascript or a javascript file.
	 * When loading javascript, this initiates the process but does not guarantee
	 * that the file is loaded.  If you need to know when the file has loaded you 
	 * should add a timer with callback to test for file's presence.
	 * 
	 * @param src
	 * @param path
	 * @return void
	 */
	loadJavascript : function (src, path) {
		var e = document.createElement('script');
		e.setAttribute('type', 'text/javascript');
		e.setAttribute('language', 'javascript');
		if (path) e.setAttribute('src', path);
		else {
			e.text = src;
			e.setAttribute('defer', 'defer');
		}
		document.getElementsByTagName('head')[0].appendChild(e);
	}
}
Utilities = new UtilitiesEngine();
/**
 * Utility that will cause the bottom and/or right sides of the subject element
 * to match those of the target element by adjusting the height and/or width of
 * the adjustor element.  You MUST make sure that the adjustor element height/width
 * changes will directly cause the subject element to change.  The height is adjusted
 * unless doHeight is false and doWidth is true.  The width is adjusted only if
 * doWidth is true.
 * 
 * You may also specify h/w offsets.  When specified the target is adjusted not 
 * to match the subject but rather to the offset from the target.
 * 
 * @param subjectID
 * @param targetID
 * @param adjustorID
 * @param hOffset
 * @param wOffset
 * @param doHeight
 * @param doWidth
 * @return
 */
function SizeMatcher(subjectID, targetID, adjustorID, hOffset, wOffset, doHeight, doWidth) {
	this.subjectID = subjectID;
	this.targetID = targetID;
	this.adjustorID = adjustorID;
	this.doHeight = doHeight || !doWidth;
	this.doWidth = doWidth;
	this.hOffset = hOffset ? hOffset : 0;
	this.wOffset = wOffset ? wOffset : 0;
	this.started = false;
	Utilities.onload(this);
}
SizeMatcher.prototype = {
	onPageLoad : function() {
		var t = this, subject, target, adjustor;
		if (t.started) return;
		t.started = true;
		if (!(t.subject = document.getElementById(t.subjectID))) return;
		if (!(t.target = document.getElementById(t.targetID))) return;
		if (!(t.adjustor = document.getElementById(t.adjustorID))) return;
		t.doResize();
		t.interval = window.setInterval(function(){t.doResize()}, 200);
	},
	onDocumentReady : function() {
		this.onPageLoad();
	},
	doResize : function() {
		var t = this, spos, tpos, ntpos, v, adj = t.adjustor;
		spos = Utilities.getAbsPosition(t.subject);
		tpos = Utilities.getAbsPosition(t.target);
		if (t.doHeight && spos.bottom != (tpos.bottom + t.hOffset)) {
			v = Math.max(parseInt(adj.offsetHeight) + tpos.bottom - spos.bottom + t.hOffset, 0);
			adj.style.height = v + 'px';
		}
		if (t.doWidth && spos.right != (tpos.right + t.wOffset)) {
			v = Math.max(parseInt(adj.offsetWidth) + tpos.right - tpos.top + t.wOffset, 0);
			adj.style.width = v + 'px';
		}
		// Stop adjusting if we have impacted the target
		ntpos = Utilities.getAbsPosition(t.target);
		if (tpos.bottom != ntpos.bottom || tpos.top != ntpos.top || tpos.left != ntpos.left || tpos.right != ntpos.right) {
			window.clearInterval(t.interval);
		}
	}
}
function ShadowBox(id, c, bg, cr, bc, bw, sc, so, ss, sx, sy) {
	this.id = id
	this.color = c;
	this.bgcolor = bg;
	this.corner = cr;
	this.borderColor = bc;
	this.borderWidth = bw;
	this.shColor = sc;
	this.shOpacity = so;
	this.shSigma = ss;
	this.shX = sx;
	this.shY = sy;
	Utilities.onload(this);
}
ShadowBox.prototype = {
	onPageLoad : function() {
		var t = this;
		var sc = document.getElementById(t.id);
		var pad = t.pad = sc.parentNode;
		if (pad.className != "shadowbox_pad") return;
		var n = t.cell = pad.parentNode;
		if (n.className == "shadowbox_cell") {
			while(n && n.className != 'shadowbox_outer') n = n.parentNode;
			if (!n) return;
		}
		t.outer = n;
		if (n.className != "shadowbox_outer") return;
		t.w = t.h = 0;
		t.doResize();
		t.interval = window.setInterval(function(){t.doResize()}, 200);
	},
	doResize : function() {
		var t = this,pad = t.pad, w = pad.offsetWidth, h = pad.offsetHeight, v;
		if (t.w == w && t.h == h) return;
		t.w = w; t.h = h;
		var st = 'url(/images/dropimg.php?shadowbox=1&w=' + w + '&h=' + h;
		if (v = t.color) st += '&color=' + encodeURIComponent(v);
		if (v = t.bgcolor) st += '&bgcolor=' + encodeURIComponent(v);
		if (v = t.corner) st += '&corner=' + encodeURIComponent(v);
		if (v = t.borderColor) st += '&border_color=' + encodeURIComponent(v);
		if (v = t.borderWidth) st += '&border_width=' + encodeURIComponent(v);
		if (v = t.shColor) st += '&shcolor=' + encodeURIComponent(v);
		if (v = t.shOpacity) st += '&shopacity=' + encodeURIComponent(v);
		if (v = t.shSigma) st += '&shsigma=' + encodeURIComponent(v);
		if (v = t.shX) st += '&shx=' + encodeURIComponent(v);
		if (v = t.shY) st += '&shy=' + encodeURIComponent(v);
		t.outer.style.backgroundImage = st + ')';		
	}
}
function WarningBlocker(blocker_id, blocked_id) {
	this.blocker_id = blocker_id;
	this.blocked_id = blocked_id;
	Utilities.onload(this);
}
WarningBlocker.prototype = {
	onPageLoad : function() {
		var t = this, w, h, blocker, blocked, pos;
		blocker = document.getElementById(t.blocker_id);
		blocked = document.getElementById(t.blocked_id);
		if (!blocker || !blocked) return;
		w = blocked.offsetWidth;
		h = blocked.offsetHeight;
		pos = Utilities.getAbsPosition(blocked);
		blocker.style.display = "block";
		blocker.style.left = pos.left + "px";
		blocker.style.top = pos.top + "px";
		blocker.style.width = w + "px";
		blocker.style.height = h + "px";		
	},
	onPageUpdate : function() {
		this.onPageLoad();
	}
}
/*
* The constructor function: creates a cookie object for the specified
* document, with a specified name and optional attributes.
* Arguments:
*   document:	The Document object that the cookie is stored for. Required.
*   name:		A string that specifies a name for the cookie. Required.
*   time:		An optional number that specifies the time the cookie expires.
*					time is expressed as a unix timestamp so is the number of seconds
*					since epoch. A time of 0 makes the cookie transient.
*   path:		An optional string that specifies the cookie path attribute.
*   domain:		An optional string that specifies the cookie domain attribute.
*   secure:		An optional Boolean value that, if true, requests a secure cookie.
*/
function CookieUtil(document, name, time, path, domain, secure) {
	this.document = document;
	this.name = name;
	this.expiration = (time * 1) ? new Date(time * 1000) : null; // Date takes milliseconds
	this.path = path ? path : null;
	this.domain = domain ? domain : null;
	this.secure = secure ? true : false;
}
CookieUtil.prototype = {
	store : function (value) {
		var cookie = this.name + '=' + value;
		if (this.expiration) cookie += '; expires=' + this.expiration.toGMTString();
		if (this.path) cookie += '; path=' + this.path;
		if (this.domain) cookie += '; domain=' + this.domain;
		if (this.secure) cookie += '; secure';

		// Now store the cookie by setting the magic Document.cookie property.
		this.document.cookie = cookie;
	},
	read : function() { 
		// First, get a list of all cookies that pertain to this document.
		// We do this by reading the magic Document.cookie property.
		var allcookies = this.document.cookie;
		if (allcookies == "") return false;

		// Now extract just the named cookie from that list.
		var start = allcookies.indexOf(this.name + '=');
		if (start == -1) return false;   // Cookie not defined for this page.
		start += this.name.length + 1;  // Skip name and equals sign.
		var end = allcookies.indexOf(';', start);
		if (end == -1) end = allcookies.length;
		return allcookies.substring(start, end);
	},
	remove : function() {
		var cookie;
		cookie = this.name + '=';
		if (this.path) cookie += '; path=' + this.path;
		if (this.domain) cookie += '; domain=' + this.domain;
		cookie += '; expires=Fri, 02-Jan-1970 00:00:00 GMT';
		this.document.cookie = cookie;
	}
}