/*
 * 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;

// consts
nri.URL_GET_ACROBAT = "http://www.adobe.com/go/EN_US-H-GET-READER";
nri.URL_GET_FLASH = "http://www.adobe.com/go/EN_US-H-GET-FLASH";
nri.URL_GET_AIR = "http://www.adobe.com/go/EN_US-H-GET-AIR";


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) // mouseover
					{ nri.Menu.expand($(this),subtree,expand_delay); },
					function(e) // mouseout
					{ 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
	nri.Menu.collapseAll();

	$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]);
			}
			
			// if the mouseout doesn't trigger a collapse, clicking anywhere in the body will do the trick.
			$("body").click(
				function()
				{
					if (this.timeout){  clearTimeout(this.timeout); }
					$(this).find("div.nrcNav_subMenuWrapper").hide('fast');
					$("body").unbind('click');
				}
			);
			
			// 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
	);
};

// collapse ALL open submenus
nri.Menu.collapseAll = function()
{
	var $ = jQuery;
	
	$('.nrcNav_subMenuWrapper').each(
		function()
		{
			var $this = $(this);
			var par = $this.parent();
			var opening = false;
			
			par = par[0];
			opening = (typeof(par.opening) != "undefined")?par.opening:false;
			
			if (! opening) // if this menu isn't in the process of opening...
			{
				if (typeof(par.timeout) != "undefined" && par.timeout) // clear the parent menu timeout, if any
				{  clearTimeout(par.timeout); }
				
				if ( $this.is(':visible') ) $this.hide();
			}
		} 
	);
	
	return true;
}


/**
 * TABBED MODULE CLASS
 */
nri.TabbedModule = function( el )
{
	var $ = jQuery;
	
	this.$el = $(el);
	
	var module = this;
	
	this.tabs = [];
	this.pages = [];
	this.default_tab = false;
	this.active_tab = false;
	
	var ttabs = this.$el.find(".nrcBlk_comboModTab");
	
	for (var i = 0, len = ttabs.length; i < len; i++)
	{
		var ttab = new nri.TabbedModule.Tab(ttabs[i],this);
		
		this.tabs[i] = ttab;
		
		this.pages[i] = this.tabs[i].page;
		
		if ( $(ttabs[i]).parent().hasClass('nrc_default') )
		{
			this.default_tab = this.tabs[i];
			this.active_tab = this.tabs[i];
		}
		else if (this.pages[i])
		{
			var pgh = this.pages[i].$el.height();
			var elh = this.$el.height();
			
			if (pgh > elh)
			{
				this.$el.height( pgh );
			}
			
			this.pages[i].hide();
		}
	}
	
	// ensure default and active tabs are set
	this.default_tab = this.default_tab ? this.default_tab : this.tabs[0];
	this.active_tab = this.active_tab ? this.active_tab : this.default_tab;
	
	this.activate(this.active_tab.name);
}

nri.TabbedModule.Tab = function( el, module )
{
	var $ = jQuery;
	
	this.$el = $(el);
	this.$anc = $( this.$el.find("a")[0] );
	this.module = module;
	this.page = false;
	
	this.name = this.$anc.attr('href');
	
	// make sure we only get the hash from the link URL
	// as the "name" of the tab
	this.name = this.name.substr( this.name.indexOf('#') );
	
	// get associated page
	var $tpageel = $( this.name ); 
	
	if ($tpageel.length)
	{
		this.page = new nri.TabbedModule.Page( $tpageel[0] );
	}
	
	var tobj = this;
	
	this.$anc.bind('click',{obj:tobj},function(e){ e.data.obj.activate(); return false; });
}

nri.TabbedModule.Tab.prototype.activate = function()
{
	this.module.activate(this.name);
}

nri.TabbedModule.Page = function( el )
{
	this.$el = jQuery(el);
	
	this.name = '#' + this.$el.attr('id');
}

nri.TabbedModule.Page.prototype.show = function()
{
	this.$el.addClass('nrc_active');
}

nri.TabbedModule.Page.prototype.hide = function()
{
	this.$el.removeClass('nrc_active');
}

nri.TabbedModule.prototype.activate = function( name )
{
	// ensure all other tabs are hidden
	for (var i = 0,len = this.pages.length; i < len; i++)
	{
		if (this.pages[i].name == name)
		{
			this.pages[i].show();
			this.tabs[i].$el.addClass('nrc_active');
		}
		else
		{
			this.pages[i].hide();
			this.tabs[i].$el.removeClass('nrc_active');
		}
	}
	
}

