var $misc = true;

function checkIfInFrame(){
	try{
		if (parent.frames.length != 0) {
			var l = location.search;
			isFramed = true;
		};
		var qs = new Querystring()
		
		if( qs.get('dynamic') ){
			isDynamic = true;
		}
	}
	catch(e){
		$.iLogger.log(e.name + ': ' + e.message, 'error', 'checkIfInFrame();');
	};
};

doHashForFrame = function(id){
	$.iLogger.log('doHashForFrame('+id+');');
	try{
		if( id != '' ){
			loadXml(framedXmlUrl, 0, function(){buildHashForFrame(id)});
		};	
	}
	catch(e){
		$.iLogger.log(e.name + ': ' + e.message, 'error', 'doHashForFrame();');
	};
};

buildHashForFrame = function(id){
	$.iLogger.log('buildHashForFrame('+id+');');
	try{
		if( id != '' ){
			var page = $('page[database-id="'+id+'"]', docXML[0]);
			var pagesParent = page.parent();
			var pages = pagesParent.children();
			var topic = pagesParent.parent();
			var topicParent = topic.parent();
			var topicChildren = topicParent.children();
			var lesson = topicParent.parent();
			var lessonParent = lesson.parent();
			var lessonChildren = lessonParent.children();
			var module = lessonParent.parent();
			var mid = module.attr('id');
			var moduleParent = module.parent();
			
			var pageIndex = pages.index(page);
			var topicIndex = topicChildren.index(topic);
			var lessonIndex = lessonChildren.index(lesson);
			
			location.hash = Array('m', mid, lessonIndex, topicIndex, pageIndex).join('-');
			$MODULEID = mid;
		};	
	}
	catch(e){
		$.iLogger.log(e.name + ': ' + e.message, 'error', 'buildHashForFrame();');
	};
};

function sendToParentFrame(url){	
	try{
		if(isFramed){
			if( url.split('?').length > 1 ){
				url = url.split('?')[1];
			};
			parent.location.search = url;
		};
	}
	catch(e){
		$.iLogger.log(e.name + ': ' + e.message, 'error', 'sendToParentFrame();');
	};
};
/**
 * @name customAfterContentisLoaded
 * @example customAfterContentisLoaded(this);
 * @desc this function is a called after the content is loaded and is passed
 *	
	a jQuery object so that you can run custom functions against $this
 */
customAfterContentisLoaded = function($this){
	if(!isFramed && !isDynamic){
		fixImagePaths($this);
	}
	checkSetModal($this);
	checkSetNewWindow($this);
	
	checkSetGlosseryTerms($this);
	
	inlineQuizCorrectInCorrect($this);
	
	checkSetInlineTestQuestion($this);
	
	checkSetImageMap($this);
	
	inlineSpecific($this);
	
	swapit($this);

};


fixImagePaths = function( html ){
	try{
	var img = $('img', html);

	var l = location;
	h = l.hostname;
	l = l.href.split('/')
	l.pop();
	
	img.each(function(){
		var el = this;
		var src = $(this).attr('src');
		src = 'common' + src.split('common')[1];
		$(this).attr('src', src);
	});
	}
	catch(e){
		alert(e.name + ': ' + e.message, 'error', 'getLastObjectPosition();');
	};
};




getLastObjectPosition = function(obj){
	$.iLogger.log('getLastObjectPosition('+obj+');');
	try{
		var a;
		for(var i in obj){
			if({ }.hasOwnProperty.call(obj, i)){
				if(i == 'toJSONString') break;
				a = i;
			}
		}
		return a;
	}
	catch(e){
		$.iLogger.log(e.name + ': ' + e.message, 'error', 'getLastObjectPosition();');
	};
}

sortNumber = function(a,b){return a - b};

