/*
	jQuery.sni
	created, modified and updated by Chris Engle
	cengle@scrippsnetworks.com
	last modfied date: 02-22-2009 11:30 ET
*/

/* -----------------------
JQuery Plugin Template
--------------------------
(function($) {
	$.fn.pluginName = function([paramList, ...], options) {
		var defaults = {
			defaultString: '',
			defaultInt: 0,
			defaultObj: {},
			defaultArray: []
		};
		var options = $.extend(defaults, options);
		return this.each(function(i) {
			var obj = this;
			// code here
		});
	};
})(jQuery);
*/

jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};

/*
	jQuery.timeDetector( time, options )
	
	time: [string] - A simple date/time format: 'January 01, 2009 13:30'
	options: [object] - A list of options / overrides
		hour					: override time.getHours()
		minute					: override time.getMinutes()
		day						: override time.getDate()
		month					: override time.getMonth()
		year					: override time.getFullYear()
		continuousCheck			: [boolean] - One time check on page load (usually) : Check once / options.continuousCheckInterval
		continuousCheckInterval	: [integer] - In seconds ( * 1000 ) to keep checking for expiration
		includeCentral			: [boolean] - Combine Central time zone with Eastern time zone
		includeMountain			: [boolean] - Combine Mountain time zone with Eastern time zone
		includePacific			: [boolean] - Combine Pacific time zone with Eastern time zone
		beforeExpire			: [function] - Any event to take place before expiration
		afterExpire				: [function] - Any event to take place after expiration
*/
jQuery.timeDetector = function( time, options ) {
	if ( !time ) { return; }
	time = new Date(time);
	var defaults = {
		hour: -1,
		minute: -1,
		day: -1,
		month: -1,
		year: -1,
		continuousCheck: false,
		continuousCheckInterval: 1, /* default to 1 second (will get multiplied by 1000) */
		includeCentral: false,
		includeMountain: false,
		includePacific: false,
		beforeExpire: function() {},
		afterExpire: function() {}
	};
	var options = $.extend(defaults, options);
	/* check our overrides */
	var year = parseInt(options.year, 10) != -1 ? parseInt(options.year, 10) : parseInt(time.getFullYear(), 10);
	var month = parseInt(options.month, 10) != -1 ? parseInt(options.month, 10) : parseInt(time.getMonth(), 10);
	var day = parseInt(options.day, 10) != -1 ? parseInt(options.day, 10) : parseInt(time.getDate(), 10);
	var hour = parseInt(options.hour, 10) != -1 ? parseInt(options.hour, 10) : parseInt(time.getHours(), 10);
	var minute = parseInt(options.minute, 10) != -1 ? parseInt(options.minute, 10) : parseInt(time.getMinutes(), 10);
	/* are we including Central, Mountain or Pacific? */
	var cHour = options.includeCentral != false ? (hour - 1) : hour;
	var mHour = options.includeMountain != false ? (hour - 2) : hour;
	var pHour = options.includePacific != false ? (hour - 3) : hour;
	/*
		function detectTime() - Here is where we actually make a choice as to what to do
	*/
	function detectTime() {
		var now = new Date();
		var showTime = time;
		if ( now.getTimezoneOffset() == 240 ) { /* eastern */ 
			showTime = new Date(year, month, day, hour, minute);
		} else if ( now.getTimezoneOffset() == 300 ) { /* central */
			showTime = new Date(year, month, day, cHour, minute);
		} else if ( now.getTimezoneOffset() == 360 ) { /* mountain */
			showTime = new Date(year, month, day, mHour, minute);
		} else if ( now.getTimezoneOffset() == 420 ) { /* pacific */
			showTime = new Date(year, month, day, pHour, minute);
		}
		if ( now >= showTime ) {
			options.afterExpire.call();
			clearInterval(i);
		} else {
			options.beforeExpire.call();
		}
	};
	/* check once OR once / options.continuousCheckInterval */
	if ( options.continuousCheck ) {
		var i = setInterval(function() { detectTime(); }, (options.continuousCheckInterval * 1000));
	} else {
		detectTime();
	}
};

jQuery.simpleEncrypt = function( method, val, key ) {
	if ( !method ) { return; }
	if ( !key ) { return; }
	var ret = '';
	switch ( method ) {
		case 'decode': { for ( i=0; i<val.length; i++ ) { ret += String.fromCharCode(key^val.charCodeAt(i)); } break; }
		case 'encode': { for ( i=0; i<val.length; ++i ) { ret += String.fromCharCode(key^val.charCodeAt(i)); } break; }
		default: { for ( i=0; i<val.length; ++i ) { ret += String.fromCharCode(key^val.charCodeAt(i)); } break; }
	}
	return ret;
};

$.fn.diyMarketplaceWidget = function(options) {
	var defaults = {
		wislist: '',
		listingIDs: '',
		keywords: '',
		width: 92,
		height: 69,
		sponsor: ''
	};
	var options = $.extend(defaults, options);
	function bubbleSort( ary ) {
		for (var i=ary.length - 2; i>=0;  i--) {
			for (var j=0; j<=i; j++) {
				var x = parseInt(ary[j + 1], ary[j + 1]);
				var y = parseInt(ary[j], ary[j]);
				if (x < y) {
					var tmp = ary[j]; ary[j] = ary[j + 1];
					ary[j + 1] = tmp;
				}
			}
		}
		return ary;
	};
	var parent = $(this);
	return $('.bd', this).each(function(i) {
		var obj = this;
		var getType = { name: 'wishlist', value: '' };
		if ( options.wishlist != '' ) {
			getType = { name: 'wishlist', value: options.wishlist }
		} else if ( options.listingIDs != '' ) {
			getType = { name: 'listingIDs', value: options.listingIDs }
		} else if ( options.keywords != '' ) {
			getType = { name: 'keywords', value: options.keywords }
		} else {
			return;
		}
		var strURL = 'http://marketplace.diynetwork.com/cms/managexmlfiles.aspx?xmlFile=SCRHGTV~FeatureProducts~' + getType.name + '=' + getType.value + ';w=' + options.width + ';h=' + options.height + '&json=true&callback=?';
		var sponsor = options.sponsor;
		$.ajax({
			url: strURL,
			dataType: 'jsonp',
			success: function(data) {
				$(obj)
					.json2HTML([{
					nodeName: 'ul',
					id: 'json-marketplace-widget',
					addClass: 'jcarousel-skin-tango clrfix'
				}]);
				var list = [];
				var li_count = 0;
				$.each(data.products, function(i, item) {
					var cn = '';
					if ( li_count == 0 ) {
						cn = 'crsl-item first';
					} else if ( li_count == (2 - 1) ) {
						cn = 'crsl-item last';
					} else {
						cn = 'crsl-item';
					}
					var li = {
						nodeName: 'li',
						addClass: cn,
						append: [{
							nodeName: 'img',
							attr: {
								src: item.photo,
								alt: item.name,
								width: '92',
								height: '69'
							}
						},{
							nodeName: 'p',
							append: [{
								nodeName: 'a',
								html: item.name,
								attr: { href: item.url }
							}]
						}]
					};
					list.push(li);
					li_count++;
					if ( data.products.length > 2 ) {
						if ( (i + 1) % 2 == 0 ) {
							$('#json-marketplace-widget').json2HTML([ { nodeName: 'li', addClass: 'panel', append: [{ nodeName: 'ul', addClass: 'crsl-group', append: list }] } ]);
							list = [];
							li_count = 0;
						}
					} else if ( data.products.length > 0 ) {
						$('#json-marketplace-widget').json2HTML([ { nodeName: 'li', addClass: 'panel', append: [{ nodeName: 'ul', addClass: 'crsl-group', append: list }] } ]);
					} else {
						$('#json-marketplace-widget').json2HTML([ { nodeName: 'li', addClass: 'panel', append: [{ nodeName: 'ul', addClass: 'crsl-group', append: [{ nodeName: 'li', html: 'No products available.' }] }] } ]);
					}
				});
				$.each($('ul', '#json-marketplace-widget'), function(i) { $(this).css('zoom', 1); });
				/* get the height of the tallest li */
				var h = [];
				$.each($('li', obj), function() { h.push(parseInt($(this).height(), 10)); });
				h = h.sort(function(a,b){return b - a})[0];
				/* make our max 160 for good old IE */
				h = h < 160 ? h : 160;
				/* let's make all the LI elements the same height */
				$.each($('li', obj), function() { $(this).height((h + 8) + 'px'); });
				SNI.Common.Carousel(parent, { pagelink:"image" });
				/* add stuff for tracking [&topic=SEO_SPONOR] */
				$.each($('a', parent), function() {
					var href = $(this).attr('href');
					$(this).attr('href', href + '&topic=' + sponsor);
				});
				/*
												TEMP SOLUTION
					for some darn reason, IE creates an extra empty LI at the beggining
					so I'm going to delete any empty LI elements that are ONLY DIRECT child
					elements of ul#json-marketplace-widget.
				*/
				if ( document.all ) { $.each($('li', parent), function() { if ( $(this).html() == '' ) { $(this).remove(); } }); }
			}
		});
	});
};

/*
	$.fn.marketplaceWidget BETA
	(being used as a temporay solution to having a marketplace widget at all on the right rail for HG)
	unfortunately this method (just like the other methods in this file), was needed and so I "hacked" it out
	just days before hackday.
	It acts like the swf version just with it's bare bones only though.  We're just fetching a list
	and it's returned in json format
	I then create a structure in the following fashion
	UL
		LI
			UL
				LI
				LI
				LI
			/
		/
		LI
			UL
				LI
				LI
				LI
			/...
	After that I merely add the dpl carousel to it the parent [UL] like so: $(parent).dpl('carousel', { pagelink: 'image' });
*/
$.fn.marketplaceWidget = function(options) {
	var defaults = {
		wislist: '',
		listingIDs: '',
		keywords: '',
		width: 100,
		height: 80,
		sponsor: ''
	};
	var options = $.extend(defaults, options);
	function bubbleSort( ary ) {
		for (var i=ary.length - 2; i>=0;  i--) {
			for (var j=0; j<=i; j++) {
				var x = parseInt(ary[j + 1], ary[j + 1]);
				var y = parseInt(ary[j], ary[j]);
				if (x < y) {
					var tmp = ary[j]; ary[j] = ary[j + 1];
					ary[j + 1] = tmp;
				}
			}
		}
		return ary;
	};
	var parent = $(this);
	return $('.bd', this).each(function(i) {
		var obj = this;
		var getType = { name: 'wishlist', value: '' };
		if ( options.wishlist != '' ) {
			getType = { name: 'wishlist', value: options.wishlist }
		} else if ( options.listingIDs != '' ) {
			getType = { name: 'listingIDs', value: options.listingIDs }
		} else if ( options.keywords != '' ) {
			getType = { name: 'keywords', value: options.keywords }
		} else {
			return;
		}
		var strURL = 'http://marketplace.hgtv.com/cms/managexmlfiles.aspx?xmlFile=SCRHGTV~FeatureProducts~' + getType.name + '=' + getType.value + ';w=' + options.width + ';h=' + options.height + '&json=true&callback=?';
		var sponsor = options.sponsor;
		$.ajax({
			url: strURL,
			dataType: 'jsonp',
			success: function(data) {
				$(obj)
					.json2HTML([{
					nodeName: 'ul',
					id: 'json-marketplace-widget',
					addClass: 'jcarousel-skin-tango clrfix'
				}]);
				var list = [];
				$.each(data.products, function(i, item) {
//					var dummyImg = $('<img>');
//					$(dummyImg).attr('src', item.photo).appendTo(document.body);
//					var tw = $(dummyImg).attr('width');
//					$(dummyImg).load(function() {
//						var tw = parseInt($(this).attr('width'), 10) < 91 ? parseInt($(this).attr('width'), 10) : 91;
//						var th = parseInt($(this).attr('height'), 10) < 91 ? parseInt($(this).attr('height'), 10) : 91;




					var li = {
						nodeName: 'li',
						append: [{
							nodeName: 'img',
							attr: {
								src: item.photo,
								alt: item.name,
								width: '91',
								height: '91'
							}
						},{
							nodeName: 'p',
							append: [{
								nodeName: 'a',
								html: item.name,
								attr: { href: item.url }
							}]
						}]
					};
					list.push(li);
					if ( data.products.length > 3 ) {
						if ( (i + 1) % 3 == 0 ) {
							$('#json-marketplace-widget').json2HTML([ { nodeName: 'li', append: [{ nodeName: 'ul', append: list }] } ]);
							list = [];
						}
					} else if ( data.products.length > 0 ) {
						$('#json-marketplace-widget').json2HTML([ { nodeName: 'li', append: [{ nodeName: 'ul', append: list }] } ]);
					} else {
						$('#json-marketplace-widget').json2HTML([ { nodeName: 'li', append: [{ nodeName: 'ul', append: [{ nodeName: 'li', html: 'No products available.' }] }] } ]);
					}
					
					
//					});
//					$(dummyImg).remove();

				});
				$.each($('ul', '#json-marketplace-widget'), function(i) { $(this).css('zoom', 1); });
				/* get the height of the tallest li */
				var h = [];
				$.each($('li', obj), function() { h.push(parseInt($(this).height(), 10)); });
				h = h.sort(function(a,b){return b - a})[0];
				/* make our max 160 for good old IE */
				h = h < 160 ? h : 160;
				/* let's make all the LI elements the same height */
				$.each($('li', obj), function() { $(this).height((h + 8) + 'px'); });
				$(parent).dpl('carousel', { pagelink: 'image' });
				/* add stuff for tracking [&topic=SEO_SPONOR] */
				$.each($('a', parent), function() {
					var href = $(this).attr('href');
					$(this).attr('href', href + '&topic=' + sponsor);
				});
				/*
												TEMP SOLUTION
					for some darn reason, IE creates an extra empty LI at the beggining
					so I'm going to delete any empty LI elements that are ONLY DIRECT child
					elements of ul#json-marketplace-widget.
				*/
				if ( document.all ) { $.each($('li', parent), function() { if ( $(this).html() == '' ) { $(this).remove(); } }); }
			}
		});
	});
};

