/*
 * nri_std_lib.js
 * 
 * NRi common utility functions.
 * 
 * requires:
 * 	- jQuery >= 1.2.3
 *  - jQuery Cookies plug-in (/sites/all/jslib/jquery_cookie.js)
*/

/* establish nri namespace and common site variables */
if (typeof(nri) == "undefined")
{
	nri = {};
}

// defaults
nri._ours = true; // is this hosted in NRi's Drupal environment (true) or by a vendor (false)?
nri._hostname = document.location.hostname;
nri._port = (document.location.port!=80 && document.location.port!=443)?":"+document.location.port:'';
nri.url_prefix = false;

nri._init = function()
{
	if (! nri.url_prefix) nri.url_prefix = (!nri._ours) ? "http://"+nri._hostname+nri._port : '';
}

jQuery(nri._init);

/** Create a "closure" to bind an object's method to that object's context
*/
nri.bind = function(toObject,methodName)
{
	return function()
	{
		toObject[methodName].apply(toObject,arguments);
	}
}

/**
 * class nri.Menu
 * Dynamic menuing system. Will dynamically fetch a full menu tree (as
 * an object in JSON or JSONp) for a menu if:
 * 1.) The top-level menu items are already populated
 * 2.) Both its root element (<ul>, <ol>) and the top-level <li>'s each
 *     have a custom attribute nri:menuid set to the appropriate Drupal
 *     menu ID
 * 
 * e.g.,
 * 
 * <ul id="nrcNav_MainMenu" nri:menuid="93">
 * 	<li nri:menuid="94">Menu item 1</li>
 * 	<li nri:menuid="95">Menu item 2</li>
 * 	...
 * 	<li nri:menuid="k">Menu item n</li>
 * </ul>
 * 
 * <script type="text/javascript">
 * // <![CDATA[
 * 	var nri.myproject.mainmenu = new nri.Menu( $("#nrcNav_MainMenu"), 75, 300);
 * // ]]>
 * </script>
 * 
 * On li:hover for any top-level menu item that contains submenu items, a submenu tree
 * with the following structure will be built:
 * 
 * e.g.,
 * 
 * <li nri:menuid="94">Menu item 1
 * 	<div class="nrcNav_subMenuWrapper">
 * 		<h4 class="nrcTxt_modHed"><span class="nrcTxt_label">Submenu:</span> Menu item 1</h4>
 * 		<ul class="nrcNav_subMenu">
 * 			<li nri:menuid="101" class="nrc_item1">Submenu item 1</li>
 * 			<li nri:menuid="102" class="nrc_item2">Submenu item 2</li>
 * 			...
 * 			<li nri:menuid="k" class="nrc_itemN nrc_itemLast">Submenu item N</li>
 * 		</ul>
 * 	</div>
 * </li>
 * 
 * @param jQuery $rootel The root element (<ul>) of the menu
 * @param int expany_delay_ms	Milliseconds to wait before expanding submenus
 * @param int collapse_delay_ms Milliseconds to wait before collapsing submenus
 */
nri.Menu = function( /* $rootel[,expand_delay_ms,collapse_delay_ms] */ )
{	
	if (arguments.length == 3)
	{
		this.expand_delay = arguments[1];
		this.collapse_delay = arguments[2];
	}
	
	// ensure nri._init()'s been called (default vars set)
	nri._init();
	
	if (arguments.length)
	{	
		this.init( arguments[0] );
	}
};

// default expansion and collapse delays
nri.Menu.prototype.expand_delay = 75;
nri.Menu.prototype.collapse_delay = 300;

nri.Menu.prototype.init = function( $rootel )
{
	var $ = jQuery;
	
	this.root = $rootel;

	this._mid = this.root.attr('nri:menuid'); // root menu ID
	this._tree = false; // menu tree
	
	if (this._mid) // this is a Drupal menu and should be fetched via nri_menujson.php helper script
	{	
		// fetch the full menu as a JSON object
		$.ajax(
			{
				url:nri.url_prefix + '/nri_menujson.php?mid=' + this._mid,
				cache:true,
				async:true,
				success:nri.bind(this,'_build'),
				error:function(s,e,x){return false;},
				dataType:(nri._ours?'json':'jsonp') // use jsonp if cross-domain
			}
		);
	}
	else // this menu was manually built; just add the hover handlers to top-level items
	{
		this._build( false );
	}
}

