/* ==================================================== *
 * TITLE   : COMMON JAVASCRIPT   |  common.js           *
 * ==================================================== */

/*=========*
 * HELPERS *
 *=========*/

/**
 * Escape for use in a javascript string literal.
 */
function addslashes(str)
{
	return str.replace(/\\/g, '\\\\')
	          .replace(/'/g, '\\\'')
	          .replace(/"/g, '\\\"')
	          .replace(/\x0/g, '\\0')
	          .replace(/\n/g, '\\n')
	          .replace(/\r/g, '\\r')
}

/* ==================================================== *
 * EXTERNAL POPUP
 * ==================================================== */

var poppedWin = null;

/**
 * Call like this: ...onclick="return !NewWindow(this.href, {'height': 600, 'scrollable': 'no'})"...
 * @return  true if popup succeeded
 */
function NewWindow(url)
{
	//retrofit for old calls
	if(arguments.length === 5)
	{
		opts =
		{
			'winLabel': arguments[1],
			'width': arguments[2],
			'height': arguments[3],
			'scrollable': arguments[4]
		};
	}
	else if(arguments.length === 2)
	{
		opts = arguments[1];
	}
	else
	{
		opts = {};
	}

	//gather requirements
	var winLabel = opts['winLabel'] || '_blank';
	var width = opts['width'] || 400;
	var height = opts['height'] || 450;
	var scrollable = opts['scrollable'] || 'yes';
	var resizable = opts['resizable'] || 'yes';
	var stripped = opts['stripped'] || 'almost'; // 'yes', 'no', or 'almost'

	//compute settigns
	var leftPosition = (screen.width) ? (screen.width-width)/2 : 0;
	var topPosition = (screen.height) ? (screen.height-height)/2 : 0;
	var chromeSettings = (stripped === 'yes' ? ',toolbar=no,location=no,directories=no,status=yes,menubar=no' : stripped === 'almost' ? ',toolbar=no,location=yes,directories=no,status=yes,menubar=no' : ',toolbar=yes,location=yes,directories=yes,status=yes,menubar=yes');

	//pop that window
	settings = 'height='+height+',width='+width+',top='+topPosition+',left='+leftPosition+',scrollbars='+scrollable+',resizable='+resizable + chromeSettings;
	poppedWin = window.open(url, winLabel, settings);

	//focus if necessary
	if(poppedWin)
		poppedWin.focus();//just in case we are replacing a backgrounded popup

/*
	//adjust for scrollbars, if necessary and possible
	$(poppedWin).load(function()
	{
		if(poppedWin.closed)
			return;

		var addWidth = poppedWin.innerWidth - width;
		var addHeight = poppedWin.innerHeight - height;
	});
*/

	return !!poppedWin;// so we can say onclick="return !NewWindow(...)"
}

/**
 * Backwards compatibility. See global.js.
 */
function sizedWindow(url, width, height)
{
	NewWindow(url, {'width':width, 'height':height, 'stripped':'yes', 'scrollable':'yes', 'resizable':'yes'});
}

/**
 * Backwards compatibility. See global.js.
 */
function fixedSizedWindow(url, width, height)
{
	NewWindow(url, {'width':width, 'height':height, 'stripped':'yes', 'scrollable':'yes', 'resizable':'no'});
}

/**
 * Backwards compatibility. See global.js.
 */
function dictWindow(term, group)
{
	var url = "http://" + window.location.hostname + "/cgi-bin/glossary.asp?term=" + term + "&group=" + group;
	NewWindow(url, {'width':400, 'height':250, 'winLabel':'dictionary', 'stripped':'yes', 'scrollable':'yes', 'resizable':'yes'});
}


/**
 * Call like this: ...onclick="return !loadInParent(this.href, true)"...
 * @return  true if popup succeeded
 */
function loadInParent(url, closeSelf)
{

	if(self.opener)
	{
		self.opener.location = url;
		if(closeSelf)
			self.close();
		return true;
	}
	else // on the slight chance that this is called from a non-popup, open link normally
	{
		return false;
	}
}

/**
 * This function loads the URL in the current popup window and then 
 * resizes the window to the max screen size.
*/
function loadInWindow(url, width, height)
{
	if(self.opener)
	{
	    self.location = url;
	    self.moveTo(0,0); // top right corner
	    self.resizeTo(width, height);
		return true;
	}
	else // on the slight chance that this is called from a non-popup, open link normally
	{
		return false;
	}
}


/*========================*
 * CLIENT-SIDE VALIDATION *
 *========================*/

/**
 * Reject obviously invalid email addresses. Does not allow TLD-less domains, such as localhost.
 */
function IsEmailValid(str)
{
	return /^[^@\s]+@([0-9a-z-]+\.)+[0-9a-z-]+$/i.test(str);
}




/*=============*
 * FLASH VIDEO *
 *=============*/

function MM_CheckFlashVersion(reqVerStr,msg){
  with(navigator){
    var isIE  = (appVersion.indexOf("MSIE") != -1 && userAgent.indexOf("Opera") == -1);
    var isWin = (appVersion.toLowerCase().indexOf("win") != -1);
    if (!isIE || !isWin){
      var flashVer = -1;
      if (plugins && plugins.length > 0){
        var desc = plugins["Shockwave Flash"] ? plugins["Shockwave Flash"].description : "";
        desc = plugins["Shockwave Flash 2.0"] ? plugins["Shockwave Flash 2.0"].description : desc;
        if (desc == "") flashVer = -1;
        else{
          var descArr = desc.split(" ");
          var tempArrMajor = descArr[2].split(".");
          var verMajor = tempArrMajor[0];
          var tempArrMinor = (descArr[3] != "") ? descArr[3].split("r") : descArr[4].split("r");
          var verMinor = (tempArrMinor[1] > 0) ? tempArrMinor[1] : 0;
          flashVer =  parseFloat(verMajor + "." + verMinor);
        }
      }
      // WebTV has Flash Player 4 or lower -- too low for video
      else if (userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 4.0;

      var verArr = reqVerStr.split(",");
      var reqVer = parseFloat(verArr[0] + "." + verArr[2]);

      if (flashVer < reqVer){
        if (confirm(msg))
          window.location = "http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash";
      }
    }
  }
}


/*===================================*
 * Late loading for quicktime movies *
 *===================================*/

var re_tagExCC_end = /^<\!\[endif\]-->/i;
var re_tagExCC_begin = /$<\!--\[if IE\]>/i;

/**
 * Bypass IE's ugly restrictions on certain types of active content by loading it dynamically.
 * Whatever needs to be loaded dynamically can be put in a <noscript class="active-content-embed"> block,
 * and this function will drop it into the DOM (after the rest of the onDomReady stuff has been called.)
 *
 * Since Safari can't look inside <noscript> elements, use this:
 * <!--[if IE]><noscript class="active-content-embed"><![endif]-->
 *   ... object and embed code ...
 * <!--[if IE]></noscript><![endif]-->
 */
function lateLoadActiveContent(i)
{
	$(this).before(this.innerHTML.replace(re_tagExCC_end, '').replace(re_tagExCC_begin, '')).remove();
}


var re_ac_objects_start = /^.+<object.+<object/;
var re_ac_objects_end = /<\/object>.*<\/object>.+$/;
var re_unfriendly_whitespace = /[\r\n\t\v\f]/g;
var re_trimmable_whitespace = /^\s+|\s+$/g;

/**
 * Version 2 allows fallback content. Contains special instructions for IE6.
 * Here's the expected markup:
 *
 * <!--[if IE]><noscript class="active-content-embed-v2"><![endif]-->
 * 	<object data="..." type="application/x-shockwave-flash" class="W3C">
 * 		<param name="FlashVars" value="..." />
 *
 * 		<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" class="IE">
 * 			<param name="movie" value="..." />
 * 			<param name="FlashVars" value="..." />
 *
 * 			You appear to not have Adobe Flashplayer installed.
 *
 * 		</object>
 * 	</object>
 * <!--[if IE]></noscript><![endif]-->
 *
 * You'll also need a style that to hide stuff from IE6, included by conditional comments:
 *
 *   noscript.active-content-embed-v2 object.W3C { display: none; }
 *
 */
function lateLoadActiveContentV2(i)
{
	var newContent = this.innerHTML;

	if(newContent.indexOf('[if IE]') !== -1) // for IE6, since IE7 strips the outer object
	{
		newContent = newContent.replace(re_unfriendly_whitespace, ' ') // newlines wreak havoc with regexes
		                       .replace(re_ac_objects_start, '<object')
		                       .replace(re_ac_objects_end, '</object>');
	}
	else // others should at least trim the string
	{
		newContent = newContent.replace(re_trimmable_whitespace, ''); // trim
	}

	$(this).before(newContent).remove();
}


/*===========================*
 * Flyout and dropdown menus *
 *===========================*/

var MENU_COUNTER = 1;

function loadMenu()
{
	if(this.id == 'dynamicMenu') {
		$('> ul > li', this).remove();

		var ul = $('<ul></ul>');
		var t = MENU_COUNTER + 10;
		for(; MENU_COUNTER < t; MENU_COUNTER++)
		{
			$('> ul', this).append('<li>Item ' + MENU_COUNTER + '</li>');
		}
	}
}

function unloadMenu()
{
	if(MENU_COUNTER >= 30)
		MENU_COUNTER = 1;
}


/*============*
 * PRINT PAGE *
 *============*/

/**
 * Switch stylesheets to preview print styles.
 * When the stylesheets have loaded, a print dialog appears.
 */
function printThisPage($)
{
	//start loading preview print styles
	var sheetsLoading = 0;
	var doneSwitching = false;
	$('link[rel="stylesheet"]').each(function()
	{
		$(this).load(sheetLoaded);

		this.href += (this.href.indexOf('?') === -1 ? '?' : '&') + 'EmulatePrintable=yes';
		sheetsLoading++;
	});
	doneSwitching = true;

	//called each time a stylesheet loads (only in IE, due to FF bug)
	function sheetLoaded()
	{
		sheetsLoading--;

		if(doneSwitching === true && sheetsLoading === 0)
			window.print();
	}
}

/*  new functions go here ^ */


/*=======================*
 * Functions to call  /\ *
 *=======================*
 * Calls to functions \/ *
 *=======================*/
jQuery(document).ready(function($)
{
	if($([]).jdMenu)
	{
		$('ul.jd_menu').jdMenu({onShow: loadMenu, onHide: unloadMenu});
		$('ul.jd_menu_vertical').jdMenu({onShow: loadMenu, onHide: unloadMenu});
	}

	//late-load quicktime/flash/WMV movies, since IE insists they must load completely before DOM-ready is called o\__/o
	$('noscript.active-content-embed-v2').each(lateLoadActiveContentV2);
	$('noscript.active-content-embed').each(lateLoadActiveContent);

    //IE background image flicker fix
    if($.browser.msie)
    {
        try { document.execCommand("BackgroundImageCache", false, true); }
	    catch(err) {}
    };

    //print this page
    if(/(\?|&)pp=T(&|$)/i.test(document.location.search)) // look for pp=T in the URL
		printThisPage($);
});



/*=======================*
 * for drop down menus
 *=======================*/


jQuery(document).ready(function($)
{
	function makeHoverOn()
	{
		$(this).addClass('hover');
	};
	function makeHoverOff()
	{
		$(this).removeClass('hover');
	};
	$('.subtabs').children().hover(makeHoverOn, makeHoverOff);
});