$.fn.marketplaceWidget2 = function(options) {
	var defaults = {
		wislist: '',
		listingIDs: '',
		keywords: '',
		width: 100,
		height: 80,
		sponsor: '',
		itemsPer: 3
	};
	var options = $.extend(defaults, options);
	function bubbleSort( ary ) {
		for (var i=ary.length - 2; i>=0;  i--) {
			for (var j=0; j<=i; j++) {
				var x = parseInt(ary[j + 1], ary[j + 1]);
				var y = parseInt(ary[j], ary[j]);
				if (x < y) {
					var tmp = ary[j]; ary[j] = ary[j + 1];
					ary[j + 1] = tmp;
				}
			}
		}
		return ary;
	};
	var parent = $(this);
	return $('.bd', this).each(function(i) {
		var obj = this;
		var getType = { name: 'wishlist', value: '' };
		if ( options.wishlist != '' ) {
			getType = { name: 'wishlist', value: options.wishlist }
		} else if ( options.listingIDs != '' ) {
			getType = { name: 'listingIDs', value: options.listingIDs }
		} else if ( options.keywords != '' ) {
			getType = { name: 'keywords', value: options.keywords }
		} else {
			return;
		}
		var strURL = 'http://marketplace.hgtv.com/cms/managexmlfiles.aspx?xmlFile=SCRHGTV~FeatureProducts~' + getType.name + '=' + getType.value + ';w=' + options.width + ';h=' + options.height + '&json=true&callback=?';
		var sponsor = options.sponsor;
		$.ajax({
			url: strURL,
			dataType: 'jsonp',
			success: function(data) {
				$(obj)
					.json2HTML([{
					nodeName: 'ul',
					id: 'json-marketplace-widget',
					addClass: 'jcarousel-skin-tango clrfix'
				}]);
				var list = [];
				$.each(data.products, function(i, item) {
					var li = {
						nodeName: 'li',
						append: [{
							nodeName: 'img',
							attr: {
								src: item.photo,
								alt: item.name,
								width: '91',
								height: '91'
							}
						},{
							nodeName: 'p',
							append: [{
								nodeName: 'a',
								html: item.name,
								attr: { href: item.url }
							}]
						}]
					};
					list.push(li);
					if ( data.products.length > options.itemsPer ) {
						if ( (i + 1) % options.itemsPer == 0 ) {
							$('#json-marketplace-widget').json2HTML([ { nodeName: 'li', append: [{ nodeName: 'ul', append: list }] } ]);
							list = [];
						}
					} else if ( data.products.length > 0 ) {
						$('#json-marketplace-widget').json2HTML([ { nodeName: 'li', append: [{ nodeName: 'ul', append: list }] } ]);
					} else {
						$('#json-marketplace-widget').json2HTML([ { nodeName: 'li', append: [{ nodeName: 'ul', append: [{ nodeName: 'li', html: 'No products available.' }] }] } ]);
					}
				});
				$.each($('ul', '#json-marketplace-widget'), function(i) { $(this).css('zoom', 1); });
				/* get the height of the tallest li */
				var h = [];
				$.each($('li', obj), function() { h.push(parseInt($(this).height(), 10)); });
				h = h.sort(function(a,b){return b - a})[0];
				/* make our max 160 for good old IE */
				h = h < 160 ? h : 160;
				/* let's make all the LI elements the same height */
				$.each($('li', obj), function() { $(this).height((h + 8) + 'px'); });
				$(parent).dpl('carousel', { pagelink: 'image' });
				/* add stuff for tracking [&topic=SEO_SPONOR] */
				$.each($('a', parent), function() {
					var href = $(this).attr('href');
					$(this).attr('href', href + '&topic=' + sponsor);
				});
				/*
												TEMP SOLUTION
					for some darn reason, IE creates an extra empty LI at the beggining
					so I'm going to delete any empty LI elements that are ONLY DIRECT child
					elements of ul#json-marketplace-widget.
				*/
				if ( document.all ) { $.each($('li', parent), function() { if ( $(this).html() == '' ) { $(this).remove(); } }); }
			}
		});
	});

};

/*
	jQuery plugin: json2HTML( obj )
	this method I created to try and
	dynamically create HTML from a json
	type structure.  Using json, you create, setup and append
	elements to whatever $( [MATCHED_ELEMENTS] )
	EXAMPLE:
		You always start with an array.
		var html = [];
		// var html = [{}]; inside the array are objects {}
		// These objects have properties that tell the plugin what to do.
		// you can think of these properties as you would with jQuery plugin options.
		nodeName - This is simply "createElement" - nodeName: 'div'
		append - Has to be an array - [] (with objects inside, yay!!) [{}] - this is what makes it possible to have mutliple versions of some element.
		html, css, attr, or any other jQuery method can be used in between nodeName AND append
			EXAMPLE STRUCTURE:
				// create an array with one div that has "Hello World" as it's innerHTML
				var html = [ { nodeName: 'div', html: 'Hello World' } ];
				$(document).json2HTML(html);
				// let's say you wanted 2 div as siblings
				var html = [
					{ nodeName: 'div', html: 'Hello World' },
					{ nodeName: 'div', html: 'Hello World, I am div #2...it's as simple as adding a comma and another set of curly brackets with nodeName: and html: properties!' }
				];
				$(document).json2HTML(html);
*/
$.fn.json2HTML = function( obj ) {
	var defaults = {};
	var options = $.extend(defaults, options);
	return this.each(function(i) {
		var previousElement = this;
		function json2HTML( obj ) {
			for ( var i=0; i<obj.length; i++ ) {
				for ( prop in obj[i] ) {
					switch ( prop ) {
						case 'eval': { eval(obj[i][prop]); break; }
						case 'nodeName': {
							var node = document.createElement(obj[i][prop]);
							break;
						}
						case 'append': {
							/*
								append here if the append: [property] is used
								since we will be executing this function again.
							*/
							$(previousElement).append(node);
							previousElement = node;
							json2HTML(obj[i][prop]);
							break;
						}
						case 'extend': {
							var props = obj[i][prop];
							for ( var x=0; x<props.length; x++ )
								for ( y in props[x] )
									$.data(node, y, props[x][y]);
							break;
						}
						case 'props': {
							var props = obj[i][prop];
							for ( var x=0; x<props.length; x++ )
								eval('node.' + props[x].split('=')[0] + ' = ' + props[x].split('=')[1] + ';');
							break;
						}
						case 'id': { $(node).attr('id', obj[i][prop]); break; }
						case 'if': { eval(obj[i][prop]); break; }
						case 'href': { $(node).attr('href', obj[i][prop]); break; }
						case 'return': { return eval(obj[i][prop]); break; }
						case 'addClass':
						case 'val':
						case 'text':
						case 'html':
						case 'attr':
						case 'css': {
								eval('$(node).' + prop + '(obj[i][prop]);');
							break;
						}
						/* default - click, mouseover, my_plugin */
						default: { eval('$(node).' + prop + '(' + obj[i][prop] + ');'); break; }
					}
				}
				/*
					this append will occur if the append: [property] is not used
					and all of the props have been gone through
				*/
				$(previousElement).append(node);
			}
			if ( node )
				previousElement = node.parentNode.parentNode;
		};
		json2HTML(obj);
	});
};


/* jQuery Ready plugin
 * version 0.5
 * Copyright (C) 2007 Bennett McElwee.
 * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.gnu.org/licenses/gpl.html) licenses.
 */

/*
	IMPLEMENTATION NOTES
	There may be race conditions. The most likely could occur if check() is
	called while a previous invocation of check() is still running. This could
	cause a callback to be called more than once, or not at all. Less likely is
	for elementReady() to be called concurrently with check() (with similar
	effects) or with itself (which could cause an interval to run forever).
	None of these are likely to occur. In fact I don't think they are possible
	at all except on IE. -- Bennett McElwee, August 2007
*/
(function($) {

// Poll every so often to check if the element is ready.
var INTERVAL_MS = 23;

/**
 * While a page is loading, call a given callback function as soon as a specific
 * element is loaded into the DOM, even before the full DOM has been loaded.
 * Executes the function within the context of the element. This means that when
 * the passed-in function is executed, the 'this' keyword points to the specific
 * DOM element.
 *
 * The function returns 'this', so you can chain multiple calls to
 * elementReady(). (Not that there's much benefit in doing that.)
 *
 * One argument is passed to the callback: a reference to the jQuery function.
 * You can name this argument $ and therefore use the $ alias even in
 * noConflict mode.
 *
 * If the element has not been found by the time the DOM is fully loaded, then
 * the function will not be called.
 *
 * @example
 * $.elementReady('powerpic', function(){
 *     this.src = 'powered-by-jquery.png';
 * });
 * @desc Change the source of a specific image as soon as it is loaded into the
 * DOM (before the whole DOM is loaded).
 *
 * @example
 * $.elementReady('header', function(){
 *     $(this).addClass('fancy');
 * });
 * @desc If you want to have the jQuery object instead of the regular DOM
 * element, use the $(this) function.
 *
 * @example
 * $.elementReady('first',  function(){ $(this).fancify(); })
 *  .elementReady('second', function(){ $(this).fancify(); });
 * @desc Chain multiple calls to $.elementReady().
 *
 * @example
 * jQuery.noConflict();
 * jQuery.elementReady('header', function($){
 *     $(this).addClass('fancy');
 * });
 * @desc Use the '$' alias within your callback, even in noConflict mode.
 *
 * @name   $.elementReady
 * @type   jQuery
 * @param  String   id  string ID of the element to wait for
 * @param  Function fn  function to call when the element is ready
 * @return jQuery
 * @cat    Plugins/Event
 * @author Bennett McElwee
 */
var interval = null;
var checklist = [];

$.elementReady = function(id, fn) {
	checklist.push({id: id, fn: fn});
	if (!interval) {
		interval = setInterval(check, INTERVAL_MS);
	}
	return this;
};

function check() {
	var docReady = $.isReady; // check doc ready first; thus ensure that check is made at least once _after_ doc is ready
	for (var i = checklist.length - 1; 0 <= i; --i) {
		var el = document.getElementById(checklist[i].id);
		if (el) {
			var fn = checklist[i].fn; // first remove from checklist, then call function
			checklist[i] = checklist[checklist.length - 1];
			checklist.pop();
			fn.apply(el, [$]);
		}
	}
	if (docReady) {
		clearInterval(interval);
		interval = null;
	}
};

})(jQuery);

/*
	PLUGIN
	$().sheild(addRemove, [options]);
	
	** Creates an iframe sheild to go behind any matched elements for jQuery([match]);
	params:
		addRemove - [string] : Either 'add' or 'remove'
	options:
		top		: 0 : [integer] - Offset top
		left	: 0 : [integer] - Offset left
		width	: 0 : [integer] - Offset width
		height	: 0 : [integer] - Offset height
	usages:
		jQuery('#myID').sheild('add'); // creates a sheild behind element with ID = myID
		jQuery('#myID').sheild('add', {
			top		: -10,
			left	: -10,
			width	: 10,
			height	: 10
		}); // creates a sheild that is 10px larger all around and is centered behind element width ID = myID
		jQuery('#myID').sheild('remove'); // removes sheild that is behind element width ID = myID
*/
(function($) {
	$.fn.sheild = function(addRemove, options) {
		switch (addRemove) {
			case 'add': {
				var defaults = {
					top		: 0,
					left	: 0,
					width	: 0,
					height	: 0
				};
				var options = $.extend(defaults, options);
				return this.each(function(i) {
					var coords = $.sniUtil.findPos(this);
					var iframe = this.parentNode.insertBefore(document.createElement('iframe'), this);
					$(iframe)
						.attr({
							scrolling		: 'no',
							height			: '0',
							frameborder		: '0',
							src				: 'about:blank'
						})
						.css({
							position		: 'absolute',
							top				: (coords[1] + options.top) + 'px',
							left			: (coords[0] + options.left) + 'px',
							width			: ($(this).width() + options.width) + 'px',
							height			: ($(this).height() + options.height) + 'px',
							border			: 'none',
							backgroundColor	: '#FFFFFF',
							zIndex			: ($(this).css('z-index') - 1)
						});
					this.sheild = iframe;
					this.hostObj = this.parentNode;
				});
				break;
			}
			case 'remove': {
				return this.each(function(i) {
					try {
						this.hostObj.removeChild(this.sheild);
					} catch(e) {}
				});
				break;
			}
		}
	};
})(jQuery);