/* 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});
	
	return true;
};

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();
	
	return true;
};

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 * 10);
	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;
};

// namespace for UI widgets and utilities
nri.ui = {};

// return the document's current maximum z-index
nri.ui.maxzindex = function()
{
	var $doc = jQuery("*");
	var zidx = 0;
	
	for (var i = 0, len = doc.length; i < len; i++)
	{
		zidx = Math.max( zidx, jQuery( $doc[i] ).css('z-index') );
	}
	
	return zidx;
}

/**
 * Overlay "window" (abs. positioned div)
 */
nri.ui.Window = function( params, style )
{
	var $ = jQuery;
	
	var id = 'nrcWgt_Window' + Math.round( Math.random() * 9000 + 1000 );
	
	var html = '<div id="'+id+'" style="position:absolute;z-index:1000000;display:none;" class="nrcWgt_Window">'
				+ '<div class="nrcBlk_wgtHed"><h3 class="nrcTxt_title"><span class="nrcTxt_label"></span></h3><ul class="nrcNav_wgtCtrls"><li class="nrcCtl_close"><a href="javascript:void(0);"><span class="nrcTxt_label">close</span></a></li></ul></div>'
				+ '<div class="nrcBlk_wgtBody"></div>'
				+'</div>';
	
	$("body").append(html);
	
	var win = this;
	
	this.$el = $('#'+id).hide();
	this.$el[0].widget = this;
	this.overlay = new nri.ui.Overlay( id );
	
	this.$head = this.$el.children('.nrcBlk_wgtHed');
	this.$body = this.$el.children('.nrcBlk_wgtBody');
	
	this.$el.find('.nrcCtl_close a, a.nrcCtl_close').bind('click',{$el:this.$el},
			function(e)
			{
				win = e.data.$el[0].widget;
				win.close();
			}
	);
	
	this.destroyOnClose = false;
	
	this.anchor =
	{
		'corner':false,
		'top':false,
		'bottom':false,
		'left':false,
		'right':false
	};
	
	if (typeof(params) == 'object')
	{
		if (params['destroyOnClose']) this.destroyOnClose = true;
		if (params['title']) this.setTitle( params['title'] );
		if (params['body']) this.setBody( params['body'] );
		if (typeof(params['anchor']) == 'object') this.setAnchor( params['anchor'] );
	}
	
	if ((!style) || (typeof(style) != 'object'))
	{
		style = {'width':0,'height':0};
	}

	this.orig_width = style['width'];
	this.orig_height = style['height'];
	
	// defaults
	if (! style['width'])
	{
		style.width = Math.floor(nri.viewport.width() * .75) + 'px';
		this.orig_width = -1;
	}
	else this.orig_width = style.width;
	
	if (! style['height'])
	{
		style.height = Math.floor(nri.viewport.height() * .75) + 'px';
		this.orig_height = -1;
	}
	else this.orig_height = style.height;
	
	$(window).bind('resize',{obj:this},this._onresize);
	
	this.$el.css(style);
}

nri.ui.Window.prototype.destroy = function()
{
	this.overlay.destroy();
	delete this.overlay;
	$(window).unbind('resize',this._onresize);
	this.$el.remove();
}

nri.ui.Window.prototype.open = function()
{
	this.center();
	
	// close window on click of overlay
	this.overlay.$el.bind('click',{'obj':this},function(e){if(e.data['obj'])e.data['obj'].close();return false;});
	
	this.overlay.show();
	this.$el.show();
	
	$(window).bind('keypress',{'obj':this},nri.ui.Window._keypress);
}

nri.ui.Window.prototype.close = function()
{
	$(window).unbind('keypress',nri.ui.Window._keypress);
	
	this.$el.css('visibility','hidden');
	this.overlay.hide();
	this.$el.trigger('nriWidgetHide');

	if (this.destroyOnClose) this.destroy();
}

nri.ui.Window.prototype.center = function()
{
	nri.ui.center(this.$el);
	this.$el.trigger('nriWidgetMove');
}

nri.ui.Window.prototype.setHead = function( html )
{
	this.$el.children('.nrcBlk_wgtHed').html( html );
}

nri.ui.Window.prototype.setTitle = function( text )
{
	this.$el.find('.nrcBlk_wgtHed .nrcTxt_title .nrcTxt_label').html( text );
}

nri.ui.Window.prototype.setBody = function( html )
{
	this.$el.children('.nrcBlk_wgtBody').html( html );
}