function array_diff (array) { 
    var arr_dif = [], i = 1, argc = arguments.length, argv = arguments, key, key_c, found=false, cntr=0;
 
    // loop through 1st array
    for ( key in array ){
        // loop over other arrays
        for (i = 1; i< argc; i++){
            // find in the compare array
            found = false;
            for (key_c in argv[i]) {
                if (argv[i][key_c] == array[key]) {
                    found = true;
                    break;
                }
            }
 
            if(!found){
                //arr_dif[key] = array[key];
                arr_dif[cntr] = array[key];
                cntr++;
            }
        }
    }
 
    return arr_dif;
}

array_same = function(ar1, ar2){
	if(typeof ar1 != 'object' || typeof ar2 != 'object'){return false;};
	var tagged = Array();
	ar1.sort(sortNumber);
	ar2.sort(sortNumber);
	if(ar1.length > ar2.length){
		for(var x in ar1){
			if(checkArraySimple(ar1[x], ar2)){
				tagged.push(ar1[x]);
			};
		};
	}
	else{
		for(var x in ar2){
			if(checkArraySimple(ar2[x], ar1)){
				tagged.push(ar2[x]);
			};
		};
	};
	
	return tagged;
}; // end : array_same

/*
 * @example
 * loadXml('common/txt/text.xml', 0);
 * @desc loads an xml file with full path and index number that is 
 * 		inserted into the doc variable like docXML[0] = returned xml;
 *
 * @name loadXml
 * @type function
 * @param String xmlFile
 * @param Integer index
 * @param Function finc
 */
loadXml = function(xmlFile, index, func){
	$.iLogger.log('loadXml('+xmlFile+', '+index+');');
	try{
		if( typeof docXML[index] == "undefined" ){
			$.ajax({
				url: xmlFile,
				async: false,
				dataType: ($.browser.msie) ? "text" : "xml",
				success: function () {
					var xml;
					if (typeof arguments[0] == 'string') {
						xml = new ActiveXObject("Microsoft.XMLDOM");
						xml.async = false;
						xml.loadXML(arguments[0]);
					}
					else{
						xml = arguments[0];
					}
					
					if( index === null ){
						docXML[0] = xml;
					}
					else{
						docXML[index] = xml;
					}
					(typeof func == "function") ? func(): '';
				}
			});
		}
		else{
			(typeof func == "function") ? func(): '';
		};
	}
	catch(e){
		$.iLogger.log(e.name + ': ' + e.message, 'error', 'loadXml();');
	}
}
/*
 * @name isArray
 * @example isArray(array)
 */
function isArray(obj) {
	return (obj.constructor.toString().indexOf("Array") != -1);
}

/*
 * @example multipleSizes();
 * @desc if $multipleSizes is true, this function will set the class
 * 		for the body to what ever is set in $800Class if the browser
 *		is below 990 pixels wide
 * @name multipleSizes
 * @type function
 */
multipleSizes = function(){
	if(!$multipleSizes) return false;

	if($(window).width()<990)
		$('body').addClass($800Class);
}

/*
 * @example replaceAll(String str, Object replacements);
 * 			replaceAll( t, [["{[FirstName]}", fname], ['{[FULLNAME]}', fname + ' ' + lname]]  );
 * @returns replaced value
 */
replaceAll = function( str, replacements ) {
    for ( i = 0; i < replacements.length; i++ ) {
        var idx = str.indexOf( replacements[i][0] );
        while ( idx > -1 ) {
            str = str.replace( replacements[i][0], replacements[i][1] );
            idx = str.indexOf( replacements[i][0] );
        }
    }
    return str;
}

/*
 * @example return2br(String dataStr);
 * @returns replaced string
 */
function return2br(dataStr) {
	if(typeof dataStr == 'undefined') return;
	return dataStr.replace(/(\r\n|\r|\n)/g, "<br />");
}

function InStr(strSearch, charSearchFor){
	for (i=0; i < Len(strSearch); i++)
	{
	    if (charSearchFor == Mid(strSearch, i, 1))
	    {
			return i;
	    }
	}
	return -1;
}