nri.Menu.prototype._build = function( tree )
{
	var $ = jQuery;
	this._tree = tree;
	var expand_delay = this.expand_delay;
	var collapse_delay = this.collapse_delay;

	// set the hover actions of all top-level menu items
	this.root.children("li").each(
		function(i)
		{
			var $el = $(this);
			var mid = $el.attr("nri:menuid");
			
			// if a.) we were passed a menu tree object and this menu item exists in that tree
			// or b.) this menu item already has a (manually defined) submenu, bind the
			// expand and collapse hover actions
			if ( (tree && mid && (typeof(tree.children[mid])!="undefined") )
				|| $el.find("div.nrcNav_subMenuWrapper").hide().length
			)
			{
				var subtree = (tree && (typeof(tree.children[mid])=="object") )?tree.children[mid]:false;

				$el.hover(
					function(e)
					{ nri.Menu.expand($(this),subtree,expand_delay); },
					function(e)
					{ nri.Menu.collapse($(this),collapse_delay); }
				);
			}
		}
	);
};

// passed a submenu_tree object, recurse through depth levels and return
// the HTML for the tree
nri.Menu._insert_menu = function(submenu_tree, depth)
{
		var $ = jQuery;
		var submenu = '';
		var cnt = 0;
		
		if ( (typeof(submenu_tree.length) == "undefined") && depth--)	// checks typeof submenu_tree.length to ensure 
		{																// an object (rather than array) was passed.
			submenu += '<ul class="nrcNav_subMenu">';					// Drupal passes an empty array if there are no
			var url = '';												// child menu items.
			
			
			for (var mid in submenu_tree)
			{
				cnt++;
				url = submenu_tree[mid].url;
				
				if ( url.substr(0,4)!='http' && nri.url_prefix )
				{
					url = nri.url_prefix + url;
				}
				
				submenu += '<li nri:menuid="'+mid+'" class="nrc_item'+cnt+(cnt==submenu_tree.length?' nrc_itemLast':'')+'">';
				submenu += '<a href="'+url+'">'+submenu_tree[mid].title+'</a>';
				
				if (depth && submenu_tree[mid].children)
				{
					submenu += nri.Menu._insert_menu(submenu_tree[mid].children,depth);
				}
				
				submenu += '</li>';
			}
			
			submenu += '</ul>';
		}
		
		return submenu;
}

nri.Menu.expand = function( $el, submenu_tree, delay )
{	
	var $ = jQuery;
	$el[0].opening = true;
	
	if ($el[0].timeout) clearTimeout($el[0].timeout);
	
	// immediately collapse all other sub menus
	$el.siblings().each(
		function()
		{
			if (this.timeout){  clearTimeout(this.timeout); }
			$(this).find("div.nrcNav_subMenuWrapper").hide('fast');
		} 
	); // clear pending axns and immediately hide all other subnavs

	$el[0].timeout = setTimeout(
		function()
		{
			// if submenus aren't already populated, build them
			if ( (! $el.find("div.nrcNav_subMenuWrapper").length) && (typeof(submenu_tree.children.length) == "undefined") )
			{
				// build submenu html...
				var submenu = '<div class="nrcNav_subMenuWrapper"><h4 class="nrcTxt_modHed"><span class="nrcTxt_label">Submenu:</span> '+submenu_tree.title+'</h4>';
				submenu += nri.Menu._insert_menu(submenu_tree.children,2);
				submenu += '</div>';
				
				// ... and append it
				$el.append( submenu );
				$(window).trigger('nriMenuAppended',[$el]);
			}
			
			// show the submenu and force it into the width of the viewport
			$el.find("div.nrcNav_subMenuWrapper").show('fast',function(){$el[0].opening=false; nri.boundByViewportWidth(this);});
		},
		delay
	);

};

nri.Menu.collapse = function( $el, delay )
{
	var $ = jQuery;
	if ($el[0].timeout) clearTimeout($el[0].timeout);
	
	$el[0].closing = true;
	
	$el[0].timeout = setTimeout(
		function()
		{
			if (! $el[0].opening) $el.find("div.nrcNav_subMenuWrapper").hide('fast');
		},
		delay
	);
};

/* preference storage structure */
nri.user_prefs = function(){ this.data = {}; };
nri.user_prefs.data = false;

nri.uri = {};
nri.uri.queryels = false;