/*
	PLUGIN
	$().dropShadow(add/remove, [ options ])
	
	** Displays a drop shadow underneath matched elements $([match])
	params:
		addRemove - [string] : Either 'add' or 'remove'
	options:
		color		: '#000',	[string] - Drop shadow color (can be hex or defined color name) example: '#000' OR 'black'
		distance	: 0,		[integer] - Drop shadow apparent distance
		degrees		: 45,		[integer] - Drop shadow angle
		layers		: 2,		[integer] - Drop shadow thickness
		opacity		: [20, 0]	[array] - Drop shadow start - end opacity
	usages:
		$('div.myDivClass').dropShadow('add', [ options ]);
		$('div.myDivClass').dropShadow('remove');
*/
(function($) {
	$.fn.dropShadow = function(addRemove, options) {
		if (!addRemove) return;
		switch (addRemove) {
			case 'add': {
				var defaults = {
					textOnly	: false,
					color		: '#000',
					distance	: 0,
					degrees		: 45,
					layers		: 2,
					opacity		: [20, 0]
				};
				var options = $.extend(defaults, options);
				
				return this.each(function() {
					if (!this) {
						return;
					}
					var w = this.offsetWidth;
					var h = this.offsetHeight;
					if ( !w ) return;
					if ( !h ) return;
					var bgImage = bgColor = '';
					bgImage = $(this).css('background-image');
					bgColor = $(this).css('background-color')
					zIndex = $(this).css('z-index')
					/* if the object we're attaching the shadow to seems to be transparent, we must make it white or the shadow will be seen */
					if ( bgColor == '' || bgColor == 'transparent' )
						if ( bgImage == '' || bgImage == 'none' ) this.style.backgroundColor = '#FFF';
					if ( options.opacity.length == 1 ) options.opacity.push(0);
					var ho = options.opacity.sort()[1];
					var lo = options.opacity.sort()[0];
					var o = ho;
					var oInc = parseInt((ho - lo) / options.layers);
					var xStep = Math.round( Math.sin( options.degrees * ( Math.PI / 180 ) ) );
					var yStep = Math.round( Math.cos( options.degrees * ( Math.PI / 180 ) ) );
					var xd = options.distance;
					var yd = options.distance;
					if ( options.degrees > 90 && options.degrees <= 180 ) yd = -yd;
					if ( options.degrees > 180 && options.degrees <= 270 ) {
						xd = -xd;
						yd = -yd;
					}
					if ( options.degrees > 270 && options.degrees <= 360 ) xd = -xd;
					this.shadowList = [];
					if ( options.textOnly ) {
						var children = $(this).children();
						var shadowObj = this;
						$.each(children, function(i) {
							var val = $(this).val() != '' ? $(this).val() : $(this).html();
							if ( val != '' ) {
								w = this.offsetWidth;
								var l = (this.offsetLeft + xd) - 1;
								var t = (this.offsetTop + yd) - 1;
								for ( var i=0; i<options.layers; i++ ) {
									l = l + xStep;
									t = t + yStep;
									bLyr = document.createElement(this.nodeName.toLowerCase());
									$(bLyr).css({
										position		: 'absolute',
										zIndex			: ( zIndex - options.layers ) + i,
										left			: l + xStep + 'px',
										top				: t + yStep + 'px',
										width			: w + 'px',
										//height			: h + 'px',
										color			: options.color,
										opacity			: o / 100
									}).html(val);
									$(this.parentNode).append(bLyr)
									o = o - oInc;
									shadowObj.shadowList.push(bLyr);
								}
								shadowObj._hostObj = this.parentNode;
								shadowObj._numShadows = options.layers;
							}
						});
					} else {
						var l = (this.offsetLeft + xd) - 1;
						var t = (this.offsetTop + yd) - 1;
						for ( var i=0; i<options.layers; i++ ) {
							l = l + xStep;
							t = t + yStep;
							bLyr = this.parentNode.insertBefore(document.createElement('div'), this);
							$(bLyr).css({
								position		: 'absolute',
								zIndex			: ( zIndex - options.layers ) + i,
								left			: l + xStep + 'px',
								top				: t + yStep + 'px',
								width			: w + 'px',
								height			: h + 'px',
								backgroundColor	: options.color,
								opacity			: o / 100
							});
							o = o - oInc;
							this.shadowList.push(bLyr);
						}
						this._hostObj = this.parentNode;
						this._numShadows = options.layers;
					}
				});
				break;
			}
			case 'remove': {
				return this.each(function() {
					for ( var i=0; i<this._numShadows; i++ )
						if ( this.shadowList[i] ) try { this._hostObj.removeChild(this.shadowList[i]); } catch(e) {}
				});
				break;
			}
		}
	};
})(jQuery);

(function($) {
	$.fn.skinnableSelect = function(options) {
		var ssHiddenStyles = document.body.appendChild(document.createElement('div'));
		ssHiddenStyles.innerHTML = '<style>.ssSneaky { overflow-x: hidden; overflow-x: hidden; overflow-y: scroll; height: 200px; } .ssOFX { overflow-x: hidden; }</style>';
		
		var defaults = {
			top						: 0,
			left					: 0,
			width					: 0,
			height					: 0,
			wrapClass				: '',
			wrapCSSBackground		: '',
			selectedIndexClass		: '',
			arrowClass				: '',
			arrowCSSBackground		: '',
			optionsHighlightClass	: '',
			openMethod				: function(container) { $(container).show(); },
			closeMethod				: function(container) { $(container).hide(); }
		};
		$.fn.skinnableSelect.openList = function(selectbox) {
			selectbox.openMethod.call(this, selectbox.optionsWrap);
			$(selectbox.optionsWrap).queue(function() {
				selectbox.hiddenText.focus();
				selectbox.ssIsOpen = true;		
//				$(this).sheild('add');
//				if ( textbox.as.options.useShadow ) {
//					$(this).dropShadow('add', {
//						color: textbox.as.options.shadowColor,
//						distance: textbox.as.options.shadowDistance,
//						degrees: textbox.as.options.shadowDegrees,
//						layers: textbox.as.options.shadowLayers,
//						opacity: textbox.as.options.shadowOpacity
//					});
//				}
				$(this).dequeue();
			});
		};
		$.fn.skinnableSelect.closeList = function(selectbox) {
			$(selectbox.optionsWrap).dequeue();
			selectbox.closeMethod.call(this, selectbox.optionsWrap);
			selectbox.ssIsOpen = false;
			if ( selectbox.blurTimeout ) {
				clearTimeout(selectbox.blurTimeout);
			}
		};
//		$.fn.skinnableSelect.handleChange = function(selectbox) {
//			alert(selectbox);
//		};
		$.fn.skinnableSelect.fillList = function(selectbox) {
			for ( var i=0; i<selectbox.length; i++ ) {
				selectbox.option = document.createElement('li');
				selectbox.option._value = selectbox.options[i].value;
				selectbox.option.selectbox = selectbox;
				selectbox.option.index = i;
				$(selectbox.option)
					.css({
						paddingLeft	: '2px',
						width		: '10000px'
					})
					.text(selectbox.options[i].text)
					.bind('click', function() {
						this.selectbox.selectedIndex = this.index;
						$(this.selectbox.selected).text($(this).text());
					});
				$(selectbox.optionsWrap).append(selectbox.option);
				/* set some default css for each option */
				if ( $(selectbox.option).css('background-color') == 'transparent' ) {
					$(selectbox.option).css('background-color', '#FFFFFF')
				}
				var optionBGColor = $(selectbox.option).css('background-color');
				$(selectbox.option)
					.bind('mouseover', function() {
						if ( options.optionsHighlightClass != '' ) {
							$(this).toggleClass(options.optionsHighlightClass);
						} else {
							$(this).css('background-color', '#CCCCCC');
						}
					})
					.bind('mouseout', function() {
						if ( options.optionsHighlightClass != '' ) {
							$(this).toggleClass(options.optionsHighlightClass);
						} else {
							$(this).css('background-color', optionBGColor);
						}
					});
			}
			if ( selectbox.length > 10 ) {
				/*
					I found that for some reason I could not set overflowY by itself.
					I could only set overflowX & overflowY OR overflow (they had to be the same)
					so I created a class called ssSneaky and it into the innerHTML of selectbox.wrap
					using style tags.
				*/
				$(selectbox.optionsWrap).addClass('ssSneaky');
			}
		};
		var options = $.extend(defaults, options);
		return this.each(function(i) {
			/* if it's not a select dropdown, return */
			if ( this.tagName.toLowerCase() != 'select' ) {
				return;
			}
			$(this).css('visibility', 'hidden');
			
			this.ssIsOpen = false;
			this.openMethod = options.openMethod;
			this.closeMethod = options.closeMethod;
			var self = this;
			//$(this).bind('propertychange', function() { $.fn.skinnableSelect.handleChange(self); });
			
			var coords = $.sniUtil.findPos(this);
			var top = coords[1];
			var left = coords[0];
			var width = options.width != 0 ? options.width : $(this).width();
			var height = options.height != 0 ? options.height : $(this).height() + 2;

			if ( options.width != 0 ) { if ( options.width < $(this).width() ) { width = $(this).width() } else { $(this).css('margin-right', (options.width - $(this).width()) + 'px'); } }
			if ( options.height != 0 ) { if ( options.height < $(this).height() ) { height = $(this).height() + 2; } else { $(this).css('margin-bottom', (options.height - $(this).height()) + 'px'); } }
			
			/* create the wrap/container and place it on top of the select box */
			var wrapCSSBackground = options.wrapCSSBackground != '' ? options.wrapCSSBackground : 'url(http://common.scrippsnetworks.com/common/js/sni_lib_images/default_wrap.jpg) no-repeat left center';
			this.wrap = document.createElement('div');
			$(this.wrap)
				.css({
					position		: 'absolute',
					top				: top + options.top + 'px',
					left			: left + options.left + 'px',
					width			: width + 'px',
					height			: height + 'px',
					cursor			: 'default',
					background		: wrapCSSBackground
				})
				.addClass(options.wrapClass)
				.html('<style>.ssSneaky { overflow-x: hidden; overflow-x: hidden; overflow-y: scroll; height: 200px; }</style>');
			$(document.body).append(this.wrap);
			
			this.hiddenText = document.body.appendChild(document.createElement('input'));
			this.hiddenText.selectbox = this;
			$(this.hiddenText)
				.css({
					position	: 'absolute',
					left		: '-2000px'
				})
				.bind('blur', function(e) {
					selectbox = this.selectbox;
					selectbox.blurTimeout = setTimeout(function() { $.fn.skinnableSelect.closeList(selectbox); }, 150);
				});
			/* create the visible selectedIndex field */
			this.clip = document.createElement('div');
			$(this.clip).css({ width: width + 'px', height: height + 'px' }).addClass('ssOFX');
			$(this.wrap).append(this.clip);
			
			this.selected = document.createElement('div');
			this.selected.selectbox = this;
			$(this.selected)
				.css({
					position		: 'relative',
					top				: '0px',
					width			: '10000px',
					height			: height + 'px'
				})
				.addClass(options.selectedIndexClass)
				.text(this.options[this.selectedIndex].text)
				.bind('click', function() {
					if ( !this.selectbox.ssIsOpen ) { $.fn.skinnableSelect.openList(this.selectbox); } else { $.fn.skinnableSelect.closeList(this.selectbox); }
				});
			$(this.clip).append(this.selected);

			var paddingLeft = parseInt($(this.selected).css('padding-left'));
			var paddingRight = parseInt($(this.selected).css('padding-right'));
			if ( (paddingLeft + paddingRight) == 0 ) {
				$(this.selected).css('padding-left', '2px');
			}
			if ( parseInt($(this.selected).css('padding-top')) == 0 ) {
				$(this.selected).css('padding-top', '2px');
			}
			/* create the arrow control */
			this.arrow = document.createElement('div');
			this.arrow.selectbox = this;
			$(this.arrow)
				.css({
					position		: 'absolute',
					top				: '0px',
					right			: '0px',
					//width			: '17px',
					height			: height + 'px',
					background		: options.arrowCSSBackground != '' ? options.arrowCSSBackground : 'url(http://common.scrippsnetworks.com/common/js/sni_lib_images/default_arrow.jpg) no-repeat center center'
				})
				.addClass(options.arrowClass)
				.bind('click', function() {
					if ( !this.selectbox.ssIsOpen ) {
						$.fn.skinnableSelect.openList(this.selectbox);
					} else {
						$.fn.skinnableSelect.closeList(this.selectbox);
					}
				});
			$(this.wrap).append(this.arrow);
			if ( parseInt($(this.arrow).css('width')) == 0 ) {
				$(this.arrow).css('width', '17px;');
			}
			/* create the list of options using the actual options from this select box */
			this.optionsWrap = document.createElement('ul');
			$(this.optionsWrap).css({
				position	: 'absolute',
				zIndex		: $.sniUtil.getHighestZIndex() + 1,
				top			: height + 'px',
				display		: 'none'
			}).addClass('ssOFX');
			$(this.wrap).append(this.optionsWrap);
			if ( $(this.optionsWrap).css('width') == '0px' || $(this.optionsWrap).css('width') == 'auto' ) {
				$(this.optionsWrap).css('width', '100%');
			}
			if ( $(this.optionsWrap).css('border') == '' || $(this.optionsWrap).css('border') == undefined ) {
				$(this.optionsWrap).css({
					border: '1px solid #000000',
					width: (width - 2) + 'px'
				});
			}
			$.fn.skinnableSelect.fillList(this);
		});
	};
})(jQuery);