function Mid(str, start, len){
	if (start < 0 || len < 0) return "";
	
	var iEnd, iLen = String(str).length;
    
	if (start + len > iLen)
    	iEnd = iLen;
	else
		iEnd = start + len;

	return String(str).substring(start,iEnd);
}

function Len(str){  return String(str).length;  }


function checkArraySimple(needle, haystack){
	for(var i = 0; i < haystack.length; i++)
		if(haystack[i] == needle)
			return true;
	return false;
}

function randomNumber(UpTo){
	var ran_unrounded=Math.random()*UpTo;
	var ran_number=Math.floor(ran_unrounded);	
	
	return ran_number;
}
/**
 * @name checkSetInnerFade
 * @example checkSetInnerFade(this);
 * @desc checks for a group of images that need to be faded in and out
 * @note set default height with h:488 in the class attribute
 *
 *	<div class="fadeImages h:488">
 *		<img src="img/2 mph wind.png" width="450"/>
 *		<img src="img/7 mph wind.png" width="450"/>
 *	</div>
 */
checkSetInnerFade = function($this){
	$('.fadeImages',$this).innerfade({speed: 2000,timeout:3000,type:'sequence'});
}

/**
 * @name checkSetImageMap
 * @example checkSetImageMap(this);
 * @desc checks for an image map and set functionality
 *
 *	<img src="img/015_clip_image001.jpg" alt="map" width="342" height="324" usemap="#Map">
 *	<map name="Map" id="Map"><area shape="rect" coords="152,280,162,293" href="#" alt="hospital" /></map>
 */
checkSetImageMap = function($this){
	var mappedImg = $('img[@usemap]',$this);
	if(mappedImg.size() != 0){
		$('#interactive').show();
		var isOver = false;
		mappedImg.click(function(){
			$('.answer').hide();
			if(!isOver){
				var sTo = $('.r2').show().highlightFade('yellow').offset();
				$bodytext.scrollTop(sTo['top'])
			}
		});
		$('#Map area')
			.hover(
				function(){isOver=true;},
				function(){isOver=false;}
			)
			.click(function(){
				$('.answer').hide();
				var sTo = $('.r1').show().highlightFade('yellow').offset();
				$bodytext.scrollTop(sTo['top']);
				$('#next').show();
				return false;
			});
	};	
};

/**
 * @name checkSetDL
 * @example checkSetDL(this);
 * @desc checks for a DL list and adds a show/hide to them
 *
 *	<dl>
 *		<dt title="Click for more information"><em>Question One:</em> This is question 1?</dt>
 *		<dd>See the quick brown fox jump over the lazy dog</dt>
 *		<dd>More text</dd>
 *	</dl>
 */
checkSetDL = function($this){
	$.iLogger.log('checkSetDL('+$this+');');
	if($('dl', $this).size() == 0) return false;

	$('dl', $this).find('DT')
	.css('cursor','pointer')
	.toggle(function(){
		$(this).addClass('open').removeClass('closed').nextUntil('DT').show();
	},function(){
		$(this).removeClass('open').addClass('closed').nextUntil('DT').hide();
	})
	.hover(function(){
		$(this).addClass('hover');
	},
	function(){
		$(this).removeClass('hover')
	})			
	.addClass('closed')
	.nextUntil('DT')
	.hide();
};

/**
 * @name checkSetPutResponse
 * @example checkSetPutResponse(this);
 * @desc checks for a #putResponse and put the users response.
 * 	<p class="putResponse" title="responseTXTOne"></p>
*/
checkSetPutResponse = function($this){
	if($('#putResponse', $this).size() != 0){
		place = $('#putResponse', $this).attr('title');
		$('#putResponse', $this).removeAttr('title').html(return2br(tempDataArray[place]));
	}
}