nri.ui.Window.prototype.setAnchor = function( anchor_descriptor )
{
	nri.ui.Window._setProp( this.anchor, "|corner|top|bottom|left|right|", anchor_descriptor );
}

nri.ui.Window.prototype._onresize = function(e)
{
	var win = (typeof(e) == 'object' && e['data']) ? e.data.obj : this;
	
	var vpw = nri.viewport.width() * .75;
	var vph = nri.viewport.height() * .75;
	
	var ww = win.$el.width();
	var wh = win.$el.height();
	
	if ( (ww > vpw) || (win.orig_width == -1) )
	{
		win.$el.width( vpw );
	}
	else if (ww < win.orig_width)
	{
		win.$el.width( Math.min(vpw,win.orig_width) );
	}
	
	if ( (wh > vph) || (win.orig_height == -1))
	{
		win.$el.height( vph );
	}
	else if (wh < win.orig_height)
	{
		win.$el.height( Math.min(vph,win.orig_height) );
	}
	
	win.center();
	
	win.overlay._afterScroll();
	
	win.$el.trigger('nriWidgetResize');
}


/** helper static to set properties of a collection (prop_collection)
  * identified in a pipe-delimited string (proplist)
  * to values defined by the user in params
*/
nri.ui.Window._setProp = function(prop_collection,proplist,params)
{
	for (prop in params) if (proplist.indexOf('|' + prop + '|') != -1)
	{
		this.prop_collection[prop] = params[prop];
	}
}

// keypress handler
nri.ui.Window._keypress = function(e)
{
	var win = e.data['obj'] ? e.data['obj'] : false;
	
	if (win)
	{
		switch(e.which)
		{
			case 0: // null char; FF is returning this for escape?
			case 27: // escape
			case e.DOM_VK_ESCAPE: // escape (Mozilla DOM)
			{
				win.close();
				break;
			}
		}
	}
}

/**
 * Center an arbitrary element in the viewport
 */
nri.ui.center = function( $element )
{
	if (typeof($element) != 'function') $element = jQuery($element);
	
	var cl = (nri.viewport.width() - $element.width()) / 2 + nri.viewport.scrollLeft();
	var ct = (nri.viewport.height() - $element.height()) / 2 + nri.viewport.scrollTop();
	
	$element.css({'position':'absolute','top':ct + 'px','left':cl + 'px'});
}


/**
 * Translucent overlay "mask"
 */
nri.ui.Overlay = function( parent_id )
{
	var $ = jQuery;
	
	// generate a "unique enough" id
	var id = 'nrcWgt_Overlay' + Math.round( Math.random() * 9000 + 1000 );
	
	// use an iframe as our overlay mask if MSIE 6
	var elem = ( jQuery.browser.msie && jQuery.browser.version < 7 ) ? 'iframe' : 'div';
	
	var html = '<'+elem+' id="'+id+'" class="nrcWgt_overlayMask"></'+elem+'>';
	
	$("body").append(html);
	
	this.$el = $('#'+id);
	this.$el[0].widget = this;
	this.parent_id = parent_id;
	this.$parent = $('#' + parent_id);
	
	// listen for nriWidgetShow and nriWidgetHide events; if the target is our parent, show/hide ourself
	this.$parent.bind('nriWidgetShow',{'$el':this},
			function(e)
			{ var $el = e.data.$el; if (e.target.id == $el.parent_id) $el.show(); }
	);
	this.$parent.bind('nriWidgetHide',{'$el':this},
			function(e)
			{ var $el = e.data.$el; if (e.target.id == $el.parent_id) $el.hide(); }
	);
}

nri.ui.Overlay.prototype.destroy = function()
{
	this.$el.hide();
	this.$el.remove();
	return null;
}

nri.ui.Overlay.prototype.show = function()
{
	var zidx = -1;
	var $ = jQuery;
	
	// get current z-index of our parent and ensure we
	// show up behind it. If it doesn't have an assigned
	// z-index, get the current max z-index and assign
	// it to the parent
	if (! (zidx = this.$parent.css('z-index')) )
	{
		zidx = nri.ui.maxzindex() + 1;		
		this.$parent.css('z-index',zidx);
	}
	
	$(window).bind('scroll',{'obj':this},this._afterScroll);
	
	this._afterScroll({data:{me:this}});
	
	this.$el.css({'z-index':(zidx-1),'visibility':'visible'});	
	this.$el.show();
}

nri.ui.Overlay.prototype.hide = function()
{
	this.$el.hide();
	$(window).unbind('scroll',this._afterScroll);
}