(function($) {
	$.fn.skinnableRadio = function(options) {
		$.fn.skinnableRadio.unselectAll = function(el) {
			var x = jQuery.data(document, el.name);
			for ( var i=0; i<x.length; i++ ) { $(x[i]).hide(); el.checked = false; }
		};
		var defaults = {
			top						: 0,
			left					: 0,
			width					: 0,
			height					: 0,
			wrapBG					: '',
			dotBG					: '',
			forAttribute			: ''
		};
		var options = $.extend(defaults, options);
		return this.each(function(i, el) {
			// create a new array for each radio group
			if ( el.name != jQuery.data(document, 'rgName') ) { jQuery.data(document, el.name, new Array()); }
			jQuery.data(document, 'rgName', el.name);
			
			if ( this.tagName.toLowerCase() != 'input' ) return;
			if ( this.type.toLowerCase() != 'radio' ) return;
			$(this).css('visibility', 'hidden');
			this.isOpen = false;
			this.openMethod = options.openMethod;
			this.closeMethod = options.closeMethod;
			var self = this;

			var width = options.width != 0 ? options.width : $(this).get(0).offsetWidth;
			var height = options.height != 0 ? options.height : $(this).get(0).offsetHeight;
			
			if ( options.width != 0 ) { if ( options.width < $(this).width() ) { width = $(this).width() } else { $(this).css('margin-right', (options.width - $(this).width()) + 'px'); } }
			if ( options.height != 0 ) {
				if ( options.height < $(this).height() ) {
					height = $(this).height() + 2;
				} else {
					$(this).css('margin-top', ( (options.height - $(this).height()) / 2) + 'px');
					$(this).css('margin-bottom', ( (options.height - $(this).height()) / 2) + 'px');
				}
			}
				
			var coords = $.sniUtil.findPos(this);
			var top = coords[1];
			var left = coords[0];
			
			/* create the wrap/container and place it on top of the radio */
			this.wrap = document.createElement('div');
			$(this.wrap)
				.css({
					position		: 'absolute',
					top				: top + options.top + 'px',
					left			: left + options.left + 'px',
					width			: width + 'px',
					height			: height + 'px',
					cursor			: 'default',
					background		: options.wrapBG != '' ? options.wrapBG : 'url(http://common.scrippsnetworks.com/common/js/sni_lib_images/default_wrap.gif) no-repeat center center'
				})
				.addClass(options.wrapClass)
				.bind('click', function() {
					$.fn.skinnableRadio.unselectAll(el);
					$(self.dot).toggle();
					self.checked = true;
				});
			$(document.body).append(this.wrap);
			
			this.dot = document.createElement('div');
			$(this.dot)
				.css({
					position		: 'absolute',
					top				: '0px',
					left			: '0px',
					width			: width + 'px',
					height			: height + 'px',
					background		: options.dotBG != '' ? options.dotBG : 'url(http://common.scrippsnetworks.com/common/js/sni_lib_images/default_dot.gif) no-repeat center center'
				})
				.addClass(options.checkedClass)
				.hide();
			$(this.wrap).append(this.dot);
			
			// see if there is an id for this radio element
			var id = $(this).attr('id');
			if ( id ) {
				// see if there is an element with the "for" attribute refering to this ID
				$('[for=' + id + ']').bind('click', function() {
					$.fn.skinnableRadio.unselectAll(el);
					$(self.dot).toggle();
					self.checked = true;
				});
				if ( options.forAttribute ) {
					$('[' + options.forAttribute + '=' + id + ']').each(function() {
						$(this).css('cursor', 'default').bind('click', function() {
							$.fn.skinnableRadio.unselectAll(el);
							$(self.dot).toggle();
							self.checked = true;
						});
					});
				}
			}

			// push each radio input into an array of that radios group
			var x = jQuery.data(document, el.name);
			x.push(this.dot);
			jQuery.data(document, el.name, x);
		});
	};
})(jQuery);

/*
	PLUGIN
	$().imageFrame({options});
	
	** Creates a nice frame around all matched elements using their direct parent elements and themselves.
	options:
		outerBorder		: 'none',	[string] - CSS notated border rule
		innerBorder		: 'none',	[string] - CSS notated border rule
		padding			: [3],		[array] - Array to determine padding (note: acts like CSS notated padding in array form)
		background		: 'none'	[string] - CSS notated background
	usage:
		$('img.myImgClass').imageFrame([ options ]);
*/
(function($) {
	$.fn.imageFrame = function(options) {
		var defaults = {
			outerBorder		: '1px solid #000',
			innerBorder		: '1px solid #000',
			padding			: [3],
			background		: 'none',
			callback		: function() {}
		};
		var options = $.extend(defaults, options);
		var pTop = pLeft = pRight = pBottom = 0;
		switch ( options.padding.length ) {
			case 1: {
				pTop = pLeft = pRight = pBottom = options.padding[0];
				break;
			}
			case 2: {
				pTop = pBottom = options.padding[0];
				pLeft = pRight = options.padding[1];
				break;
			}
			case 3: {
				pTop = options.padding[0];
				pLeft = pRight = options.padding[1];
				pBottom = options.padding[2];
				break;
			}
			case 4: {
				pTop = options.padding[0];
				pRight = options.padding[1];
				pBottom = options.padding[2];
				pLeft = options.padding[3];
				break;
			}
		}
		return this.each(function(i) {
			var w = $(this).width();
			var h = $(this).height();
			$(this).css({
				border			: options.innerBorder,
				marginTop		: pTop + 'px',
				marginLeft		: pLeft + 'px'
			});
			var ibSize = parseInt($(this).css('borderWidth'));
			$(this).parent().css({
				display		: 'block',
				border		: options.outerBorder,
				background	: options.background,
				width		: document.all ? (w + ((pLeft + pRight) + (2 * (ibSize )))) + 2 : (w + ((pLeft + pRight) + (2 * (ibSize )))) + 'px',
				height		: document.all ? (h + ((pTop + pBottom) + (2 * (ibSize )))) + 2 : (h + ((pTop + pBottom) + (2 * (ibSize )))) + 'px'
			});
			options.callback.call(this, this);
		});
	};
})(jQuery);

/*
	PLUGIN
	$().imageFrame2({options});
	
	** Creates a nice frame around all matched elements using their direct parent elements and themselves.
	*** This plugin should only really be used when there's no doctype on the page ***
	NOTE: This version fixes the click for images in IE
	options:
		outerBorder		: 'none',	[string] - CSS notated border rule
		innerBorder		: 'none',	[string] - CSS notated border rule
		padding			: [3],		[array] - Array to determine padding (note: acts like CSS notated padding in array form)
		background		: 'none'	[string] - CSS notated background
		callback		: null		[function] - Any callback function you wish to execute
	usage:
		$('img.myImgClass').imageFrame2([ options ]);
*/
(function($) {
	$.fn.imageFrame2 = function(options) {
		var defaults = {
			outerBorder		: '1px solid #000',
			innerBorder		: '1px solid #000',
			padding			: [3],
			background		: 'none',
			callback		: null
		};
		var options = $.extend(defaults, options);
		var pTop = pLeft = pRight = pBottom = 0;
		switch ( options.padding.length ) {
			case 1: { pTop = pLeft = pRight = pBottom = options.padding[0]; break; }
			case 2: { pTop = pBottom = options.padding[0]; pLeft = pRight = options.padding[1]; break; }
			case 3: { pTop = options.padding[0]; pLeft = pRight = options.padding[1]; pBottom = options.padding[2]; break; }
			case 4: { pTop = options.padding[0]; pRight = options.padding[1]; pBottom = options.padding[2]; pLeft = options.padding[3]; break; }
		}
		return this.each(function(i) {
			var self = this;
			var isInsideAnchor = false;
			var aHref = '';
			var aTarget, aClick = null;
			var aHasHref = aHasJS = false;
			while (self = self.parentNode) {
				if ( self.nodeType == 1 )
					if ( self.nodeName.toLowerCase() == 'a' ) {
						/* looks like imageFrame is wrapped inside an anchor */
						isInsideAnchor = true;
						/*
							while we're here, let's get the anchors href value
							and let's see if it has a target as well as an onclick
							* these items will get passed to the image itself for good old IE
						*/
						aHref = $(self).attr('href');
						if ( aHref.toLowerCase().indexOf('javascript:') != -1 ) {
							aHref = aHref.substring(aHref.toLowerCase().indexOf('javascript:'), aHref.length);
							aHasJS = true;
						} else
							aHasHref = true;
						aTarget = $(self).attr('target');
						aClick = $(self).attr('onclick');
					}
			}
			$(this).css({
				border		: options.innerBorder,
				marginTop	: pTop + 'px',
				marginLeft	: pLeft + 'px'
			});
			var ibSize = parseInt($(this).css('borderWidth'));
			var ieOffset = 0;
			if ( document.all ) {
				ieOffset = 5;
				if ( isInsideAnchor ) {
					$('*', this.parentNode).css('cursor', 'pointer');
				}
				/*
					here IF we have determined that the imageFrame is
					wrapped inside anchor, let's give the image an
					onclick value that is equal to that anchor for IE
				*/
				if ( isInsideAnchor ) {
					$(this).click(function() {
						if ( aTarget != '' ) {
							switch ( aTarget ) {
								case '_blank': { window.open(aHref); break; }
								default: { window.location = aHref; break; }
							}
						}
						if ( aHasJS )
							eval(aHref);
					});
				}
			}
			/* let's create the div to wrap around the image */
			var cursor = 'default';
			if ( isInsideAnchor )
				cursor = 'pointer';
			var div = document.createElement('div');
			$(div)
				.css({
					cursor		: cursor,
					border		: options.outerBorder,
					background	: options.background,
					width		: ($(this).width() + ((pLeft + pRight) + (2 * (ibSize )))) + ieOffset + 'px',
					height		: ($(this).height() + ((pTop + pBottom) + (2 * (ibSize )))) + ieOffset + 'px'
				});
			$(this).parent().prepend(div);
			$(div).append(this);
			if ( options.callback != null )
				if ( $.isFunction(options.callback) )
					options.callback.call(this, this);
		});
	};
})(jQuery);