nri.user_prefs._init = function()
{
	nri.user_prefs.load();
	
	// set initial font size
	var fontsize = nri.user_prefs.get('font_zoom');
	if (! fontsize) fontsize = 0;
	nri.setFontSize(fontsize);
	
}

nri.user_prefs.store = function()
{
	var $ = jQuery;
	if (typeof($.cookie)=="undefined") return false;
	
	var data = JSON.stringify(nri.user_prefs.data);
	$.cookie('nri_user_prefs',data,{ expires:45,path:'/',secure:false});
}

nri.user_prefs.load = function()
{
	var $ = jQuery;
	if (typeof($.cookie)=="undefined") return false;
	
	var data = $.cookie('nri_user_prefs');
	
	if (data) data = data.substr( data.indexOf('=') + 1 );
	
	if (data == "undefined" || data == "false") data = false;

	if (data) {nri.user_prefs.data = eval('('+data+')');}
	else nri.user_prefs.data = new Object();
}

nri.user_prefs.set = function(key,val)
{
	nri.user_prefs.data[key] = val;
	nri.user_prefs.store();
}

nri.user_prefs.get = function( key )
{
	if (nri.user_prefs.data.hasOwnProperty(key)) return nri.user_prefs.data[key];
	else return false;
}

nri.setFontSize = function( zoom_level )
{
	var $ = jQuery;
	var fontpct = 95 + (zoom_level * 5);
	nri.user_prefs.set('font_zoom',zoom_level);
	return $(".font-resizable").css('font-size',fontpct + '%');
}

nri.increaseFontSize = function()
{
	var fontsize = nri.user_prefs.get('font_zoom');
	fontsize++;
	return nri.setFontSize(fontsize);
}

nri.decreaseFontSize = function()
{
	var fontsize = nri.user_prefs.get('font_zoom');
	fontsize--;
	return nri.setFontSize(fontsize);
}

nri.resetFontSize = function()
{
	return nri.setFontSize(0);
}

// ititialize preferances
jQuery(document).ready( nri.user_prefs._init );

/**
 * Common utilities
 */
 
// open url in a new window with (optional) attributes 
nri.openWindow = function(  url /*[, name[, width[, height[, with_decorations]]]] */ )
{
	var win = false;
	var width = arguments[2]?arguments[2]:800;
	var height = arguments[3]?arguments[3]:600;
	var name = arguments[1]?arguments[1]:Math.round( Math.random() * 999999999 )+'nriwin';
	var decorations = 'width='+width+',height='+height+',scrollbars=1,resizable=1' + (arguments[4]?',menubar=1,toolbar=1,status=1':'');
	win = window.open(url,name,decorations);
	win.focus();
	return win;
};

// force-fit an element into the viewport width
nri.boundByViewportWidth = function(el)
{
	var $ = jQuery;
	
	// fetch viewport width and height
	var vpw = typeof(window.innerWidth)=="undefined"?document.documentElement.clientWidth:window.innerWidth;
	var vph = typeof(window.innerHeight)=="undefined"?document.documentElement.clientHeight:window.innerHeight;
	
	var $tel = $(el);
	
	// reset left margin (if changed)
	if (typeof( ($tel[0].nri_marginLeft)!="undefined") && $tel[0].nri_marginLeft)
	{ $tel.css('margin-left',$tel[0].nri_marginLeft);	}
	
	$tel[0].nri_marginLeft = $tel.css('margin-left');
	
	var left = parseInt($tel[0].nri_marginLeft);
	var os = $tel.offset();
	var right = os.left + $tel.width() + parseInt($tel.css('padding-left')) + parseInt($tel.css('padding-right')) + parseInt($tel.parent().css('padding-right'));

	if ( right > vpw )
	{
		left += vpw - right - 15;
	}
	else if (os.left < 0)
	{
		left += 0 - left;	
	}
	
	$tel.css('margin-left',left+'px');
}

// switch the active stylesheet
nri.setActiveStyleSheet = function(title) {
   var i, a, main, oldstyle, oldtitle;
   
   oldstyle = false;
   
	for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
		oldtitle = a.getAttribute("title");
		if(a.getAttribute("rel").indexOf("style") != -1
			&& oldtitle) {
			
			if ( (! a.disabled) && (oldtitle != title) ) oldstyle = oldtitle;
			
			a.disabled = true;
			
			if(a.getAttribute("title") == title) a.disabled = false;
		}
	}
   
   return oldstyle;
}