nri.ui.Overlay.prototype._afterScroll = function()
{
	var me = (typeof(arguments[0]) == 'object' && arguments[0]['target']) ? arguments[0].data.obj : this;

	// recalculate viewport and scroll extents and make sure we fill the page
	me.$el.css({'width':nri.viewport.docWidth()+'px','height':nri.viewport.docHeight()+'px'});	
}

// alert the user. By default, simply a wrapper for window.alert(), though
// this can be overridden.
nri.alert = function(msg)
{
	return alert(msg);
}

//prompt the user to confirm an action. By default, simply a wrapper for window.confirm(), though
//this can be overridden.
nri.confirm = function(msg)
{
	return confirm(msg);
}

//prompt the user for input. By default, simply a wrapper for window.prompt(), though
//this can be overridden.
nri.prompt = function(msg)
{
	return prompt(msg);
}

nri.viewport = function()
{
	this.width = nri.viewport.width();
	this.height = nri.viewport.height();
}

nri.viewport.width = function()
{
	return typeof(window.innerWidth)=="undefined"?document.documentElement.clientWidth:window.innerWidth;
}

nri.viewport.height = function()
{
	return typeof(window.innerHeight)=="undefined"?document.documentElement.clientHeight:window.innerHeight;	
}

nri.viewport.scrollLeft = function()
{
	return typeof(window.scrollX)!="undefined" ? window.scrollX : document.documentElement.scrollLeft;
}

nri.viewport.scrollTop = function()
{
	return typeof(window.scrollY)!="undefined" ? window.scrollY : document.documentElement.scrollTop;
}

nri.viewport.docWidth = function()
{
	return typeof(window.scrollMaxX) != "undefined" ? nri.viewport.width() + window.scrollMaxX : document.body.offsetWidth;
}