/*
	PLUGIN
	jQuery().tabbedPUP(options)

	** Turns cild nodes of matched elements jQuery([match]) and creates a tabbable PUP
	options:
		tabTagName				: 'li',			[string] - The type of element that is tabbable
		tabPupIDAttribute		: 'id',			[string] - The name of the attribute used to hold the PUP ID's
		highlightClassName		: 'highlight',	[string] - Highlight class name for tabbable list
		selectedClassName		: 'selected',	[string] - Selected class name for tabbable list
		pupAppDivID				: 'swfWrap',	[string] - ID for PUP container
		pupSiteID				: 'hgtv',		[string] - Site ID for PUP
		pupLCDivName			: 'ad_300_250',	[string] - ID for LC banner container
		pupInitNum				: -1,			[integer] - Initial PUP channel to play
		pupConfigXML			: '',			[string] - PUP configuration XML
		pupServer				: '',			[string] - PUP server ID
		pupShowList				: true,			[boolean] - Show PUP list?
		pupHasSearch			: false,		[boolean] - Use PUP internal search?
		pupAutoPlay				: false,		[boolean] - Set PUP to auto play?
		pupForceList			: false,		[boolean] - Force a list for PUP?
		pupSearchWithin			: true,			[boolean] - Search within PUP only?
		pupShowList				: false,		[boolean] - Show PUP list?
		pupVideoID				: null,			[integer] - PUP video ID
		pupOnForceChannel		: null,			[function] - callback function for on force channel
		pupOnPlaylistComplete	: null			[function] - callback function when playlist is complete
	usage:
		$('ul#myUL').tabbedPUP([ options ]);
	notes:
		This pup list creator can be used for any elements inside any container.  It was originally meant for a set
		of LI's inside a UL or OL but can be for example a set of anchors within a div.
		It defaults to an LI list so to use with anchors, you need to use the tabTagName option.
		EXAMPLE: $('div#myDiv').tabbedPUP({ tabTagName: 'a' });
		
		The defaults attribute to hold the pup channels is 'id' but can be anything using the tabPupIDAttribute option.
		EXAMPLE $('div#myDiv').tabbedPUP({ tabTagName: 'a', tabPupIDAttribute: 'pupchannel' });
			- for the above example, your HTML may be structured like so:
				<div id="myDiv">
					...
					<a pupchannel="1234" href="javascript: void(0);">Video 1</a>
					<a pupchannel="5678" href="javascript: void(0);">Video 2</a>
					<a pupchannel="9012" href="javascript: void(0);">Video 3</a>
					...
				</div>
*/
(function($) {
	$.fn.tabbedPUP = function(options) {
		var plCreator = new jQuery.tabbedPUPCreator(options);
		var oScript = document.createElement('script');
		oScript.type = 'text/javascript';
		oScript.src = 'http://common.scrippsnetworks.com/common/pup/pup.js';
		oScript.language = 'javascript';
		if ( document.getElementsByTagName('head')[0] ) {
			document.getElementsByTagName('head')[0].appendChild(oScript);
		} else {
			document.body.appendChild(oScript);
		}
		oScript._this = this;
		oScript.onload = function() {
			plCreator.scriptReady(this._this);
		}
		oScript.onreadystatechange = function() {
			if ( oScript.readyState == 'loaded' || oScript.readyState == 'complete' ) {
				plCreator.scriptReady(this._this);
			}
		};
	};
})(jQuery);

jQuery.tabbedPUPCreator = function(options) {
	var defaults = {
		tabTagName				: 'li',
		tabPupIDAttribute		: 'id',
		highlightClassName		: 'highlight',
		selectedClassName		: 'selected',
		disabledClassName		: 'disabled',
		toggleImg				: 'toggle',
		pupAppDivID				: 'swfWrap',
		pupSiteID				: 'hgtv',
		pupLCDivName			: 'ad_300_250',
		clickCallback			: null,
		useVideoIDChannelID		: -1,
		pupSwitchOptions		: null,
		pupInitNum				: -1,
		pupConfigXML			: '',
		pupServer				: '',
		pupShowList				: false,
		pupHasSearch			: false,
		pupAutoPlay				: false,
		pupForceList			: false,
		pupSearchWithin			: false,
		pupVideoID				: null,
		pupOnForceChannel		: null,
		pupOnPlaylistComplete	: null
	};
	this.options = jQuery.extend(defaults, options);
};

jQuery.extend(jQuery.tabbedPUPCreator, {
	prototype: {
		scriptReady: function(obj) {
			var tabbed_pup = this;
			var listContainers = [];
			var initNumUsed = false;
			return obj.each(function(i) {
				listContainers.push(this);
				/* get options.pupInitNum if it's not supplied then get the first LI's ID and use that */
				var usingVideoID = false;
				var all = jQuery(this).get(0).getElementsByTagName(tabbed_pup.options.tabTagName.toLowerCase());
				var pupIDAttribute = tabbed_pup.options.tabPupIDAttribute.toLowerCase();
				if ( !initNumUsed ) {
					var initialNum = 0;
					if ( tabbed_pup.options.pupInitNum == -1 ) {
						var num = parseInt(jQuery(all[0]).attr(pupIDAttribute), 10);
						if ( !isNaN(num) ) {
							initialNum = parseInt(jQuery(all[0]).attr(pupIDAttribute), 10);
						}
					} else
						initialNum = tabbed_pup.options.pupInitNum;
					if ( tabbed_pup.options.useVideoIDChannelID != -1 ) {
						usingVideoID = true;
						initialNum = tabbed_pup.options.useVideoIDChannelID;
					}
					//if ( initialNum == 0 )
					//	return;
					tabbed_pup.pupObj = new sniPUP({
						appDivID			: tabbed_pup.options.pupAppDivID,
						lcDivID				: tabbed_pup.options.pupLCDivName,
						channelID			: initialNum,
						siteID				: tabbed_pup.options.pupSiteID,
						showList			: tabbed_pup.options.pupShowList,
						autoPlay			: initialNum != 0 ? tabbed_pup.options.pupAutoPlay : false,
						hasSearch			: tabbed_pup.options.pupHasSearch,
						configXML			: tabbed_pup.options.pupConfigXML,
						server				: tabbed_pup.options.pupServer,
						forceList			: tabbed_pup.options.pupForceList,
						searchWithin		: tabbed_pup.options.pupSearchWithin,
						showList			: tabbed_pup.options.pupShowList,
						videoID				: tabbed_pup.options.pupVideoID,
						onForceChannel		: tabbed_pup.options.pupOnForceChannel,
						onPlaylistComplete	: tabbed_pup.options.pupOnPlaylistComplete
					});
					initNumUsed = true;
				}
				/* setup handles for the LI's */
				for ( var i=0; i<all.length; i++ ) {
					var child = all[i];
					var _initNum = parseInt(jQuery(child).attr(pupIDAttribute), 10);
					if ( _initNum == initialNum )
						if (jQuery(child).attr('class').indexOf(tabbed_pup.options.disabledClassName) == -1 )
							jQuery(child).addClass(tabbed_pup.options.selectedClassName);
					if ( tabbed_pup.options.tabTagName == 'img' ) {
						child.img1 = jQuery(child).attr('src');
						child.img2 = jQuery(child).attr(tabbed_pup.options.toggleImg);
						if ( _initNum == initialNum )
							jQuery(child).attr('src', jQuery(child).attr(tabbed_pup.options.toggleImg));
					}
					jQuery(child).bind('mouseover', function() {
						if ( tabbed_pup.options.tabTagName != 'img' )
							if (jQuery(this).attr('class').indexOf(tabbed_pup.options.disabledClassName) == -1 )
								if ( jQuery(this).attr('class').indexOf(tabbed_pup.options.selectedClassName) == -1 )
									jQuery(this).toggleClass(tabbed_pup.options.highlightClassName);
					}).bind('mouseout', function() {
						if ( tabbed_pup.options.tabTagName != 'img' )
							if ( jQuery(this).attr('class').indexOf(tabbed_pup.options.disabledClassName) == -1 )
								if ( jQuery(this).attr('class').indexOf(tabbed_pup.options.selectedClassName) == -1 )
									jQuery(this).toggleClass(tabbed_pup.options.highlightClassName);
					}).bind('click', function() {
						if ( jQuery(this).attr('class') != tabbed_pup.options.disabledClassName ) {
							if ( tabbed_pup.options.tabTagName != 'img' ) {
								for ( var i=0; i<listContainers.length; i++ ) {
									var lc = listContainers[i];
									for ( var j=0; j<lc.childNodes.length; j++ )
										if ( lc.childNodes[j].nodeType == 1 )
											if ( lc.childNodes[j].tagName.toLowerCase() == tabbed_pup.options.tabTagName.toLowerCase() )
												jQuery(lc.childNodes[j]).removeClass(tabbed_pup.options.selectedClassName).removeClass(tabbed_pup.options.highlightClassName);
								}
								jQuery(this).addClass(tabbed_pup.options.selectedClassName);
							} else {
								for ( var i=0; i<listContainers.length; i++ ) {
									var lc = listContainers[i];
									for ( var j=0; j<lc.childNodes.length; j++ )
										jQuery(lc.childNodes[j]).attr('src', lc.childNodes[j].img1);
								}
								jQuery(this).attr('src', this.img2);
							}
							var channelID = jQuery(this).attr(pupIDAttribute);
							if ( isNaN(channelID) )
								return;
							tabbed_pup.currentNode = this;
							if ( usingVideoID )
								tabbed_pup.pupObj.videoID = channelID;
							else
								tabbed_pup.pupObj.channelID = channelID;
							if ( tabbed_pup.options.pupSwitchOptions != null )
								for ( option in tabbed_pup.options.pupSwitchOptions )
									eval('tabbed_pup.pupObj.' + option + ' = ' + tabbed_pup.options.pupSwitchOptions[option]);
							tabbed_pup.pupObj.write();
							if ( tabbed_pup.options.clickCallback != null )
								tabbed_pup.options.clickCallback.call(this, tabbed_pup);
							return false;
						}
					});
				}
			});
		}
	}
});

/*
	PLUGIN
	$().printContent({options});
	
	** Prints the content of [containers] via any matched elements inside $([match])
	options:
		cssFile		: '',	[string] - The fully qualified path for a css file to be used with print sheet
		containers	: []	[array] - A list of containers who's innerHTML is to be printed.
	usage:
		$('a#btnPrint').printContent({ 'div#printArea' });
		
	notes:
		The CSS File is currently only supported by XHTML 1.0 Transitional//EN mime types
		Containers array list item can be string (with jQuery style selector) or jQuery matched notation.
		EXAMPLE:
			The following will print the contents of:
				a DIV (with ID = myID),
				all spans (with className = myClass),
				all anchors
				and some plain text
			containers: ['div#myID', 'span.myClass', $('a'), 'Don\'t forget to print me too!']
*/
(function($) {
	$.fn.printContent = function(options) {
		var defaults = {
			cssFile		: '',
			containers	: []
		};
		if ( typeof options != 'string' ) {
			var options = $.extend(defaults, options);
			var cssFiles = options.cssFile;
			var containers = options.containers;
			/* exit if there are no containers to print */
			if ( options.containers.length == 0 )
				return;
		} else
			containers = options;
		return this.each(function(i) {
			$(this).bind('click', function() {
				if ( !$('#printIFrame').get(0) ) {
					var f = document.createElement('iframe');
					$(f)
						.attr({
							src			: 'about:blank',
							id			: 'printIFrame',
							name		: 'printIFrame',
							frameborder	: '0',
							scrolling	: 'no'
						})
						.css({
							position	: 'absolute',
							width		: '1px',
							height		: '1px',
							top			: '-100px',
							visibility	: 'visible'
						})
						.bind('load', function() {
							if (self.frames['printIFrame'].name != 'printIFrame') {
								// must do a self check on the name to make sure it exists!!!
								self.frames['printIFrame'].name = 'printIFrame';
							}
						});
					$(document.body).append(f);
				}
				if ( $(f).get(0) ) {
					var strHTML = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
					strHTML += '<html xmlns="http://www.w3.org/1999/xhtml">';
					if ( typeof options != 'string' )
						strHTML += '<link rel="stylesheet" type="text/css" href="' + cssFiles + '" />';
					strHTML += '<body>';
					var c = 0;
					if ( typeof containers != 'string' ) {
						for ( var i=0; i<containers.length; i++ ) {
							if ( $(containers[i]).html() != null ) {
								$.each($(containers[i]), function() {
									if ( $(this).html() == '') {
										if ( this.tagName.toLowerCase() == 'br' ) {
											strHTML += '<br />';
											c++;
										}
									} else {
										strHTML += $(this).html();
										c++;
									}
								});
							} else {
								if ( containers[i] == '\n' ) {
									strHTML += '<br />';
									c++;
								} else {
									strHTML += containers[i];
									c++
								}
							}
						}
					} else {
						strHTML += $(containers).html();
					}
					strHTML += '<\/body><\/html>';
					if ( c > 0 ) {
						window['printIFrame'].document.open();
						window['printIFrame'].document.write(strHTML);
						window['printIFrame'].document.close();
						setTimeout(function() {
							var isIE = false;
							if ( navigator.appName.toUpperCase() == 'MICROSOFT INTERNET EXPLORER' ) {
								isIE = true;
							}
							if ( isIE ) {
								printIFrame.focus();
								printIFrame.print();
							} else {
								window.frames['printIFrame'].focus();
								window.frames['printIFrame'].print();
							}
						}, 1000);
					}
				}
			});
		});
	};
})(jQuery);

