function get_parent_container(parent_container) {
	// references:
	//   * http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object
	//   * http://www.javascriptkit.com/domref/nodetype.shtml

	var isWindow = function(o){
		var result = false;
		var dom2 = (
						(typeof Window === "object") &&
						(o instanceof Window)
		);
		result = dom2;
		return result;
	};
	var isNode = function(o){
		var dom2 = (
						(typeof Node === "object") &&
						(o instanceof Node)
		);
		var dom1 = (
						(typeof o === "object") &&
						(typeof o.nodeType === "number") &&
						(typeof o.nodeName==="string")
		);
		var result = dom2 || dom1;
		return result;
	}
	var isDocument = function(o){
		var result	= false;
		var is_node	= isNode(o);
		var dom2, dom1;
		if (is_node){
			dom2 = (
				(typeof HTMLDocument === "object") &&
				(o instanceof HTMLDocument)
			);
			dom1 = (
				(o.nodeType === 9)
			);
			result = dom2 || dom1;
		}
		return result;
	}
	var isElement = function(o){
		var result	= false;
		var is_node	= isNode(o);
		var dom2, dom1;
		if (is_node){
			dom2 = (
				(typeof HTMLElement === "object") &&
				(o instanceof HTMLElement)
			);
			dom1 = (
				(o.nodeType === 1)
			);
			result = dom2 || dom1;
		}
		return result;
	}

	if      (isWindow(parent_container))														{parent_container = parent_container.document;}
	else if (isDocument(parent_container))														{}
	else if (isElement(parent_container))														{}
	else if (typeof parent_container === 'object' && parent_container instanceof jQuery)		{}
	else if (typeof parent_container === 'string')												{parent_container = $(parent_container);}
	else																						{parent_container = window.document;}
	return parent_container;
}

// ================================================================================================

function initialize_all_popup_elements(parent_container, force_unbind) {				// enables this function to be reused after the document ready-handler has been called. For instance, after an element has been (dynamically) added to the DOM.. this function can be called with the parent container passed as the parameter.
	parent_container = get_parent_container(parent_container);

	var selectors = [
						'.popup'
					,	'.popup_nested'
// note: pdf popups are disabled because NS serves all .pdf files with a Content-Disposition HTTP header, which prevents in-browser display; forces the "save-as or open" dialog.
//					,	'.popup_pdf'
					,	'.scene_7_popup_cust'
					,	'.scene7Popup'
//					,	'.popup_window'
	];
	$.each(selectors, function(i, selector){
		initialize_popup_elements(selector, parent_container, force_unbind);
	});
}

// ================================================================================================