nri.viewport.docHeight = function()
{
	return typeof(window.scrollMaxY)!= "undefined" ? nri.viewport.height() + window.scrollMaxY : document.body.offsetHeight;
}
escape
// force-fit an element into the viewport width
nri.boundByViewportWidth = function(el)
{
	var $ = jQuery;
	
	// fetch viewport width and height
	var vpw = nri.viewport.width();
	var vph = nri.viewport.height();
	
	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,i=0;
	
	for (i = 0; i < styles_assoc_array.inactive.length; i++)
	{
		ss = styles_assoc_array.inactive[i];
		ss.disabled = false;
	}
	
	for (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;
};

nri.txtBreakLongLines = function( text, length )
{
	var c = 0;
	var char = '';
	var inent = 0;
	var breakchars = " \t\n\r-";
	var begentchars = "&<";
	var endentchars = "&>;";
	var outtext = "";
	var shychar = "&shy;"; // character sequence to use as a 'discretionary hyphen'
		
	for (var i = 0; i < text.length; i++)
	{
		char = text.charAt(i);
		
		if ((inent == 0) && (breakchars.indexOf( char ) != -1) )
		{
			c = 0;
			inent = 0;
		}
		else if (inent && (endentchars.indexOf( char ) != -1) )
		{
			c -= inent - 1;
			inent = 0;
		}
		else
		{
			c++;
			inent += ( (inent || (begentchars.indexOf( char ) != -1)) ? 1 : 0);
		}
			
		if ( (c > length) && (! inent))
		{
			outtext += shychar;
			c = 0;
		}

		outtext += char;
	}
	
	return outtext;
}

/* display a photo gallery in a thickbox window */
nri.inlineGallery = function( e )
{
	var nid = e.data.nid;
	var url = "#TB_inline?width=800&height=520&inlineId=nrcBlk_Gallery";

	if (! $("#nrcBlk_Gallery").length)
	{
		$("body").append(
				"<div id=\"nrcBlk_Gallery\" class=\"thickbox\" style=\"display:none\">" +
				"<div id=\"nrcBlk_GalleryPH\">" +
				"<div class=\"nrcWgt_loading nrcWgt_loadingSWF\">" +
				"<a href=\"http://www.adobe.com/go/getflashplayer\" target=\"_blank\">" +
				"<img src=\"/sites/all/themes/custom/nrcom09/style/images/flash_loading.gif\" alt=\"Flash presentation loading\" width=\"94\" height=\"94\"/>" +
				"</a>" +
				"<p><strong>Attempting to load rich media.</strong> Please wait a moment. </p>" +
				"<p>This feature requires the free " +
				"<a href=\"http://www.adobe.com/go/getflashplayer\" target=\"_blank\"><strong>Adobe Flash Player&reg;</strong></a>" +
				"<span>, version 9 or better</span>.</p></div>" +
				"</div></div>"
		);
	}
	
	var flashvars = {};
	flashvars.pathToImages = "/files/imagecache/zoom_view/Images/";
	flashvars.pathToControlFile = "/nri/gallery/soundslides/xml/" + nid + "/soundslides.xml";
	
	/**
	 * @TODO for some reason, SWFObject isn't writing out the FlashVars parameter when
	 * passed as an argument. I'm haivng to tack it onto the SWF URL as a query part instead
	 */
	flashvars_str = "?";
	
	for (var p in flashvars)
	{
		flashvars_str += escape(p) + "=" + escape(flashvars[p]) + "&";
	}
	
	var params = {
		base:"/nri/gallery/soundslides/xml/" + nid + "/",
		allowScriptAccess:"always",
		quality:"high",
		allowFullScreen:"true",
		menu:"false",
		bgcolor:"#000000",
		wmode:"opaque"
	};

	swfobject.embedSWF(
		"/sites/all/modules/nri_utilities/soundslides/soundslides_player.swf" + flashvars_str,
		"nrcBlk_GalleryPH",
		800, 520, "7", void(0),
		void(0),
		params
	);
	
	setTimeout( function(){tb_show(null,url);}, 100);
	return false; // go no further
}

/** 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;
		}
	}
	
	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;
};

/**
 * Browser capabilities
 */
nri.browser = {};

var nri_detectableWithVB = false;

// plug-in detection routines
//adapted from http://support.adobe.com/devsup/devsup.nsf/docs/52970.htm/$File/detectplugins.htm

nri.browser.detectPDF = function()
{
	var pluginFound = nri.browser.detectPlugin('Adobe','Acrobat'); 
	// if not found, try to detect with VisualBasic
	if(!pluginFound && nri_detectableWithVB) {
		pluginFound = detectActiveXControl('PDF.PdfCtrl.5');
	}
	
	return pluginFound;
}

nri.browser.detectFlash = function()
{
	pluginFound = nri.browser.detectPlugin('Shockwave','Flash'); 
	// if not found, try to detect with VisualBasic
	if(!pluginFound && nri_detectableWithVB) {
		pluginFound = detectActiveXControl('ShockwaveFlash.ShockwaveFlash.1');
	}
	// check for redirection
	return pluginFound;
}


nri.browser.detectPlugin = function() {
	// allow for multiple checks in a single pass
	var daPlugins = nri.browser.detectPlugin.arguments;
	// consider pluginFound to be false until proven true
	var pluginFound = false;
	// if plugins array is there and not fake
	if (navigator.plugins && navigator.plugins.length > 0) {
		var pluginsArrayLength = navigator.plugins.length;
		// for each plugin...
		for (pluginsArrayCounter=0; pluginsArrayCounter < pluginsArrayLength; pluginsArrayCounter++ ) {
			// loop through all desired names and check each against the current plugin name
			var numFound = 0;
			for(namesCounter=0; namesCounter < daPlugins.length; namesCounter++) {
				// if desired plugin name is found in either plugin name or description
				if( (navigator.plugins[pluginsArrayCounter].name.indexOf(daPlugins[namesCounter]) >= 0) || 
					(navigator.plugins[pluginsArrayCounter].description.indexOf(daPlugins[namesCounter]) >= 0) ) {
					// this name was found
					numFound++;
				}   
			}
			// now that we have checked all the required names against this one plugin,
			// if the number we found matches the total number provided then we were successful
			if(numFound == daPlugins.length) {
				pluginFound = true;
				// if we've found the plugin, we can stop looking through at the rest of the plugins
				break;
			}
		}
	}
	return pluginFound;
} // detectPlugin

nri.browser.getPlugin = function( type )
{
	var msg = false;
	var url = "";
	
	if (type == "pdf")
	{
		msg  = "The free Adobe Reader\xAE browser plug-in is required to view this document.\n\n";
		msg += "You do not appear to have Adobe Reader installed. Would you like to visit Adobe's website ";
		msg += "to download and install the plug-in?";
		
		url = nri.URL_GET_ACROBAT;
	}
	else if (type == "flash")
	{
		msg  = "The free Adobe Flash Player\xAE browser plug-in is required to view this content.\n\n";
		msg += "You do not appear to have Adobe Flash Player installed. Would you like to visit Adobe's website ";
		msg += "to download and install the plug-in?";
		
		url = nri.URL_GET_FLASH;
	}
	else if (type == "air")
	{
		msg  = "The free Adobe AIR\xAE run-time environment is required to use this application.\n\n";
		msg += "You do not appear to have Adobe AIR installed. Would you like to visit Adobe's website ";
		msg += "to download and install the run-time?";
		
		url = nri.URL_GET_AIR;
	}
	
	if ( msg && nri.confirm(msg) )
	{
		nri.openWindow(url,'nri-plugin-window',950,550,true);

		if ( nri.confirm("Once you have installed the plug-in, click 'Ok' to continue.") ) return true;
		else return false;
	}
	else
	{
		if ( nri.confirm("You do not appear to have the plug-in or application neccessary to view this content. Would you like to continue anyway?") )
		{
			return true;
		}
		else return false;
	}
}

// VBScript plug-in detected routine for MSIE (Windows)
if ((navigator.userAgent.indexOf('MSIE') != -1) && (navigator.userAgent.indexOf('Win') != -1)) {
	document.writeln('<script language="VBscript">');

	document.writeln('\'do a one-time test for a version of VBScript that can handle this code');
	document.writeln('nri_detectableWithVB = False');
	document.writeln('If ScriptEngineMajorVersion >= 2 then');
	document.writeln('  nri_detectableWithVB = True');
	document.writeln('End If');

	document.writeln('\'this next function will detect most plugins');
	document.writeln('Function detectActiveXControl(activeXControlName)');
	document.writeln('  on error resume next');
	document.writeln('  detectActiveXControl = False');
	document.writeln('  If nri_detectableWithVB Then');
	document.writeln('     detectActiveXControl = IsObject(CreateObject(activeXControlName))');
	document.writeln('  End If');
	document.writeln('End Function');

	document.writeln('\'and the following function handles QuickTime');
	document.writeln('Function detectQuickTimeActiveXControl()');
	document.writeln('  on error resume next');
	document.writeln('  detectQuickTimeActiveXControl = False');
	document.writeln('  If nri_detectableWithVB Then');
	document.writeln('    detectQuickTimeActiveXControl = False');
	document.writeln('    hasQuickTimeChecker = false');
	document.writeln('    Set hasQuickTimeChecker = CreateObject("QuickTimeCheckObject.QuickTimeCheck.1")');
	document.writeln('    If IsObject(hasQuickTimeChecker) Then');
	document.writeln('      If hasQuickTimeChecker.IsQuickTimeAvailable(0) Then ');
	document.writeln('        detectQuickTimeActiveXControl = True');
	document.writeln('      End If');
	document.writeln('    End If');
	document.writeln('  End If');
	document.writeln('End Function');

	document.writeln('</scr' + 'ipt>');
}

nri.browser._is_unsupported = -1;

nri.browser.unsupported = function()
{
	// if we've already checked and cached the result, return it
	if (nri.browser._is_unsupported > -1)
	{ return nri.browser._is_unsupported; }

	// otherwise, compare the browser against our list of "unsupported" agents
	var $ = jQuery;
		
	if ( 	($.browser.msie && parseInt($.browser.version) < 7)		// MSIE < 7
		 ||	($.browser.safari && parseInt($.browser.version) < 522)	// Webkit < v522 (Safari, Chrome)
	)
	{
		return nri.browser._is_unsupported = 1;
	}
	
	return nri.browser._is_unsupported = 0;
}

nri.browser.unsupported.notifier = function()
{
	return false;
}

nri.browser.unsupported.dialog = function()
{
	if (nri.user_prefs.get('unsupported-browser-dialog')) return false;
	else if (nri.browser.unsupported())
	{
		var $ = jQuery;
		
		if (typeof($.cookie)=="undefined") return false; // if the cookie doesn't exist because we couldn't set it, abort!

		var html = '<div id="nrc_BrowserMessage" style="visibility:hidden;"><table width="400" cellpadding="0" cellspacing="0" border="0" id="nrc_BrowserMessage"><tr><td class="borderCorner">&nbsp;</td><td class="borderT" colspan="2" align="right"><a href="javascript:nri.browser.unsupported.dialog.destroy();void(0);">close (X)</a></td></tr><tr><td class="borderL">&nbsp;</td><td class="content"><table width="380" cellpadding="0" cellspacing="0" border="0"><tr><td class="header">Upgrade Recommended</td></tr><tr><td><p>To enjoy News-Record.com as its designers intended,<br />we strongly suggest that you upgrade to the latest version<br />of Firefox, Internet Explorer, Safari, or Chrome.<br />If you are using an older version of one of these browsers &#151; or are using another browser entirely &#151; and cannot upgrade<br />to a more recent version, please be aware that certain<br />features may not work for you.</p><a href="http://www.news-record.com/browserUpgrade" class="learnMore">Learn More<br />About Upgrading</a><span class="orLine">- or upgrade now -</span><ul><li><a href="http://www.mozilla.com/en-US/firefox/personal.html" target="_blank"><img title="Mozilla Firefox" alt="Mozilla Firefox" src="http://mm.news-record.com/drupal/sites/all/themes/custom/shared/style/browserUpgrade/browser-firefox.gif" width="78" height="105" /></a></li><li><a href="http://www.microsoft.com/windows/internet-explorer/default.aspx?pkw=internet%20explorer" target="_blank"><img title="Microsoft Internet Explorer" alt="Microsoft Internet Explorer" src="http://mm.news-record.com/drupal/sites/all/themes/custom/shared/style/browserUpgrade/browser-explorer.gif" width="78" height="105" /></a></li><li><a href="http://www.apple.com/safari/" target="_blank"><img title="Apple Safari" alt="Apple Safari" src="http://mm.news-record.com/drupal/sites/all/themes/custom/shared/style/browserUpgrade/browser-safari.gif" width="78" height="105" /></a></li><li><a href="http://www.google.com/chrome" target="_blank"><img title="Google Chrome" alt="Google Chrome" src="http://mm.news-record.com/drupal/sites/all/themes/custom/shared/style/browserUpgrade/browser-chrome.gif" width="78" height="105" /></a></li></ul></td></tr></table></td><td class="borderR">&nbsp;</td></tr><tr><td class="borderCorner">&nbsp;</td><td class="borderB">&nbsp;</td><td class="borderCorner">&nbsp;</td></tr></table></div>';
		
		$("body").append(html);
		
		var $el = $("#nrc_BrowserMessage");
					
		$el[0].overlay = new nri.ui.Overlay("nrc_BrowserMessage");					
		
		// clicking on the overlay closes the dialog
		$el[0].overlay.$el.click(
			function()
			{
				nri.browser.unsupported.dialog.destroy();
				return false; // stop the bubble!
			}
		);
		
		nri.browser.unsupported.dialog._afterScroll({data:{'$el':$el,'animate':false}});

		// reposition on scroll
		$(window).bind('scroll',{'$el':$el},nri.browser.unsupported.dialog._afterScroll);
		
		$el.hide().css({'visibility':'visible'}).fadeIn('slow').css('visibility','visible').trigger('nriWidgetShow');
	}
	
	nri.user_prefs.set('unsupported-browser-dialog','YES');
}

nri.browser.unsupported.dialog._afterScroll = function(e)
{
	var $el = ( typeof(e.data != "undefined") ? e.data.$el : e);
	var animate = ( typeof(e.data.animate) != "undefined" ? e.data.animate : true);
	
	
	$el.stop();

	// fetch viewport width and height
	var vpw = nri.viewport.width();
	var vph = nri.viewport.height();
	
	var w = $el.width();
	var h = $el.height();
	
	var left = ((w && vpw > w) ? Math.floor((vpw - w) / 2) : 10) + nri.viewport.scrollLeft();
	var top = ((h && vph > h) ? Math.floor((vph - h) / 2) : 10) + nri.viewport.scrollTop();
	
	if (animate) $el.stop().animate({'top':top+'px','left':left+'px'},300,'swing');
	else $el.stop().css({'top':top+'px','left':left+'px'});
}

nri.browser.unsupported.dialog.destroy = function()
{
	var $el = jQuery('#nrc_BrowserMessage');
	$(window).unbind('scroll',nri.browser.unsupported.dialog._afterScroll);
	var overlay = $el[0].overlay;
	$el.hide().trigger('nriWidgetHide').remove();
	overlay.destroy();
	delete overlay;
}

nri.inspect = {};

nri.inspect.properties = function( object )
{
	var retstr = "";
	
	for (prop in object)
	{
		retstr += "o " + prop + " = " + object[prop] + "\n"; 
	}
	
	return retstr;
}

/**
 * Copyright Eric Windelin (http://eriwen.com/javascript/js-stack-trace/)
 * and Luke Smith 
 */
nri.inspect.stackTrace = function ()
{
	var mode;
	try {(0)()} catch (e) {
	    mode = e.stack ? 'Firefox' : window.opera ? 'Opera' : 'Other';
	}

	switch (mode) {
	    case 'Firefox' : return function () {
	        try {(0)()} catch (e) {
	            return e.stack.replace(/^.*?\n/,'').
	                           replace(/(?:\n@:0)?\s+$/m,'').
	                           replace(/^\(/gm,'{anonymous}(').
	                           split("\n");
	        }
	    };

	    case 'Opera' : return function () {
	        try {(0)()} catch (e) {
	            var lines = e.message.split("\n"),
	                ANON = '{anonymous}',
	                lineRE = /Line\s+(\d+).*?in\s+(http\S+)(?:.*?in\s+function\s+(\S+))?/i,
	                i,j,len;

	            for (i=4,j=0,len=lines.length; i<len; i+=2) {
	                if (lineRE.test(lines[i])) {
	                    lines[j++] = (RegExp.$3 ?
	                        RegExp.$3 + '()@' + RegExp.$2 + RegExp.$1 :
	                        ANON + RegExp.$2 + ':' + RegExp.$1) +
	                        ' -- ' + lines[i+1].replace(/^\s+/,'');
	                }
	            }

	            lines.splice(j,lines.length-j);
	            return lines;
	        }
	    };

	    default : return function () {
	        var curr  = arguments.callee.caller,
	            FUNC  = 'function', ANON = "{anonymous}",
	            fnRE  = /function\s*([\w\-$]+)?\s*\(/i,
	            stack = [],j=0,
	            fn,args,i;

	        while (curr) {
	            fn    = fnRE.test(curr.toString()) ? RegExp.$1 || ANON : ANON;
	            args  = stack.slice.call(curr.arguments);
	            i     = args.length;

	            while (i--) {
	                switch (typeof args[i]) {
	                    case 'string'  : args[i] = '"'+args[i].replace(/"/g,'\\"')+'"'; break;
	                    case 'function': args[i] = FUNC; break;
	                }
	            }

	            stack[j++] = fn + '(' + args.join() + ')';
	            curr = curr.caller;
	        }

	        return stack;
	    };
	}
};

nri.gmap = {};

nri.gmap.expand = function( mapid )
{
	var $ = jQuery;
	var obj = Drupal.gmap.getMap( mapid );
	
	if (obj && obj['map'] && obj.map.isLoaded())
	{
		var map = obj.map;
		var $container = $( map.getContainer() );
	}
	else
	{
		return false;
	}
	
	// create an overlay window for the map
	var win = new nri.ui.Window(
			{
				destroyOnClose:true				
			}
	);
	
	var tofs = $container.offset();
	
	// insert a placeholder and move the map to the overlay window
	var orig_width = $container.width();
	var orig_height = $container.height();
	
	// put map back where it belongs when window closes
	win.$el.bind('nriWidgetHide',
		function(e)
		{
				$container.width(orig_width).height(orig_height);
				
				obj.change('widthchange',-1,orig_width);
				obj.change('heightchange',-1,orig_height);
				obj.change('move',-1);
				
				$('#' + $container[0].id + '-stub').replaceWith($container);
		}
	);
	
	win.$el.bind('nriWidgetResize',
			function(e)
			{
				$container.width( win.$el.width() ).height( win.$el.height() );
				obj.change('widthchange',-1,win.$el.width());
				obj.change('heightchange',-1,win.$el.height());
				obj.change('move',-1);
			}
	);
	
	
	win.$el.bind('nriWidgetMove',
			function(e)
			{
				obj.change('move',-1);
			}
	);
	
	var stub = '<div id="' + $container[0].id + '-stub' + '" style="background:#CCC;width:'+orig_width+'px;height:'+orig_height+'px"></div>';
	
	$container.width( win.$el.width() ).height( win.$el.height() );	
	
	$container.before(stub).appendTo( win.$body );
	
	win.open();

	obj.change('widthchange',-1,win.$el.width());
	obj.change('heightchange',-1,win.$el.height());	
	obj.change('move',-1);
}

nri.gmap.recenter = function(mapid,latitude,longitude,zoom)
{
	var obj = Drupal.gmap.getMap(mapid);	
	
	if (obj && obj['map'])
	{
		obj.vars.latitude = latitude;
		obj.vars.longitude = longitude;
		obj.vars.zoom = zoom ? zoom : obj.vars.zoom;
		
		if (obj.map.isLoaded())
		{
			if (zoom) obj.change('zoom',-1);
			obj.change('move',-1);
		}
	}
}