/*
	Plugin: ThumbSwap
	<a class="thumbSwap" href="javascript: void(0);">
		<img src="1.jpg" width="100" height="100" alt="" />
		<ul>
			<li file="1.jpg" href="#">Item 1</li>
			<li file="2.jpg" href="#">Item 2</li>
			<li file="3.jpg" href="#">Item 3</li>
			<li file="4.jpg" href="#">Item 4</li>
			<li file="5.jpg" href="#">Item 5</li>
		</ul>
	</a>
*/
(function($) {
	$.fn.thumbSwap = function(options) {
		var defaults = {
			serverPath	: '',
			toggleClass	: '',
			defaultNav	: -1
		};
		var options = $.extend(defaults, options);
		return this.each(function(i) {
			var aryLI = [];
			var obj = this;
			var setNum = i;
			var img = $(obj).find('img');
			var li = $(obj).find('li');
			$(img).attr('src', $(li[0]).attr('file'));
			$(obj).attr('href', $(li[0]).attr('href'));
			function setThumb(el) {
				for ( var i=0; i<aryLI.length; i++ )
					$(aryLI[i]).removeClass(options.toggleClass);
				$(el).toggleClass(options.toggleClass);
				$(img).attr({
					src: $(el).attr('file'),
					alt: $(el).text()
				});
				$(obj).attr('href', $(el).attr('href'));
			}
			$.each(li, function(i, el) {
				aryLI.push(this)
				$.data(document, 'aryLI' + obj + setNum, aryLI);
				if ( options.defaultNav == -1 && i == 0 ) $(this).toggleClass(options.toggleClass);
				$(this)
					.bind('mouseover', function() {
						setThumb(this);
					});
				if ( options.defaultNav != -1 ) {
					if ( isNaN(options.defaultNav) ) {
						if ( $(options.defaultNav).get(0) == $(el).get(0) )
							setThumb(options.defaultNav);
						else
							if ( i == 0 )
								setThumb(el);
					} else {
						var num = options.defaultNav - 1;
						if ( i == num )
							setThumb(el);
					}
				}
			});
		});
	};
})(jQuery);

/*
	Pickle Lib
*/
/*
	simulatePickle( isLoggedIn );
		Simulates the needed functionality from universal registration for pickle applications.
		params:
			isLoggedIn: (true:false) - Is the user logged in?
		notes:
			This function needs to go before any code that requires it's properties and methods
*/
function simulatePickle( isLoggedIn ) {
	urUser = {};
	urUser.getEmail = function() { return 'email@domain.com'; }
	urUser.getUserName = function() { return 'John'; }
	urUser.getUserId = function() { return '123456'; }
	if ( isLoggedIn ) urUser.isLoggedIn = true;
}

/*
	findPickleWidget( list )
		Checks the parameter "cat" in the url against [list] and sets vw_widget_name equal to the proper widget
		and sets vw_sort_order according to the parameter "sortby" (can be either: recent, rating or views).
		Also set the order (vw_arrange_order) to DESC (descending)
		params:
			list: (string/object) - If a single string value is passed in, that widget_name will be returned.
									To create a list of multiple channels/categories do something like the following:
									var myList = { channel1: 'hgtv.1000000852.1070', channel2: 'hgtv.1000000852.1071' }
									NOTE: in the case above, the URL will look something like http://.../gallery.html?cat=channel2&sortby=recent
*/
function findPickleWidget( list ) {
	var sortby = jQuery.PickleSetup.getURLParam('sortby');
	var category = jQuery.PickleSetup.getURLParam('cat');
	if ( typeof list == 'string' ) vw_widget_name = list;
	else {
		/* get sortby & cat params */
		/* if category (?cat=) has a value then see if it matches against [list] */
		if ( category != '' ) {
			for (x in list )
				if ( x == category )
					vw_widget_name = list[x];
		}
	}
	/* have the gallery default to most recent */
	switch ( sortby ) {
		case 'recent': { vw_sort_order = 'MOST_RECENT'; vw_arrange_order = 'DESC'; break; }
		case 'rating': { vw_sort_order = 'BY_RATING'; vw_arrange_order = 'DESC'; break; }
		case 'views': { vw_sort_order = 'MOST_POPULAR'; vw_arrange_order = 'DESC'; break; }
		default: { vw_sort_order = 'MOST_RECENT'; vw_arrange_order = 'DESC'; break; }
	}
	return vw_widget_name;
}

/*
	pickleSetup( options )
		Sets up pickle functions to multiple elements on a page contained inside wrapping element of [matched_elements]
		in jQuery( [matched_elements] ).pickleSetup();
		options:
			urUser					[object] The universal registration object
			site					[string] The site or brand name (hgtv, food, hrpo, etc.)
			userNameWrap			[string:object] Reference to the element that will display the user name
			signInWrap				[string:object] Reference to the element that will house the sign in tools
			signOutWrap				[string:object] Reference to the element that will house the sign out tools
			channelNavWrap			[string:object] Reference to the element that will house the channel/category navigation
			sortbyNavWrap			[string:object] Reference to the element that will house the "Sort By" navigation
			channelNavToggleClass	[string] The alternate class name for channel/category navigation
			onChannelChange			[function] A callback function that fires when the channel/category has changed
			categoryAttr			[string] The name of the attribute to be used to specify the category
			sortbyAttr				[string] The name of the attribute to be used to specify the sort order
			defaultNav				[string:object] Reference to the element that will serve as default navigation
			navClassName			[string] The name of the selected class for navigation
			btnUpload				[string:object] Reference to the element that will serve as the "Upload" button
			btnSignIn				[string:object] Reference to the element that will serve as the "Sign In" button
			btnSignOut				[string:object] Reference to the element that will serve as the "Sign Out" button
			btnBackToGallery		[string:object] Reference to the element that will serve as the "Back To Gallery" button
			uploadURL				[string] URL for the upload page
			galleryURL				[string] URL for the gallery page
*/
(function($) {
	$.fn.pickleSetup = function( options ) {
		var pSetup = new jQuery.PickleSetup(options);
		pSetup.init(this);
	};
})(jQuery);

jQuery.PickleSetup = function( options ) {
	/* set default values for the options */
	var defaults = {
		urUser						: null,
		site						: '',
		userNameWrap				: null,
		signInWrap					: null,
		signOutWrap					: null,
		channelNavWrap				: null,
		sortbyNavWrap				: null,
		channelNavToggleClass		: 'selected',
		onChannelChange				: function() {},
		categoryAttr				: 'cat',
		sortbyAttr					: 'sortby',
		defaultNav					: 'recent',
		navClassName				: 'selected',
		btnUpload					: null,
		btnSignIn					: null,
		btnSignOut					: null,
		btnBackToGallery			: null,
		uploadURL					: '',
		galleryURL					: ''
	};
	/* did any of the options get overriden? */
	this.options = jQuery.extend(defaults, options);
};

/* The heart of the program */
jQuery.extend(jQuery.PickleSetup, {
	prototype: {
		init: function(obj) {
			var pickleSetup = this;
			var sortby = jQuery.PickleSetup.getURLParam('sortby');
			var category = jQuery.PickleSetup.getURLParam('cat');
			var foundCategoryMatch = false;
			
			return obj.each(function(i) {
				/*
					set the href value for every anchor inside sortbyNavWrap to
					galleryURL + '?cat=' + category + '&sortby=' + jQuery(this).attr(pickleSetup.options.sortbyAttr)
				*/
				if ( pickleSetup.options.sortbyNavWrap != null ) {
					jQuery.each(jQuery(pickleSetup.options.sortbyNavWrap).find('a'), function() {
						/* if one of the anchors sortbyAttr matches [sortby] then set it's class to navClassName */
						if ( jQuery(this).attr(pickleSetup.options.sortbyAttr) == sortby )
							jQuery(this).addClass(pickleSetup.options.navClassName);
						jQuery(this).attr('href', pickleSetup.options.galleryURL + '?cat=' + category + '&sortby=' + jQuery(this).attr(pickleSetup.options.sortbyAttr));
					});
				}
				
				/* if the parameter "sortby" is nothing, try and match an element either by id=[sortby] or sortbyAttr=[sortby] */
				if ( sortby == '' ) {
					if ( pickleSetup.options.sortbyAttr != 'id' ) {
						jQuery.each(jQuery('*'), function() {
							if ( jQuery(this).attr(pickleSetup.options.sortbyAttr) == pickleSetup.options.defaultNav )
								jQuery(this).addClass(pickleSetup.options.navClassName);
						});
					} else
						jQuery('#' + pickleSetup.options.defaultNav).addClass(pickleSetup.options.navClassName);
				}
				
				/* if [category] has something then send it's value to callback(onChannelChange) */
				if ( category != '' )
					pickleSetup.options.onChannelChange.call(this, category);
				
				/* handle channel/category navigation */
				/* see if channelNavWrap is in use */
				if ( pickleSetup.options.channelNavWrap != null ) {
					
					/* get all children of channelNavWrap */
					var children = jQuery(pickleSetup.options.channelNavWrap).children();
					
					/* get all anchors of channelNavWrap */
					var all = jQuery(pickleSetup.options.channelNavWrap).find('a');
					
					/*
						go through each child of channelNavWrap and see if categoryAttr=[category]
						and if so, change it's class to channelNavToggleClass
					*/
					jQuery.each(children, function() {
						if ( jQuery(this.childNodes[0]).attr(pickleSetup.options.categoryAttr) == category ) {
							jQuery(this).addClass(pickleSetup.options.channelNavToggleClass);
							foundCategoryMatch = true;
						}
					});
					
					/* if foundCategoryMatch=false, set the first child of channelNavWrap's class to channelNavToggleClass */
					if ( !foundCategoryMatch )
						jQuery(children[0]).addClass(pickleSetup.options.channelNavToggleClass);
						
					/*
						set the href value for each anchor in channelNavWrap to
						galleryURL + '?cat=' + jQuery(this).attr(pickleSetup.options.categoryAttr) + '&sortby=' + sortby
					*/
					jQuery.each(all, function() {
						jQuery(this).attr('href', pickleSetup.options.galleryURL + '?cat=' + jQuery(this).attr(pickleSetup.options.categoryAttr) + '&sortby=' + sortby);
					});
				}
				
				/* setup btnBackToGallery if it's in use */
				if ( pickleSetup.options.btnBackToGallery != null )
					if ( pickleSetup.options.galleryURL != '' )
						jQuery(pickleSetup.options.btnBackToGallery)
							.attr('href', pickleSetup.options.galleryURL + '?sortby=' + pickleSetup.options.defaultNav)
							
				/* setup btnUpload if it's in use */
				if ( pickleSetup.options.btnUpload != null )
					jQuery(pickleSetup.options.btnUpload).attr('href', pickleSetup.options.uploadURL);
					
				/*******************************/
				/* FOLLOWING SECTION IS FOR UR */
				/*******************************/
				
				/* check to see if urUser is being used */
				if ( pickleSetup.options.urUser != null ) {
					
					/* make ursign default to HGTV */
					var ursign = 'http://my.hgtv.com/registration/login.esi?DEST_URL=' + pickleSetup.options.uploadURL;
					
					if ( pickleSetup.options.site != '' ) {
						if ( pickleSetup.options.btnSignIn != '' ) {
							
							/* set ursign based on site */
							switch ( pickleSetup.options.site ) {
								case 'hgtv': { var ursign = 'http://my.hgtv.com/registration/login.esi?DEST_URL=' + pickleSetup.options.uploadURL; break; }
							}
						}
					}
					
					/* setup btnSignIn if it's in use based on which site we're at (defaulting to HGTV) */
					if ( pickleSetup.options.btnSignIn != null )
						jQuery(pickleSetup.options.btnSignIn).attr('href', ursign);
					
					/* user is logged in */
					if ( pickleSetup.options.urUser.isLoggedIn ) {
						
						/* set the innerHTML for userNameWrap if it's in use */
						if ( pickleSetup.options.userNameWrap != null )
							jQuery(pickleSetup.options.userNameWrap).html('Hi, ' + urUser.getEmail());
							
						/* show the signoutWrap if it's being used */
						if ( pickleSetup.options.signOutWrap != null )
							jQuery(pickleSetup.options.signOutWrap).show();
							
						/* setup btnSignOut if it's being used */
						if ( pickleSetup.options.btnSignOut != null ) {
							
							/*
								set the onclick event for btnSignOut to:
								- logout();
								- hide signOutWrap if it's in use
								- show signInWrap if it's in use
							*/
							jQuery(pickleSetup.options.btnSignOut).bind('click', function() {
								urUser.logout();
								if ( pickleSetup.options.signOutWrap != null )
									jQuery(pickleSetup.options.signOutWrap).hide();
								if ( pickleSetup.options.signInWrap != null )
									jQuery(pickleSetup.options.signInWrap).show();
							});
						}
					/* user is NOT logged in */
					} else {
						/* if we're on the upload page, redirect the user to galleryURL */
						if ( jQuery.PickleSetup.checkUploadPage(pickleSetup) )
							window.location.href = pickleSetup.options.galleryURL;
						/* for all other pages other than the upload page, show signInWrap if it's in use */
						if ( pickleSetup.options.signInWrap != null )
							jQuery(pickleSetup.options.signInWrap).show();
					}
				}
			});
		}
	},
	/*
		checkLoginPage()
			Returns true if the current url is the same as the uploadURL option, otherwise returns false
			usage:
				if ( jQuery.PickleSetup.checkUploadPage() ) // do something
	*/
	checkUploadPage: function( self ) {
		if ( self.options.uploadURL != '' )
			if ( window.location.href.indexOf(self.options.uploadURL) != -1 )
				return true;
		return false;
	},
	/*
		getURLParam( param )
			Returns the value associated with [param] in a url.
			usage:
				var sortby = jQuery.PickleSetup.getURLParam('sortby');
	*/
	getURLParam: function( param ) {
		var q = document.location.search || document.location.hash;
		if ( param == null )
			return q;
		if ( q ) {
			var pairs = q.substring(1).split('&');
			for ( var i=0; i<pairs.length; i++ )
				if ( pairs[i].substring(0, pairs[i].indexOf('=')) == param )
					return pairs[i].substring((pairs[i].indexOf('=') + 1));
		}
		return '';
	}
});