// switch active stylesheets by media type
nri.setStyleSheetByMedia = function(media_type) {
   var styles = { inactive:[], active:[] };
   
   var lnkels = document.getElementsByTagName("link");
   var ss = false, mtype = false, css = false;
   
	for(var i=0; i < lnkels.length; i++) {
		ss = lnkels[i];
		css = (ss.getAttribute("type")=="text/css")?true:false;
		mtype = ss.getAttribute("media");
		
		if (css && mtype && (mtype.indexOf('all') == -1) )
		{
			if (mtype != media_type)
			{
				if (!ss.disabled)
				{
					styles.inactive[styles.inactive.length] = ss;
					ss.disabled = true;
				}
			}
			else
			{
				ss.setAttribute("media",mtype+=",all,temp")
				styles.active[styles.active.length] = ss;
				ss.disabled = false;
			}
		}
	}
   
   return styles;
}

nri.toggleStyleSheets = function( styles_assoc_array )
{
	var ss,mtype,idx;
	
	for (var i = 0; i < styles_assoc_array.inactive.length; i++)
	{
		ss = styles_assoc_array.inactive[i];
		ss.disabled = false;
	}
	
	for (var i = 0; i < styles_assoc_array.active.length; i++)
	{
		ss = styles_assoc_array.active[i];
		mtype = ss.getAttribute("media");
		idx = mtype.indexOf(",all,temp");
		
		if (idx != -1)
		{
			mtype = mtype.substr(0,idx) + mtype.substr(idx+9);
		}
		ss.setAttribute("media",mtype);
		ss.disabled = true;
	}
	
	var tval = styles_assoc_array.inactive;
	
	styles_assoc_array.inactive = styles_assoc_array.active;
	styles_assoc_array.active = tval;
	
	return styles_assoc_array;
}

// switch to the "printer-friendly" stylesheet and print the current page
nri.printPage = function()
{
	var oldstyles = nri.setStyleSheetByMedia('print');
	
	window.print();
	
	confirm("When finished printing, please click 'ok' to return to the standard view.");
	
	nri.toggleStyleSheets(oldstyles);
	
	return true;
}

/** form functions **/

nri.form = {};

nri.form.tbsubmit = function( oform )
{
	// if Thickbox isn't loaded, just target the form results to a new window 
	if (typeof("tb_show") == "undefined")
	{
		oform.target = "_blank";
		return true;
	}
	
	/**
	 * otherwise, check to see if the Thickbox iframe has been initialized
	 * if so, submit the form, targeting the results to th TB iframe
	 * if not, init the iframe and submit once it's instantiated
	 */
	
	if (jQuery("#TB_iframeContent").length)
	{
		oform.target = jQuery("#TB_iframeContent").attr('name');
		
		if (oform.submitted) return true;
		else
		{
			oform.submitted = true;
			oform.submit();
		}
	}
	else // if not, initialize it
	{
		try
		{
			tb_show('','/empty.html?KeepThis=true&TB_iframe=true&width=700&height=500',null);
			setTimeout( function() { nri.form.tbsubmit(oform); }, 100 );
			oform.submitted = false;
			return false;
		}
		catch(e)
		{
			return true;
		}
	}
}

nri.uri._fetchparams = function()
{
	var tq = window.location.search.substr(1);
	var ci=0,li=0,tk=false;
	
	nri.uri.queryels = {};
	
	if (tq.length) do
	{
		ci = tq.indexOf('=',li);
		if (ci == -1) break;
		
		tk = tq.substr(li,(ci - li));
		
		li = tq.indexOf('&',li + 1);
		
		if (typeof(nri.uri.queryels[tk]) == "undefined") nri.uri.queryels[tk] = new Array();
		
		nri.uri.queryels[tk][nri.uri.queryels[tk].length] = tq.substr((ci+1),(li>-1)?(li-ci-1):(tq.length-ci));
	} while( li++ != -1 );
}

nri.uri.getparam = function( key )
{
	// if we haven't already done so, build query params array
	if (! nri.uri.queryels) nri.uri._fetchparams();
	
	if (typeof(nri.uri.queryels[key]) != "undefined")
	{
		if (nri.uri.queryels[key].length == 1) return nri.uri.queryels[key][0];
		else return nri.uri.queryels[key];
	}
	
	return false;
}