function initialize_popup_elements(selector, parent_container, force_unbind) {		// enables this function to be reused after the document ready-handler has been called. For instance, after an element has been (dynamically) added to the DOM.. this function can be called with the parent container passed as the parameter.
	parent_container = get_parent_container(parent_container);

	$(selector, parent_container).each(function(){
		var options = $(this).attr('options');
		if (options) {																// enables colorbox options to be declared inline on a per-element basis.
			options = eval("(" + options + ")");									// note: $.parseJSON() won't work in this case, because hook functions are not proper JSON data values. (ie: '{"onComplete":function(){}}')
		}
		if (typeof options === 'object') {
			if (typeof options.onInitialization === 'function') {
				options.onInitialization( $(this), options );						// adds an additional hook, which is only run once during this initialization step. Parameters passed: (1) a reference to the a.popup element, (2) a reference to the options object
				delete options.onInitialization;
			}
		}
		else {
			options = {};
		}

		var url = $(this).attr('href');
		if ( (url.length > 1) && (url.substring(0,1) === '#') ) {					// sets a convention to auto-detect inline elements. (can be disabled by explicitely assigning the inline option to false).
																					// examples: <a class="popup" href="#div_id">show hidden inline div in colorbox</a> is equivalent to: <a class="popup" href="#div_id" options='{"inline":true}'>show hidden inline div in colorbox</a> but NOT: <a class="popup" href="#">url has to be longer than 1 character!!!</a> NOR: <a class="popup" href="#div_id" options='{"inline":false}'>do something different</a> NOR: <a class="popup" href="#div_id" options='{"inline":true, "href":"#another_div"}'>show a different inline div in colorbox</a>
			if (
					(typeof options.href === 'undefined') &&
					(
						(typeof options.inline === 'undefined') ||
						(options.inline == true)
					)
			) {
				options.inline	= true;
				options.href	= url;
			}
		}

		if (selector === '.popup_nested') {											// associate a set of default options to a css class (jquery selector)
			var hook_handlers = {};
			hook_handlers.onComplete = [];
			if (typeof options.onComplete === 'function') {							// inject additional hook handler, called after user-defined function if present.
				hook_handlers.onComplete.push(options.onComplete);
			}
			hook_handlers.onComplete.push(function(){
				initialize_all_popup_elements('#colorbox', true);					// attach $.fn.colorbox() functionality to all popup classes contained within the parent_container: #colorbox
			});
			options.onComplete = function(){
				$.each(hook_handlers.onComplete, function(i, foo){foo();});
			};
		}
		if (selector === '.popup_pdf') {											// associate a set of default options to a css class (jquery selector)
			options.iframe		= true;
			options.width		= Math.round( ($(window).width())  * (0.9) );
			options.height		= Math.round( ($(window).height()) * (0.9) );
			options.maxWidth	= '980px';
		}
		if (selector === '.scene_7_popup_cust') {									// associate a set of default options to a css class (jquery selector)
			options.photo		= true;
		}
		if (selector === '.scene7Popup') {											// associate a set of default options to a css class (jquery selector)
			options.iframe		= true;
			options.innerWidth	= '540px';
			options.innerHeight	= '650px';

			if (typeof options.clear_eventhandlers === 'undefined') {				// can over-ride inline by assigning the value: []
				options.clear_eventhandlers = ['click'];
			}
		}
		if (typeof options.clear_eventhandlers !== 'undefined') {
			for (var i=0; i<options.clear_eventhandlers.length; i++) {
				$(this).unbind(options.clear_eventhandlers[i]);
			}
			delete options.clear_eventhandlers;
		}

		if (
				(!options.inline)
			&&	(!options.html)
			&&	(!options.href)
			&&	(url.length > 1)
			&&	(url.substring(0,1) !== '#')
		) {
			options.href	= encodeURI(url);
		}

		$.extend(options, {															// globally over-ride to force particular desired attributes:
			"transition"	: "none",
			"speed"			: 0
		});

		if (force_unbind === true){
			$(this).unbind('click');
		}

		$(this).colorbox(options);
	});
}

// ================================================================================================

$(document).ready(function(){
	initialize_all_popup_elements();

	// ----------------------------------------------
	// IE css fixes that require direct DOM access..
	// ----------------------------------------------
	if ($.browser.msie) {
		$('#colorbox.cboxIE #cboxWrapper + div:first').css('width','1px');

		$(document).bind('cbox_complete cbox_iframe_resize_complete', function(event){

			var event_handler = function(){
				$('#cboxOverlay').css('display', 'none');
				$('#cboxOverlay').css('height', $(document).height()+'px');
				$('#cboxOverlay').css('display', 'block');
/* ************************************************************************** */
/*
				var middle_elements = {
					"left":		$('#cboxMiddleLeft'),
					"center":	$('#cboxContent'),
					"right":	$('#cboxMiddleRight')
				};
				var middle_height	= heightOfChildren(middle_elements.center) + 'px';

				$.each(middle_elements, function(key){
					middle_elements[key].css('height', middle_height);
				});

				middle_elements.center.parent().css('width','auto').css('height','auto').parent().css('width','auto').css('height','auto');
				var width = middle_elements.center.parent().width();
				middle_elements.center.parent().css('width',width).parent().css('width',width);
*/
/* ************************************************************************** */
			};

//			if (event.type === 'cbox_complete') {
				event_handler();
//			}
/* ************************************************************************** */
/*
			if (event.type === 'cbox_iframe_resize_complete') {
				var poll_function = function( poll_function, event_handler ){
					var colorbox = $('#colorbox:not(:animated)');
					if (colorbox.length === 1) {
						event_handler();
					}
					else {
						setTimeout(function(){ poll_function( poll_function, event_handler ); }, 200);
					}
				};
				poll_function( poll_function, event_handler );
			}
*/
/* ************************************************************************** */
		});
	}
});