obj2String = {
	compactOutput: false, 		
	includeProtos: false, 	
	includeFunctions: true,
	detectCirculars: true,
	restoreCirculars: true,
	make:function(arg,restore) {
		this.restore=restore;
		this.mem=[];this.pathMem=[];
		return this.toJsonStringArray(arg).join('');
	},
	toObject:function(x){
		if(!this.cleaner){
			try{this.cleaner=new RegExp('^("(\\\\.|[^"\\\\\\n\\r])*?"|[,:{}\\[\\]0-9.\\-+Eaeflnr-u \\n\\r\\t])+?$')}
			catch(a){this.cleaner=/^(true|false|null|\[.*\]|\{.*\}|".*"|\d+|\d+\.\d+)$/}
		};
		if(!this.cleaner.test(x)){return {}};
		eval("this.myObj="+x);
		if(!this.restoreCirculars || !alert){return this.myObj};
		if(this.includeFunctions){
			var x=this.myObj;
			for(var i in x){if(typeof x[i]=="string" && !x[i].indexOf("JSONincludedFunc:")){
				x[i]=x[i].substring(17);
				eval("x[i]="+x[i])
			}}
		};
		this.restoreCode=[];
		this.make(this.myObj,true);
		var r=this.restoreCode.join(";")+";";
		eval('r=r.replace(/\\W([0-9]{1,})(\\W)/g,"[$1]$2").replace(/\\.\\;/g,";")');
		eval(r);
		return this.myObj
	},
	toJsonStringArray:function(arg, out) {
		if(!out){this.path=[]};
		out = out || [];
		var u; // undefined
		switch (typeof arg) {
		case 'object':
			this.lastObj=arg;
			if(this.detectCirculars){
				var m=this.mem; var n=this.pathMem;
				for(var i=0;i<m.length;i++){
					if(arg===m[i]){
						out.push('"JSONcircRef:'+n[i]+'"');return out
					}
				};
				m.push(arg); n.push(this.path.join("."));
			};
			if (arg) {
				if (arg.constructor == Array) {
					out.push('[');
					for (var i = 0; i < arg.length; ++i) {
						this.path.push(i);
						if (i > 0)
							out.push(',\n');
						this.toJsonStringArray(arg[i], out);
						this.path.pop();
					}
					out.push(']');
					return out;
				} else if (typeof arg.toString != 'undefined') {
					out.push('{');
					var first = true;
					for (var i in arg) {
						if(!this.includeProtos && arg[i]===arg.constructor.prototype[i]){continue};
						this.path.push(i);
						var curr = out.length; 
						if (!first)
							out.push(this.compactOutput?',':',\n');
						this.toJsonStringArray(i, out);
						out.push(':');                    
						this.toJsonStringArray(arg[i], out);
						if (out[out.length - 1] == u)
							out.splice(curr, out.length - curr);
						else
							first = false;
						this.path.pop();
					}
					out.push('}');
					return out;
				}
				return out;
			}
			out.push('null');
			return out;
		case 'unknown':
		case 'undefined':
		case 'function':
			if(!this.includeFunctions){out.push(u);return out};
			//arg="JSONincludedFunc:"+arg;
			//out.push('"');
			//var a=['\n','\\n','\r','\\r','"'];
			//arg+=""; for(var i=0;i<6;i+=2){arg=arg.split(a[i]).join(a[i+1])};
			out.push(arg);
			//out.push('"');
			return out;
		case 'string':
			if(this.restore && arg.indexOf("JSONcircRef:")==0){
				this.restoreCode.push('this.myObj.'+this.path.join(".")+"="+arg.split("JSONcircRef:").join("this.myObj."));
			};
			out.push('"');
			var a=['\n','\\n','\r','\\r','"','\\"'];
			arg+=""; for(var i=0;i<6;i+=2){arg=arg.split(a[i]).join(a[i+1])};
			out.push(arg);
			out.push('"');
			return out;
		default:
			out.push(String(arg));
			return out;
		}
	}
};

/*
	Quiz Lib
*/
jQuery.quizUtils = {
	debug: function( msg ) {
		if ( window.console ) console.debug(msg);
		else alert(msg);
	},
	initLanding: function( domain ) {
		var d = '';
		if ( domain )
			d = domain;
		var sniIQCookie = {
			ga: [],
			at: [],
			clearAnswers: false,
			domain: d
		};
		var strCookie = 'var sniIQCookie =' + obj2String.make(sniIQCookie) + ';';
		jQuery.cookie('sniIQCookie', strCookie, { expires: 1, domain: d, path: '/' });
		eval(jQuery.quizUtils.getCookie());
		if ( typeof sniIQCookie != 'object' )
			alert("There was a problem with setting a cookie on your computer and this quiz requires them to function.\n\n Please enable cookies in the settings of your browser.");
	},
	getCookie: function() {
		var str = jQuery.cookie('sniIQCookie');
		return str;
	},
	checkQuiz: function( url ) {
		eval(jQuery.quizUtils.getCookie());
		if ( typeof sniIQCookie != 'object' ) {
			alert("It appears you've entered this quiz from a page other than the start page, or your browser is not set to accept cookies. You will be redirected to the beginning of the quiz.");
			document.location.href = url;
		}
	},
	backToLastQuestion: function(goBack) {
		alert('It appears the last question was not properlly recorded.  You will now be redirected to the last question.  Please submit your last answer again.');
		history.go(goBack);
		eval(jQuery.quizUtils.getCookie());
		var ga = sniIQCookie.ga.length != 0 ? sniIQCookie.ga : [];
		var at = sniIQCookie.at.length != 0 ? sniIQCookie.at : [];
		var d = sniIQCookie.domain;
		var sniIQCookie = {
			ga: ga,
			at: at,
			clearAnswers: true,
			domain: d
		};
		var strCookie = 'var sniIQCookie =' + obj2String.make(sniIQCookie) + ';';
		jQuery.cookie('sniIQCookie', strCookie, { expires: 1, domain: d, path: '/' });
	},
	setQuestionPage: function( options ) {
		var defaults = {
			landingURL		: '',
			num				: 0,
			form			: null,
			labelPrependID	: '',
			progressBar		: null,
			goBack			: -1
		};
		var options = jQuery.extend(defaults, options);
		/* stop here if no options.landingURL, options.form OR options.num was supplied */
		if ( !options.landingURL ) { jQuery.quizUtils.debug('landing url was not set.  Use option [landingURL]'); return; }
		if ( !jQuery(options.form).get(0) ) { jQuery.quizUtils.debug('Form was not set properly.  Use option [form]'); return; }
		if ( !options.num ) { jQuery.quizUtils.debug('Page number was not set.  Use option [num]'); return; }
		/* check to see if the user just landed on some question page or should be here */
		jQuery.quizUtils.checkQuiz(options.landingURL);
		if ( eval(jQuery.cookie('clearQuizAnswers')) ) {
			var allRadios = jQuery('[type=radio]', options.form);
			jQuery.each(allRadios, function(i) {
				this.checked = false;
			});
		}
		eval(jQuery.quizUtils.getCookie());
		var ga = sniIQCookie.ga.length != 0 ? sniIQCookie.ga : [];
		var at = sniIQCookie.at.length != 0 ? sniIQCookie.at : [];
		var d = sniIQCookie.domain;
		var sniIQCookie = {
			ga: ga,
			at: at,
			clearAnswers: false,
			domain: d
		};
		var strCookie = 'var sniIQCookie =' + obj2String.make(sniIQCookie) + ';';
		jQuery.cookie('sniIQCookie', strCookie, { expires: 1, domain: d, path: '/' });
		/* let's see if the last answer was recorded */
		if ( options.num > 1 )
			if ( sniIQCookie.ga.length < (options.num - 1) )
				jQuery.quizUtils.backToLastQuestion(options.goBack);
		/* set the onsubmit for options.form to validateRadioGroup */
		jQuery(options.form).submit(function() {
			return jQuery.quizUtils.validateRadioGroup(options.form, options.num, options.labelPrependID);
		});
		/* if options.progressBar is being used then set it up */
		if ( options.progressBar != null )
			if ( jQuery(options.progressBar).get(0) )
				jQuery(options.progressBar).progressBar( options.num );
	},
	setupTiePage: function( options ) {
		var defaults = {
			landingURL				: '',
			num						: 0,
			form					: null,
			labelPrependID			: '',
			questionWrapPrependID	: ''
		};
		var options = jQuery.extend(defaults, options);
		if ( !options.landingURL ) { jQuery.quizUtils.debug('landing url was not set.  Use option [landingURL]'); return; }
		if ( !options.form ) { jQuery.quizUtils.debug('Form was not set properly.  Use option [form]'); return; }
		if ( !options.num ) { jQuery.quizUtils.debug('Page number was not set.  Use option [num]'); return; }
		if ( !options.labelPrependID ) { jQuery.quizUtils.debug('Label prepend id was not set.  Use option [labelPrependID]'); return; }
		jQuery.quizUtils.checkQuiz(options.landingURL);
		var aryTie = jQuery.cookie('tiedAnswers').toString().split(',');
		for ( var i=0; i<aryTie.length; i++ )
			if ( jQuery('#' + options.questionWrapPrependID + (parseInt(aryTie[i]) + 1)).get(0) )
				jQuery('#' + options.questionWrapPrependID + (parseInt(aryTie[i]) + 1)).show();
		jQuery(options.form).submit(function() {
			return jQuery.quizUtils.validateRadioGroup(options.form, options.num, options.labelPrependID);
		});
	},
	popupWindow: function( url ) {
		jQuery.quizUtils.popupWin(url, {
			width: 800,
			height: 600,
			resize: 1,
			scrolls: 1,
			status: 1,
			toolbar: 0,
			location: 0,
			menu: 0
		});
	},
	popupWin: function( url, options ) {
		var defaults = {
			width: 800,
			height: 600,
			resize: 0,
			scrolls: 0,
			status: 0,
			toolbar: 0,
			location: 0,
			menu: 0
		};
		var options = jQuery.extend(defaults, options);
		var popupWin = window.open(url, 'popWin', 'width=' + options.width + ', height=' + options.height + ', resizable=' + options.resize + ', scrollbars=' + options.scrolls + ', status=' + options.status + ', toolbar=' + options.toolbar + ', location=' + options.location + ', menubar=' + options.menu);
	},
	validateRadioGroup: function( form, num, labelID ) {
		var chosen = false;
		var allRadios = jQuery(form).find('[type=radio]');
		jQuery.each(allRadios, function(i) {
			if ( jQuery(this).get(0).checked ) {
				eval(jQuery.quizUtils.getCookie());
				sniIQCookie.ga[num - 1] = jQuery(this).val().toUpperCase();
				if ( labelID )
					sniIQCookie.at[num - 1] = escape(jQuery('#' + labelID + (i + 1)).html());
				var ga = sniIQCookie.ga.length != 0 ? sniIQCookie.ga : [];
				var at = sniIQCookie.at.length != 0 ? sniIQCookie.at : [];
				var d = sniIQCookie.domain;
				var sniIQCookie = {
					ga: ga,
					at: at,
					clearAnswers: false,
					domain: d
				};
				var strCookie = 'var sniIQCookie =' + obj2String.make(sniIQCookie) + ';';
				jQuery.cookie('sniIQCookie', strCookie, { expires: 1, domain: d, path: '/' });
				chosen = true;
			}
		});
		if ( !chosen ) {
			alert("Please choose an answer to continue.");
			return false;
		}
	},
	getNumCorrect: function( options ) {
		var defaults = {
			correctAnswers: [],
			beratementSplit: [4, 7, 11],
			numCorrectObj: '',
			beraterHeaderObj: '',
			beraterDescriptionObj: '',
			beraterHeaders: [],
			beraterDescriptions: [],
			goBack: -1
		};
		var options = jQuery.extend(defaults, options);
		eval(jQuery.cookie('sniIQCookie'));
		if ( sniIQCookie.ga.length < options.correctAnswers.length )
			jQuery.quizUtils.backToLastQuestion(options.goBack);
		var numCorrect = 0;
		for ( var i=0; i<options.correctAnswers.length; i++ ) {
			if ( sniIQCookie.ga[i].toLowerCase() == options.correctAnswers[i].toLowerCase() )
				numCorrect++;
		}
		/* loop through options.beratementSplit and see what range we're in */
		for ( var i=0; i<options.beratementSplit.length; i++ ) {
			if ( numCorrect < options.beratementSplit[i] ) {
				jQuery(options.beraterHeaderObj).html(options.beraterHeaders[i]);
				jQuery(options.beraterDescriptionObj).html(options.beraterDescriptions[i]);
				break;
			}
		}
		jQuery(options.numCorrectObj).html(numCorrect.toString());
	},
	displayGuessedAnswers: function( options ) {
		var defaults = {
			numQuestions: 10,
			userAnswerObj: ''
		};
		var options = jQuery.extend(defaults, options);
		var str = jQuery.cookie('sniIQCookie');
		eval(str);
		if ( sniIQCookie.at ) {
			if ( sniIQCookie.at.length == options.numQuestions ) {
				for ( i=0; i<options.numQuestions; i++ ) {
					jQuery('#' + options.userAnswerObj + (i + 1)).html(unescape(sniIQCookie.at[i]));
				}
			}
		}
	},
	getMaxOfNumberSet: function() {
		var largest = arguments[0];
		var tmp = [];
		var mArrayCounter = 0;
		for ( i=0; i<arguments.length; i++ ) {
			if ( arguments[i] >= largest ) {
				if ( arguments[i] > largest ) {
					tmp = [];
					mArrayCounter = 0;
				}
				tmp[mArrayCounter] = i;
				largest = arguments[i];
				mArrayCounter++;
			}
		}
		return tmp;
	},
	getNumOccurrences: function( lookFor, lookIn ) {
		var numCount = 0;
		for ( var i=0; i<lookIn.length; i++ ) {
			if ( lookIn.charAt(i) == lookFor ) {
				numCount++;
			}
		}
		return parseInt(numCount);
	},
	getPersonality: function( options ) {
		var defaults = {
			numQuestions: 10,
			choices: ['a', 'b', 'c', 'd'],
			tieURL: '',
			beraterHeaderObj: '',
			beraterDescriptionObj: '',
			beraterHeaders: [],
			beraterDescriptions: []
		};
		var options = jQuery.extend(defaults, options);
		var tieQuiz = jQuery.cookie('tieQuiz');
		var cookieValue = paramStr = '';
		eval(jQuery.quizUtils.getCookie());
		for ( var i=0; i<(options.numQuestions + 1); i++ ) {
			if ( sniIQCookie.ga[i] != null )
				cookieValue += sniIQCookie.ga[i] + ',';
		}
		for ( i=0; i<options.choices.length; i++ ) {
			eval('var num' + options.choices[i] + ' = jQuery.quizUtils.getNumOccurrences(\'' + options.choices[i].toLowerCase() + '\', cookieValue.toLowerCase());');
			paramStr += 'num' + options.choices[i] + ', ';
		}
		eval('var theHighest = jQuery.quizUtils.getMaxOfNumberSet(' + paramStr.substring(0, paramStr.length - 2) + ');');
		if (theHighest.length > 1) {
			jQuery.cookie('tiedAnswers', theHighest, { expires: 1 });
			if ( options.tieURL ) window.location.href = options.tieURL;
		}
		/* next 2 lines are depreciated (use return) */
		jQuery(options.beraterHeaderObj).html(options.beraterHeaders[parseInt(theHighest)]);
		jQuery(options.beraterDescriptionObj).html(options.beraterDescriptions[parseInt(theHighest)]);
		return theHighest;
	},
	createSendToFriend: function( options ) {
		var defaults = {
			serverPath: '',
			url: 'send_to_friend.htm',
			subject: '',
			body: '',
			width: 300,
			height: 350,
			element: '#btnSendToFriend'
		};
		var options = jQuery.extend(defaults, options);
		jQuery(options.element).attr('href', 'javascript: jQuery.quizUtils.popupWin("' + options.serverPath + options.url + '?serverpath=' + options.serverPath + '&subject=' + options.subject + '&body=' + options.body + '", { width: ' + options.width + ', height: ' + options.height + '});');
	}
};