/**
 * @name checkSetOptShow
 * @example checkSetOptShow(this);
 * @desc checks for a .optShow and shows that response
 * 	<a href="#" class="optShow" name="r1">[Maria]</a>
 *	<p class="answer r1"></p>
*/
checkSetOptShow = function($this){
	var optShow = $('a.optShow', $this);
	if(optShow.size() != 0){
		$('#interactive').show();
		optShow.click(function(){
			$('.answer').hide();
			var current = $(this).attr('name');
			var sTo = $('.'+current).show().highlightFade('yellow').offset();
			$('.bodytext').scrollTop(sTo['top']);
			return false;
		});
	}
}

/**
 * @name addToInit
 * @example	addToInit();
 * @description To keep the init function as clean as possible, this function
 *				function was created.  Add any new functionality that needs
 *				to be executed at start up to this function.  Remember to 
 *				comment a the begging and end of each piece of code
 */
addToInit = function(){
	$.iLogger.log('addToInit();');
	modalLinks();
}

/**
 * @name customTabs
 * @example	customTabs();
 * @description To keep the setTabzFunctions function as clean as possible, this function
 *				was created.  Add any new functionality that is needed for the tab set
 *				if jqtabs is not set, this function will not get executed
 */
customTabs = function(){
	try{
		$('.a_tab1,.a_tab2,.a_tab3').click(function(){
			var $this = $(this);
			if($this.is('.a_tab1')){
				if(jqtabs.is('.opened') && jqtabs.is('.showTab1'))
					jqtabs.removeClass('opened');
				else
					jqtabs.addClass('opened');

				jqtabs.addClass('showTab1').removeClass('showTab2').removeClass('showTab3');
			}
			
			if($this.is('.a_tab2')){
				if(jqtabs.is('.opened') && jqtabs.is('.showTab2'))
					jqtabs.removeClass('opened');
				else
					jqtabs.addClass('opened');

				jqtabs.addClass('showTab2').removeClass('showTab1').removeClass('showTab3');
			}
			
			if($this.is('.a_tab3')){
				if(jqtabs.is('.opened') && jqtabs.is('.showTab3'))
					jqtabs.removeClass('opened');
				else
					jqtabs.addClass('opened');

				jqtabs.addClass('showTab3').removeClass('showTab1').removeClass('showTab2');
			}
			return false;
		});
		jqtabs.mouseout(function(){
			jqtabs.removeClass('over');
			TO = setTimeout(function(){jqtabs.removeClass('opened');}, 300 )
		})
		.mouseover(function(){
			jqtabs.addClass('over');
			clearTimeout(TO);
		});
	}
	catch(e){
		$.iLogger.log(e.name + ': ' + e.message, 'error', 'setTabzFunctions();');
	}
}

var TO;

/**
 * @name unLoadFunction
 * @example this is place you would set any window unload function
 */
unLoadFunction = function(){}


/**
 * @name customSelectedText
 * @example customSelectedText(mX,lX,tX,pX);
 * @desc This function is to add to custom variables
 * @example  say you add another attribute to the xml doc that you want to
 *			be able to access later
 * @note you must set any new variables in the preset file for these new
 *			to be accessable in other code.
 */
customSelectedText = function(mX,lX,tX,pX){};



closeTrigger = function(){
	$.iLogger.log('closeTrigger();');
	$('.jqmClose').click();
}