// ================================================================================================ helper functions

function popup___nested_iframe__open(link, window_context, options) {
	if (typeof options === 'undefined') {options = {};}
	options.iframe		= true;
	options.href		= parent.$(link).attr("href");

	if (
		!( options.href.match(/^(http:\/\/|\/)/) )
	) {
		// path is relative to the window.document.location rather than parent.window.location,
		// will need to rewrite it as an absolute path:

		// in this context, the global "window" variable will refer to the parent window,
		// which requires that a reference to the iframe window be passed into the function.
		if (typeof window_context === 'undefined') {
			return false;
		}
		var path = window_context.document.location.pathname.replace(/[^\/]*$/, '');
		options.href = path + options.href;
	}

	if ( (typeof options.width  === 'undefined') && (typeof options.innerWidth  === 'undefined') && (typeof options.width_percent != 'undefined') ) {
		var width_percent  = parseFloat(options.width_percent);
		if ( (!isNaN(width_percent)) && (width_percent >= 0) && (width_percent <= 1) ) {
			options.width	= Math.round( (parent.$(parent.window).width()) * (width_percent) )+"px";
		}
	}
	if ( (typeof options.height === 'undefined') && (typeof options.innerHeight === 'undefined') && (typeof options.height_percent != 'undefined') ) {
		var height_percent = parseFloat(options.height_percent);
		if ( (!isNaN(height_percent)) && (height_percent >= 0) && (height_percent <= 1) ) {
			options.height	= Math.round( (parent.$(parent.window).height()) * (height_percent) )+"px";
		}
	}

	// globally over-ride to force particular desired attributes:
	parent.$.extend(options, {
		"transition"	: "none",
		"speed"			: 0
	});

	parent.$.fn.colorbox(options);
	return false;
}

function popup___nested_iframe__resize(options) {
	if (typeof options === 'undefined') {options = {};}

	if ( (typeof options.width  === 'undefined') && (typeof options.innerWidth  === 'undefined') && (typeof options.width_percent != 'undefined') ) {
		var width_percent  = parseFloat(options.width_percent);
		if ( (!isNaN(width_percent)) && (width_percent >= 0) && (width_percent <= 1) ) {
			options.width	= Math.round( (parent.$(parent.window).width()) * (width_percent) )+"px";
		}
	}
	if ( (typeof options.height === 'undefined') && (typeof options.innerHeight === 'undefined') && (typeof options.height_percent != 'undefined') ) {
		var height_percent = parseFloat(options.height_percent);
		if ( (!isNaN(height_percent)) && (height_percent >= 0) && (height_percent <= 1) ) {
			options.height	= Math.round( (parent.$(parent.window).height()) * (height_percent) )+"px";
		}
	}
	parent.$.colorbox.resize(options);
	parent.$.event.trigger('cbox_iframe_resize_complete');
	return false;
}

function heightOfChildren(element){
	var $ = parent.jQuery;
	var heights = 0;
	$(element).children(':visible').each(function(){
		var height = $(this).outerHeight(true);
		heights += height;
	});
	return heights;
}

function widthOfChildren(element){
	var $ = parent.jQuery;
	var widths = [];
	$(element).children(':visible').each(function(){
		var width = $(this).outerWidth(true);
		widths.push(width);
	});
	return widths.sort(function(a,b){return a - b}).pop();							// sort numerically and ascending, return last/largest width
}