/* Plugin: progressBar() for Quizzes */
(function($) {
	$.fn.progressBar = function( num ) {
		return this.each(function(i) {
			var clip = document.createElement('div');
			$(clip).css({
				position	: 'relative',
				width		: ($(this).get(0).offsetWidth / 2) + 'px',
				height		: $(this).get(0).offsetHeight,
				overflow	: 'hidden'
			});
			$(this)
				.wrap(clip)
				.css({
					position	: 'absolute',
					visibility	: 'visible',
					left		: '-' + ( ($(this).get(0).offsetWidth / 2) - (num * $(this).get(0).offsetHeight) ) + 'px'
				});
		});
	};
})(jQuery);

/*
	Utilities Library
*/
jQuery.sniUtil = {

	applyParamsToInputs: function( options ) {
		var defaults = { list: [] };
		var options = $.extend(defaults, options);
		for ( var i=0; i<options.list.length; i++ ) {
			$('input[name=' + options.list[i].split(':')[0] + ']').val(jQuery.sniUtil.getParam(options.list[i].split(':')[1]));
		}
	},
	
	/* function compareNums(a, b) : Compares two numbers and returns the greater one */
	compareNums: function(a, b) {
		return a - b;
	},
	
	/*
		function getHighestZIndex() - Returns the element on the page with the highest z-index
		Return Type: (int)
		Usage:
			var highZIndex = $.sniUtil.getHighestZIndex();
			document.getElementById('myID').style.zIndex = $.sniUtil.getHighestZindex() + 1;
	*/
	getHighestZIndex: function() {
		var allElements = document.getElementsByTagName('*');
		var mZindices = new Array();
		mZindices[0] = 0;
		for (var i=0; i<allElements.length; i++) {
			if (allElements[i].nodeType == 1) {
				if (document.all) { if (allElements[i].currentStyle) { mZIndex = allElements[i].currentStyle['zIndex']; if (!isNaN(mZIndex)) { mZindices.push(mZIndex); } } else if (window.getComputedStyle) { mZIndex = document.defaultView.getComputedStyle(allElements[i], null).getPropertyValue('zIndex'); if (!isNaN(mZIndex)) { mZindices.push(mZIndex); } }
				} else { if (allElements[i].currentStyle) { mZIndex = allElements[i].currentStyle['z-index']; if (!isNaN(mZIndex)) { mZindices.push(mZIndex); } } else if (window.getComputedStyle) { mZIndex = document.defaultView.getComputedStyle(allElements[i], null).getPropertyValue('z-index'); if (!isNaN(mZIndex)) { mZindices.push(mZIndex); } } }
			}
		}
		mZindices = mZindices.sort(jQuery.sniUtil.compareNums);
		var highest = parseInt(mZindices[mZindices.length - 1]);
		if (highest == 0) highest = 100;
		return highest;
	},
	
	/*
		function sortAssocArray() - Returns a new array of an associated array sorted
		Usage:
			alert($.sniUtil.sortAssocArray(assocArry));
	*/
	sortAssocArray: function(assocArray) {
		var newArr = new Array;
		for (var property in assocArray) {
			newArr[newArr.length] = assocArray[property];
		}
		return newArr.sort();
	},
	
	/*
		function getScrollXY() - Reutrns the ScrollX and ScrollY of a webpage
		Return Type: (array with integers)
		Usage:
			var xScroll = $.sniUtil.getScrollXY()[0];
			var yScroll = $.sniUtil.getScrollXY()[1];
	*/
	getScrollXY: function() {
		  var scrOfX = 0, scrOfY = 0;
		  if ( typeof( window.pageYOffset ) == 'number' ) {
			// Netscape compliant
			scrOfY = window.pageYOffset;
			scrOfX = window.pageXOffset;
		  } else if ( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
			// DOM compliant
			scrOfY = document.body.scrollTop;
			scrOfX = document.body.scrollLeft;
		  } else if ( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
			// IE6 standards compliant mode
			scrOfY = document.documentElement.scrollTop;
			scrOfX = document.documentElement.scrollLeft;
		  }
		  return [ scrOfX, scrOfY ];
	},
	
	/*
		function getScreenHeight() - Returns the height of the screen
		Return Type: (int)
		Usage:
			var scrHeight = $.sniUtil.getScreenHeight();
			alert(  $.sniUtil.getScreenHeight() );
	*/
	getScreenHeight: function() {
		var myHeight = 0;
		if ( typeof( window.innerWidth ) == 'number') myHeight = window.innerHeight;
		else if ( document.documentElement && ( document.documentElement.clientHeight ) ) myHeight = document.documentElement.clientHeight;
		else if ( document.body && ( document.body.clientHeight ) ) myHeight = document.body.clientHeight;
		return myHeight;
	},
	
	/*
		function findPos(obj) - Returns the top and left position of obj
		Return Type: (array with integers)
		Usage:
			var topOffset = 30;
			var leftOffset = 50;
			var pos = $.sniUtil.findPos( document.getElementById('myID') );
			document.getElementById('someOtherElementID').style.top = pos[1] + topOffset + 'px';
			document.getElementById('someOtherElementID').style.left = pos[0] + leftOffset + 'px';
			----***----
			$('#someOtherElementID').get(0).style.top = $.sniUtil.findPos( document.getElementById('myID') )[1] + 200 + 'px';
	*/
	findPos: function(obj) {
		var _currentLeft = _currentTop = 0;
		if (obj.offsetParent) {
			_currentLeft = obj.offsetLeft;
			_currentTop = obj.offsetTop;
			while (obj = obj.offsetParent) { _currentLeft += obj.offsetLeft; _currentTop += obj.offsetTop; }
		}
		return [_currentLeft, _currentTop];
	},
	findPosFromParent: function(obj) {
		
	},
	isArray: function(obj) {
		return obj && !(obj.propertyIsEnumerable('length')) && typeof obj === 'object' && typeof obj.length === 'number';
	},
	find: function(str) {
		var ret = false;
		for ( i=0; i<this.length; i++ ) {
			if ( typeof(str) == 'function' ) {
				if ( str.test(this[i]) ) {
					if ( !ret ) { ret = [] }
					ret.push(i);
				}
			} else {
				if ( this[i] === str ) {
					if ( !ret ) { ret = [] }
					ret.push(i);
				}
			}
		}
		return ret;
	},
	capitalize: function( str, words ) {
		if ( !words && words != 0 ) {
			var w = 'all';
		} else {
			w = words;
		}
		var ret = '';
		var ary = str.split(' ');
		// looks for keywords and change to numbers
		if ( w == 'first' ) { w = 0; }
		if ( w == 'last' ) { w = ary.length - 1; }
		for ( var i=0; i<ary.length; i++ ) {
			switch ( typeof w ) {
				case 'string':
					if ( w == 'all' ) {
						ret += ary[i].substring(0, 1).toUpperCase() + ary[i].substring(1, ary[i].length) + ' ';
					}
					break;
				case 'number':
					if ( w == (i + 1) ) {
						ret += ary[i].substring(0, 1).toUpperCase() + ary[i].substring(1, ary[i].length) + ' ';
					} else {
						ret += ary[i] + ' ';
					}
					break;
				case 'object':
					if ( jQuery.sniUtil.isArray(w) ) {
						if ( w.find((i + 1)) ) {
							ret += ary[i].substring(0, 1).toUpperCase() + ary[i].substring(1, ary[i].length) + ' ';
						} else {
							ret += ary[i] + ' ';
						}
					}
					break;
			}
		}
		return ret.replace(/\s*$/, '');
	},
	formatNumberWithCommas: function( num ) {
		var num = num.toString(), c = Math.floor((num.length - 1) / 3), s = num.length, o = '';
		for ( var i=c; i>=0; i-- ) {
			s -= 3;
			var set = i != c ? num.substring(s, s + 3) + ',' : num.substring(s, s + 3);
			o = set + o;
		}
		return o;
	},
	getParam: function( param ) {
		var q = document.location.search || document.location.hash;
		if ( param == null ) return q;
		if ( q ) {
			var pairs = q.substring(1).split('&');
			for ( var i=0; i < pairs.length; i++ ) {
				if ( pairs[i].substring(0, pairs[i].indexOf('=')) == param ) {
					return pairs[i].substring((pairs[i].indexOf('=')+1));
				}
			}
		}
		return '';
	}
};

/* MISC Javascript */

/*
	pickleSetup plug in for jQuery
	by: Chris Engle
	last modified: 09.11.08
	
	jQuery( [matched_elements] ).pickleSetup( options );
	Sets up pickle functions to multiple elements on a page contained inside wrapping element of [matched_elements]
*/

/* This is just a little fix for IE6 with background images.  Prevents from flickering. */
if ( document.all ) { try { document.execCommand("BackgroundImageCache", false, true); } catch(err) {} }