callFromSimTest = function(simName, simStatus, simScore){
	$.iLogger.log('callFromSimTest(simName='+simName+', simStatus='+simStatus+', simScore='+simScore+');');
	try{
		var m = location.hash.replace(/^.*#/, '').split('-');
		var mX = getJustModulePath(m[1]);
		var lX = getJustLessonPath(m[2]);
		var tX = getJustTopicPath(m[3]);
		var pX = getJustPagePath(m[4]);
		var pagename = $(mX+lX+tX+pX, docXML[0]).attr('name')					
		if($sitedata.lessonLevel[$locationMarker]['sInlineQuiz'] != ''){$sitedata.lessonLevel[$locationMarker]['sInlineQuiz'] += ',';}
		$sitedata.lessonLevel[$locationMarker]['sInlineQuiz'] += pagename;
		getData();
		if(simStatus=='complete')$('#next').show();
	}
	catch(e){
		$.iLogger.log(e.name + ': ' + e.message, 'error', 'callFromSimTest();');
	};	
}


modalLinks = function(){
	$('a.modal').click(function(){
		buildDialogBox({
			u: $(this).attr('href'),
			m : false,
			title: $(this).attr('title')
		});
		return false;
	});
};



function NewWindow(mypage,myname,w,h,scroll,pos){
	if(pos=="random"){
		LeftPosition=(screen.width)?Math.floor(Math.random()*(screen.width-w)):100;TopPosition=(screen.height)?Math.floor(Math.random()*((screen.height-h)-75)):100;
	}
	if(pos=="center"){
		LeftPosition=(screen.width)?(screen.width-w)/2:100;TopPosition=(screen.height)?(screen.height-h)/2:100;
	}
	else if((pos!="center" && pos!="random") || pos==null){
		LeftPosition=0;
		TopPosition=20;
	}
	settings='width='+w+',height='+h+',top='+TopPosition+',left='+LeftPosition+',scrollbars='+scroll+',location=no,directories=no,status=no,menubar=no,toolbar=no,resizable=no';
	win=window.open(mypage,myname,settings);
}

 /*
 * @example
 * buildDialogBox({m:false, f:aFunction});
 * @desc builds a dialog box
 *
 * @name buildDialogBox
 * @type function
 * @param String u // u is the view name you want to pull in
 * @param String d // d is the style of the dialog box, check 
 * stylesheet for styles
 * @param String h // h is the holder, this would only need to
 * be if you are doing to or more boxes at the same time.
 * @param Function f // f is/are the function(s) that you are passing
 * to the buildDialogBox function and that will be executed
 * when/after the dialog box is loaded.
 * @param Int o // o to set the transparency of the overlay
 * @param Boolean m // m set it to make the background unclickable,
 * set to false to set background to close dialog box on click
 */

buildDialogBox = function(options){
	var defaults = {
		u	: "dummy",
		d	: "jqmWindow",
		h	: "theDialog",
		m	: true,
		f	: null,
		o	: 50,
		z	: 3000,
		title: null
	}
	var o = $.extend(defaults,options);
	
	$('#'+o.h).remove();
	var strUrl;
		strUrl = o.u;
	$('body').append($.DIV({'id':o.h, 'class':o.d},
								$.DIV({}, $.DIV({}, o.title).addClass('title'),$.DIV({}, '<a href="#" class="jqmClose">close</a>').addClass('jqmCloseDiv')).addClass('head'),
								'<div class="legend"><div class="hold"><div class="left">&nbsp;</div><div class="center"></div><div class="right">&nbsp;</div></div></div>',
								$('<iframe width="536" height="300" frameborder="0" id="dtarget" allowtransparency="1" marginheight="0" marginwidth="0"/>').attr('src',strUrl)
							));
				
	$('#'+o.h).jqm({zIndex:o.z,modal:o.m,overlay:o.o,target:'#dtarget',
		onHide: function(hash, serial){
			hash.o.remove();
			hash.w.remove();
		},
		onLoad: function(){
			if(typeof o.f == 'function'){
				o.f();
			}
		}
	}).jqmShow(); 
}

addToRunExit = function(){
	$.iLogger.log('addToRunExit();');
	try{
		/* add exit code */
	}
	catch(e){
		$.iLogger.log(e.name + ': ' + e.message, 'error', 'addToRunExit();');
	};
};

addToRunIsCompleted = function(){
	$.iLogger.log('addToRunIsCompleted();');
	try{
		/* add addToRunIsCompleted code */
	}
	catch(e){
		$.iLogger.log(e.name + ': ' + e.message, 'error', 'addToRunIsCompleted();');
	};
};

addToRunRestictDomainCode = function(){
	$.iLogger.log('addToRunRestictDomainCode();');
	try{
		/* add addToRunRestictDomainCode code */
		$('body').empty();
		alert('Sorry, this course is limited to the '+domainToRestrictTo+' domain');
	}
	catch(e){
		$.iLogger.log(e.name + ': ' + e.message, 'error', 'addToRunRestictDomainCode();');
	};
};


/**********************************************************
 *		
 *********************************************************/
 
doTopicLabel = function(num, name){
	try{
		jqtopicName.text(name);
	}
	catch(e){};
};

getPagesPath = function(moduleRef, lessonRef, topicRef){
	return 'modules/'+moduleRef+'/'+lessonRef+'/'+topicRef+'/pages/';
};

/**
 *
 */
runDoComplete = function(){
	try{
		doComplete();
	}catch(e){
		$.iLogger.log(e.name + ': ' + e.message, 'error', 'runDoComplete();');
	};
};
 
/**********************************************************
 *		
 *********************************************************/
 
checkAndClose = function(){
	try{
		if( typeof wbt.jqGlossaryTerm != 'undefined' &&  wbt.jqGlossaryTerm ){
			window.jqGlossaryTerm.hide();
		};
		if( typeof wbt.checkSetModal != 'undefined' &&  wbt.checkSetModal ){
			$('#footerBtns a').each(function(){
				this.dialog = null;
			});
			$.each(wbt.checkSetModal.dialog, function(i){
				$(this).dialog('destroy').remove();
			});
		};
		
	}catch(e){
		$.iLogger.log(e.name + ': ' + e.message, 'error', 'checkAndClose();');
	};
};

$.fn.fixPNG = function() {
	if( $.browser.msie && $.browser.version < 7 ){
		return this.each(function () {
			var image = $(this).css('backgroundImage');
			if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {
				image = RegExp.$1;
				$(this).css({
					'backgroundImage': 'none',
					'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
				})
			}
		});
	};
}

function array_diff (array) {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Sanjoy Roy
    // *     example 1: array_diff(['Kevin', 'van', 'Zonneveld'], ['van', 'Zonneveld']);
    // *     returns 1: ['Kevin']
 
    var arr_dif = [], i = 1, argc = arguments.length, argv = arguments, key, key_c, found=false, cntr=0;
 
    // loop through 1st array
    for ( key in array ){
        // loop over other arrays
        for (i = 1; i< argc; i++){
            // find in the compare array
            found = false;
            for (key_c in argv[i]) {
                if (argv[i][key_c] == array[key]) {
                    found = true;
                    break;
                }
            }
 
            if(!found){
                //arr_dif[key] = array[key];
                arr_dif[cntr] = array[key];
                cntr++;
            }
        }
    }
 
    return arr_dif;
}


function Querystring(qs) { // optionally pass a querystring to parse
	this.params = {};
	
	if (qs == null) qs = location.search.substring(1, location.search.length);
	if (qs.length == 0) return;

// Turn <plus> back to <space>
// See: http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4.1
	qs = qs.replace(/\+/g, ' ');
	var args = qs.split('&'); // parse out name/value pairs separated via &
	
// split out each name=value pair
	for (var i = 0; i < args.length; i++) {
		var pair = args[i].split('=');
		var name = decodeURIComponent(pair[0]);
		
		var value = (pair.length==2)
			? decodeURIComponent(pair[1])
			: name;
		
		this.params[name] = value;
	}
}

Querystring.prototype.get = function(key, default_) {
	var value = this.params[key];
	return (value != null) ? value : default_;
}

Querystring.prototype.contains = function(key) {
	var value = this.params[key];
	return (value != null);
}