///////////////  the Case class - represents a single case  /////////////////////
//Define a single test case
function Case(name){
	this.caseName  = name;
	this.toDisplay = new Array();	//array of pairs [displayAreaName, contentName] - content will be written in the area designated
	this.toTarget = new Array();	// array  [targetDiv, contentName. loadFlag] - content of div id='targetDiv' will be replaced by content from source 'contentName'.  Upon content load, loadFlag will be set to true
	this.toTrack = new Array();		//array of id's of divs to track: [id1, id2, id3,...]
	this.toTrackNames = new Array();	//array of numan readable names to match divs in 'toTrack'
	this.showLoad = false;		//if true, on load, track loads
	this.showSelect = false;		//if true, show case selection (coookies only)
	this.trackingBase = "";		//click tracking url
	this.loadURL = "";	//url to show page  has loaded
	this.caseSelectURL = "";	//tracking URL for case selection
	this.displayWeight = 1;		//weighting for how  frequently this case wll be displayed
	this.preContent = ""; //content that will be displayed with this case before init block - unlike other settings in which the setting in Case overrides the argument in Cases, this operates independently
	//this.postContent = "";//content that will be displayed with this case after init block
}

//Add a region to track clicks on
Case.prototype.addClickDiv = function(divs)
{
	divs = divs.replace(/\s/g, "");
	this.toTrack  = divs.split(/\,/g);
	for(toTracki=0;toTracki<this.toTrack.length;toTracki++){
		if(this.toTrack[toTracki].search(/(.+)\:(.+)/) != -1){// a  div name can optionally be followed by a ':' + label, where the label is a humanly readable name for that  div which will appear in the tracking
			this.toTrackNames[toTracki] = this.toTrack[toTracki].replace(/(.+)\:(.+)/, "$2");
			this.toTrack[toTracki] = this.toTrack[toTracki].replace(/(.+)\:(.+)/, "$1");
		}
		else{
			this.toTrackNames[toTracki] = this.toTrack[toTracki];// if no label given, use  div name as label
		}
	}
	//alert(this.toTrack[0]+"+"+this.toTrack[1]);
}

//Add a container to assign content to
Case.prototype.addDisplay = function(contentName,contentPiece)
{
	var displayPart = new Array(contentName,contentPiece);
	this.toDisplay.push(displayPart);
}

//Add an existing div to assign content to
Case.prototype.addTarget = function(targetDiv,contentPiece)
{
	var displayPart = new Array(targetDiv,contentPiece,false);//array[target div in which to put content, content to put there, loadflag=true if content already loaded, else fale]
	this.toTarget.push(displayPart);
}

//sets flag to show tracking URL on page load. showFlag=true/false
Case.prototype.addLoadLister = function(showFlag)
{
	this.showLoad = showFlag;
}

/////////////////////  The Cases Class - a collection of cases, along with glabal parameters for the test ///////////////
//A collection of all test cases
function Cases(testName,trackingBase){
	this.testName = testName;
	this.trackingBase = trackingBase;//base url for click tracking with default function
	this.loadURL = trackingBase;	//url to show page  has loaded
	this.trackingAppend = "mi_tester_force_case=@case_num#";	//tracking into  to append to URLs, as opposed to that which would be used in the default function
	this.appendTo = "no_cookie";		//who to append tracking to: "" = nobody, "all" everybody, "no_cookie"= only people without cookies
	this.trackNoCookies = true;		//true: track people with cookies  disabled, false: don't track them 
	this.theCase = new Array();
	this.caseNum = 0;
	this.contentPieces = new Array();	//associative array by content name, see function addContent: ['loc'] - location of content, ['type'] ='comp'/'url' - content type, ['divID'] - div id, ['code'] - div code that would be written with this
	this.caseSelectionType = 'page';//method of choosing which case - 'page' = selects case on page by page basis, 'cookie' selects case on cookie value
	this.cookieExpiration = 180;//expiration time in minutes
	this.cookiesEnabled = true;
	this.cookieDomain = "";
	this.overrideURLs = new Array();//array of URL regex mmatches that will trigger a particular case
	this.caseSelectURL = "";	//tracking URL for case selection
	this.onOff = 'on';				//gobal on/off switch	
	this.defaultDisplayWeight = 0;			//display weight for default content
	//this.defaultCase = 0;
	this.trackingAlertMode = false;	//if true, tracking will be turned off and alerts will show with tracking urls that would have been sent
	//this.altClickStr = "";	//format of custom alternative tracking string, if any
	this.altClickFunction  = "";	//name of custom alternative tracking function to use
	this.altTracking = "off";		//'on'=use  custom tracking, 'off'= use build in tracking
	this.errorMsg = "";			//data member which holds any errors
	this.errorOut = "";			//format for errors to be appended to tracking - contents of errorMsg will be inserted at &error=@error#
}


//returns true if test is on
Cases.prototype.isOff = function()
{
	if(this.onOff.search(/off/i) != -1){return true;}
	return false;
}

//add a content piece to the test object
Cases.prototype.addContent = function()
{
	//var displayPart = new Array(div,url);
	var displayPart = new Array();
	var contentName = this.addContent.arguments[0];
	var contentLocation = this.addContent.arguments[1];
	var divCode = '';
	if(this.addContent.arguments.length > 2){divCode = this.addContent.arguments[1];}
	contentName = contentName.replace(/([^A-Za-z_0-9]|\s)/gi, "");
	//displayPart['name'] = contentName;
	displayPart['loc'] = contentLocation;
	if(contentLocation.search(/\.comp$/) != -1){
		displayPart['type'] = 'comp';
	}
	else{
		displayPart['type'] = 'url';
	}
	if(divCode != ''){//if they supplied div code, extract the id
		if(divCode.search(/\sid=['"].+?["']/i) == -1){
			displayPart['divID'] = divCode.replace(/.+\sid=['"](.+?)["'].+/i, "$1");
		}
		else{this.errorMsg += "Bad div code:"+contentName+"|";}
	}
	else{//else generate our own div id
		displayPart['divID'] = contentName;//= "mi_tester_"+contentName;
	}
	
	if(divCode != ''){
		displayPart['code'] = divCode;
	}
	else{displayPart['code'] = '<div id="'+displayPart['divID']+'">';}
	
	this.contentPieces[contentName] = displayPart;
}

//given a case name, return the number
Cases.prototype.caseName2num = function(casename)
{
	for (i=0;i<this.theCase.length;i++){
		if(this.theCase[i].caseName == casename){return i;}
	}
}

//given a case number, return the name
Cases.prototype.caseNum2name = function(theNum)
{
	return this.theCase[i].caseName;
}

//choose which case to display
Cases.prototype.chooseCase = function()
{
	var numCases = this.theCase.length;//numCases = the numbe rof cases to choose from
	var chosenCase = 0;
	var trackSelectFlag = false;
	
	var forcedCase = this.findForcedCase(document.location.href);//see if we have a manually foreced case
	if(this.isOff()){//if test is turned off, use default content
		chosenCase = 0;
	}
	else if(forcedCase > -1){
		chosenCase = forcedCase;
	} 
	else if(this.caseSelectionType == 'cookie'){//choose case based on cookie value
		var theCookie = this.getCookie();
		if(theCookie == ""){//no cookie value so far, so set one
			chosenCase = this.generateCaseNum();
			this.setCookie(chosenCase);
			var cookieVal = this.getCookie();
			if(cookieVal == ""){//check to see if cookies are enabled
				this.cookiesEnabled = false;
			}
			else{
				if(this.theCase[chosenCase].showSelect){//track case selection if requested
					trackSelectFlag = true;
				}
			}
		}
		else{
			chosenCase = this.getCookie();
		}
	}
	else{	//choose case on page load
		chosenCase = this.generateCaseNum();
	}
	
	this.caseNum = chosenCase;
//	if(this.showLoad){
//		this.showPageLoad();alert("show page load from chooseCase");
//	}
	if(trackSelectFlag){
		this.showCaseSelection();
	}
	return this.caseNum;
}


//generate a random case number,  with weighting
Cases.prototype.generateCaseNum = function()
{	
	var totalWeight = 0;
	for(var i_cases = 0;i_cases < this.theCase.length;i_cases++){
		totalWeight += this.theCase[i_cases].displayWeight;//document.write("<br>i_cases:"+i_cases+"|this.theCase[i_cases].displayWeight:"+this.theCase[i_cases].displayWeight+"|");
	}
	var randSelect = Math.random()*totalWeight;
	var cumulativeWeight = 0;//document.write("<br>randSelect:"+randSelect+"|totalWeight:"+totalWeight+"|");
	for(i_cases = 0;i_cases < this.theCase.length;i_cases++){//this was correct before default cases were added
		cumulativeWeight += this.theCase[i_cases].displayWeight;//document.write("<br>cumulativeWeight:"+cumulativeWeight+"|");
		if(cumulativeWeight > randSelect){//document.write("returning:"+i_cases+"|");
			return i_cases;
		}
	}
	return 0;//return "default";	//TEMP - UNTIL DEFAULT CASES ARE ACTIVATED
}


//Add a test case to the test object
Cases.prototype.addCase = function(casename)
{
	var newCase = new Case(casename);
	this.theCase.push(newCase);
}

//Add a test case
Cases.prototype.addCase2 = function(newCase)
{
	this.theCase.push(newCase);
}



//Add a region to track clicks on to the test object
Cases.prototype.addClickDiv = function(casename, divs)
{
	for (i=0;i<this.theCase.length;i++){
		if(this.theCase[i].caseName == casename){break;}
	}
	divs = divs.replace(/\s/g, "");
	this.theCase[i].toTrack  = divs.split(/\,/g);
	
}

//returns true if this div is currently for this case, el returns false
Cases.prototype.isTracked = function(divname, whichCase)
{
	var divs = this.theCase[whichCase].toTrack;
	for (i=0;i<divs.length;i++){
		if(divs[i] == divname){return true;}
	}
	return false;
}

//Add a container to assign content to the test object
Cases.prototype.addDisplay = function(casename, contentName,contentPiece)
{
	for (i=0;i<this.theCase.length;i++){
		if(this.theCase[i].caseName == casename){break;}
	}
	var displayPart = new Array(contentName,contentPiece);
	this.theCase[i].toDisplay.push(displayPart);
}

//sets flag to show tracking URL on page load. showFlag=true/false
Cases.prototype.addLoadLister = function(casename, showFlag)
{
	for (i=0;i<this.theCase.length;i++){
		if(this.theCase[i].caseName == casename){break;}
	}
	this.theCase[i].showLoad = showFlag;
}

//get tracking url when page is loaded, if case requests it
Cases.prototype.showPageLoad = function()
{
	if(this.theCase[this.caseNum].showLoad){
		var getURL = this.makeLoadURL();
		if(this.trackingAlertMode){alert("Page Load URL: "+getURL);}
		else{$.get(getURL);}
	}
}

//get tracking url when case is selected
Cases.prototype.showCaseSelection = function()
{
	if(this.theCase[this.caseNum].showSelect){
		var getURL = this.makeSelectURL();
		if(this.trackingAlertMode){alert("Case Selection URL: "+getURL);}
		else{$.get(getURL);}
	}
}

//retrieve the URL of content to be loaded into a display area
Cases.prototype.getDisplayLocation = function(displayArea)
{
	var divs = this.theCase[this.caseNum].toDisplay;
	var theContent = '';
	for (i=0;i<divs.length;i++){
		if(divs[i][0] == displayArea){//if this matches the display area
			//return divs[i]['loc'];
			theContent = divs[i][1];//get cntent name
			break;
		}
	}
	return this.contentPieces[theContent]['loc'];
}

//given a content area name, returns which type of content is to be displayed
Cases.prototype.getDisplayType = function(displayArea)
{
	var divs = this.theCase[this.caseNum].toDisplay;
	var theContent = '';
	for (i=0;i<divs.length;i++){
		if(divs[i][0] == displayArea){//if this matches the display area
			theContent = divs[i][1];//get cntent name
			break;
		}
	}
	return this.contentPieces[theContent]['type'];
}

//given a display area name, returns the name of the content piece to display there for the current case
Cases.prototype.getWhichContent = function(displayArea)
{
	var divs = this.theCase[this.caseNum].toDisplay;
	for (i=0;i<divs.length;i++){
		if(divs[i][0] == displayArea){//if this matches the display area
			return divs[i][1];//get content name
		}
	}
	return '';
}


//given a target div id, returns the name of the content piece to display there for the current case
Cases.prototype.getTargetContent = function(targetDiv)
{
	var divs = this.theCase[this.caseNum].toTarget;
	for (var i=0;i<divs.length;i++){
		if(divs[i][0] == targetDiv){//if this matches the display area
			return divs[i][1];//get content name
		}
	}
	return '';
}

//returns true if the target div has already had it's contents loaded
Cases.prototype.targetLoaded = function(targetDiv)
{
	var divs = this.theCase[this.caseNum].toTarget;
	for (var i=0;i<divs.length;i++){
		if(divs[i][0] == targetDiv){//if this matches the display area
			return divs[i][2];//get content name
		}
	}
	return false;
}

//marks a div as loaded
Cases.prototype.markAsLoaded = function(targetDiv)
{
	var divs = this.theCase[this.caseNum].toTarget;
	for (var i=0;i<divs.length;i++){
		if(divs[i][0] == targetDiv){//if this matches the display area
			divs[i][2] = true;
			return;
		}
	}
}

//returns human readable name of current selected case
Cases.prototype.getCaseName = function()
{
	return this.theCase[this.caseNum].caseName;
}

//given a content piece name, returns the hidden div where that source is kept
Cases.prototype.content2sourceDiv = function(contentPiece)
{
	return "mi_testSource_"+contentPiece;
}

//given a display area name, returns piece name, returns the hidden div where that source is kept
//NOT SURE THIS IS STILL VALID 
Cases.prototype.display2sourceDiv = function(theDiv)
{
	return "mi_testSource_"+this.getWhichContent(theDiv);
}

//HTML comments are escaped by template toolkit.  This unescapes them.
Cases.prototype.unescapeHTMLcontent = function(theContent)
{
	theContent = theContent.replace(/<\!\-\-<MI_Test>/g, "");
	theContent = theContent.replace(/<MI_Test>\-\->/g, "");
	theContent = theContent.replace(/=;CommentStart;=/g, "<!--");
	return theContent.replace(/=;CommentEnd;=/g, "-->");
}

//escape stuff inside a hidden div, commented out
Cases.prototype.escapeHTMLContent = function(theContent)
{
	theContent = theContent.replace(/<\!\-\-/g, "=;CommentStart;=");
	theContent = theContent.replace(/\-\->/g, "=;CommentEnd;=");
	return "<!--"+theContent+"-->";
}

//loads div with content from url
Cases.prototype.divLoaderRetry = function(url, div, tries)
{
	if(--tries < 1){return false;}
	try{
		$("#"+div).load(url);
		return true;
	}
	catch(exception){
		divLoader(url, div, tries);
	}
}

//loads div with content from url, retries built in
Cases.prototype.divLoader = function(url, div)
{
	this.divLoaderRetry(url, div,3);
}

//creates div, loads content from URL
Cases.prototype.makeDivAndLoad = function(url, div)
{
	document.write("<div id=\""+div+"\"></div>");
	divLoader(url, div);
}

//sets default name for a div area if we're creating a div
Cases.prototype.contentAreaDivName = function(contentArea)
{
	return this.testName + "_" + contentArea +"_display";
}

//creates div, automatically generating a name for that content area loads content from URL
Cases.prototype.makeContentDiv = function(url, contentArea)
{
	this.makeDivAndLoad(url, this.contentAreaDivName(contentArea));
}

//given a content name, returns content from hidden div.  Handles the all unescaping.
Cases.prototype.getContentFromDiv = function(contentName)
{
	var contentStr = "";
	var sourceDivID = this.content2sourceDiv(contentName);
	var sourceDiv = document.getElementById(sourceDivID); 
	if(sourceDiv != null){
		contentStr = sourceDiv.innerHTML;
		contentStr = this.unescapeHTMLcontent(contentStr);//put back HTML comments that were removed by template toolkit
	}
	else{this.errorMsg += "Content not found:"+contentName+"|";}
	return contentStr;
}

//contentName - name of a piece of content, returns content type ('url' or 'comp')
Cases.prototype.getContentType = function(contentName)
{
	if(this.contentPieces[contentName] != null){
		return this.contentPieces[contentName]['type'];
	}
	return '';
}

//given a display area name, returns what type of content to put there for current case ('url' or 'comp')
Cases.prototype.areaContentType = function(areaName) 
{
	var contentName = this.getWhichContent(areaName);
	return this.getContentType(contentName);
}


//give a content area name, returns content for that content area for the current case
Cases.prototype.getContent = function(contentArea)
{
	var contentStr = "";
	if(this.areaContentType(contentArea)  == 'url'){
		//var contentLocation = this.contentPieces[theContent]['loc'];
		//TO DO: ADD WAY TO GET CONTENT FROM URL AND RETURN IT
		return "";
	}
	else{
		var sourceName = this.getWhichContent(contentArea);
		if(sourceName == "default"){
			contentStr = this.getDefaultContent(contentArea);//display content that was there before the test
		}
		else if(sourceName == ''){//nothing was specified for this content area - human error
			return "";
		}
		else{
			contentStr = this.getContentFromDiv(sourceName);//grab content from one of our cotent sources
		}
	}
	return contentStr;
}

//give a content area, writes out the content.  If content is from hidden div, does a document.write, if from url, document.writes a URL and then loads content from URL
Cases.prototype.writeContent = function(contentArea)
{
	if(this.caseNum == 0){//default case, just write out default content
		var theContent = this.getDefaultContent(contentArea);
		document.write(theContent);
	}
	else if(this.areaContentType(contentArea) == 'url'){//if url, make div and load content
		var contentLocation = this.getDisplayLocation(contentArea);
		this.makeContentDiv(contentLocation, contentArea);
	}
	else{//if stored content from hidden div, just write it
		var theContent = "";
		var sourceName = this.getWhichContent(contentArea);
		if(sourceName == ""){//check against human error: if somebody forgets to specify content, default content will be displayed.
			theContent = this.getDefaultContent(contentArea);
		}
		else{
			theContent = this.getContent(contentArea);
		}
		document.write(theContent);
	}
	if(typeof mitestNeedsLoad != 'undefined'){
		if(mitestNeedsLoad != null){mitestNeedsLoad = false;}
	}
}

//replace the contents of a target div with other contents
Cases.prototype.contentToTarget = function(targetDiv)
{
	//if(this.areaContentType(contentArea) == 'url'){//if url, make div and load content
	if(false){
		//var contentLocation = this.getDisplayLocation(contentArea);
		//this.makeContentDiv(contentLocation, contentArea);
		//CODE HERE TO PULL IN VIA HTTP
	}
	else{//if stored content from hidden div
		if(!this.targetLoaded(targetDiv)){//if not already loaded
			var contentStr = "";
			var sourceName = this.getTargetContent(targetDiv);//which contents is supposed to go in this div?
			//var theContent = this.getContent(contentArea);
			if(sourceName != ""){
				contentStr = this.getContentFromDiv(sourceName);
				var targetDivObj = document.getElementById(targetDiv); 
				if(targetDivObj != null){
					targetDivObj.innerHTML = contentStr;
					this.markAsLoaded(targetDiv);
				}
				else{this.errorMsg += "No target:"+targetDiv+"|";}
			}
		}
	}
}

//replace the contents of all target divs with other contents
Cases.prototype.contentToAllTargets_real = function()
{
	var divs = this.theCase[this.caseNum].toTarget;//loop through targeted divs for this case
	for (var i=0;i<divs.length;i++){
		this.contentToTarget(divs[i][0]);//replace the contents
	}
}

//replace the contents of all target divs with other contents
Cases.prototype.contentToAllTargets = function()
{
	//var divs = this.theCase[this.caseNum].toTarget;//loop through targeted divs for this case
	for (var i=0;i<this.theCase[this.caseNum].toTarget.length;i++){
		this.contentToTarget(this.theCase[this.caseNum].toTarget[i][0]);//replace the contents
	}
}

//gets the default content for a given content area
Cases.prototype.getDefaultContent = function(contentArea)
{
	var sourceDivID = "mi_defaultSource_" + contentArea;
	var sourceDiv = document.getElementById(sourceDivID); 
	var contentStr = "";
	if(sourceDiv != null){
		contentStr = sourceDiv.innerHTML;
		contentStr = this.unescapeHTMLcontent(contentStr);//put back HTML comments that were removed by template toolkit
	}
	else{this.errorMsg += "No default:"+contentArea+"|";}
	return contentStr;
}

//writes case specify content at  beginning of init
Cases.prototype.writePreInit = function()
{
	var contentName = this.theCase[this.caseNum].preContent;
	if(contentName != ""){
		var theContent = this.getContentFromDiv(contentName);
		document.write(theContent);
	}
}


//master display function - this may be obsolete since i think you're breaking it into loaddiv and doc.write functions
Cases.prototype.displayContent = function(contentArea, targetDivID)
{
	var targetDiv = document.getElementById(targetDivID); 
	if(targetDiv != null){
		var theContent = this.getContent(contentArea);
		if(theContent == ""){	//IF CONTENT IS FROM HIDDEN DIV
			targetDiv.innerHTML = this.getContent(contentArea);
		}
		else{//IF CONTENT IS FROM URL
			//GET CONTENT LOCATION
			var sourceName = this.getWhichContent(contentArea);
			var contentLocation = this.contentPieces[sourceName]['loc'];
			$("#"+theDiv).load(contentLocation);
		}
	}
	else{this.errorMsg += "Target not found:"+targetDiv+"|";}
}


//loads content into a div - theDiv=div to load content into
//this might now be obsolete, due to newer target code, the obsolete unescaping, as of 8/4 it is not called by anything
Cases.prototype.loadDiv = function(theDiv)
{
	//var contentLocation = testCases.getDisplayLocation(theDiv);
	var contentLocation = this.getDisplayLocation(theDiv);
	var contentType = this.getDisplayType(theDiv);//this.contentPieces[theDiv]['type'];
	//if(contentLocation.search(/http:\/\//g) != -1){
	//if(contentLocation.search(/(\.rss$|\.txt$|\.html?$)/g) != -1){
	if(contentType == 'url'){
		$("#"+theDiv).load(contentLocation);
		//for(var i=1;i<10000000;i++){var j = 10/i;}//TAKE OUT
		//alert('$(#'+theDiv+').load("'+contentLocation+'");');
		//setTimeout('$(#'+theDiv+').load("'+contentLocation+'")',1000);
		//setTimeout('$(#display_div1).load(contentLocation)',1000);
	}
	else if(contentType == 'comp'){
		//var sourceID = this.content2sourceDiv(theDiv);
		var sourceID = this.display2sourceDiv(theDiv);
		var sourceElement = document.getElementById(sourceID);
		if(sourceElement != null){
			var sourceText = sourceElement.innerHTML;
			sourceText = sourceText.replace(/<\!\-\-/, "");
			sourceText = sourceText.replace(/\-\->/, "");
			var destinationElement = document.getElementById(theDiv);
			if(destinationElement != null){
				destinationElement.innerHTML = sourceText;
			}
		}
		else{this.errorMsg += "Did not load:"+theDiv+"|";}
	}
}


//given the id of an element, adds an onlick listener
Cases.prototype.addClickListener = function(objName)
{
	var trackingFunction;
	if(this.altTracking == "on"){//if custom tracking function is defined, use it
		//trackingFunction = eval(this.altClickFunction);
		trackingFunction = this.altClickFunction;
	}
	else{//else use built in trcking
		//trackingFunction = mitest_captureClick;
		trackingFunction = this.testName + ".mitest_captureClick(this.id)";//THIS WILL HAVE TO BE CHANGED IF YOU CHANGE TEST OBJECT NAME IN COMPONENT
	}
	//this.bindClickID(trackingFunction,objName);
	this.bindClickID4(trackingFunction,objName);
}


//placeholder - hardcoded omniture function
Cases.prototype.bindClickID4 = function(functionStr, objId)
{
	var selector = "#"+objId +" a";
	var label = this.divTrackingLabel(objId);
	if(label == ""){label = objId;}
	var trackTag = mistats_testsuffix + label;
	
	var trackingClick = "s.tl( this, 'o', '" + trackTag + "')";
	//var trackingClick = "s.tl( this, 'o', mistats_testsuffix +':" + label + "')";
	//var trackingClick = "alert('" + trackTag + "')";
	//var trackingClick = "alert(this.href)";
	//functionStr = functionStr.replace(/\@click_name#/g, label);alert("bindClickID: "+functionStr);
	$(selector).bind("click", function(){
	  eval(trackingClick);
	});
}



//binds function to onclick of all elements matchig a jquery selector string
Cases.prototype.bindClickBySelector = function(functionStr, selector)
{
	$(selector).bind("click", function(){
	  eval(functionStr);
	});
}


//adds listeners to all the appropriate divs
//Cases.prototype.addClickListenerAll = function(objName)
//Also, will add query string to links  if requested
Cases.prototype.addClickListenerAll = function()
{
	//if(this.onOff == 'off'){return;}
	if(this.isOff()){return;}
	var divs = this.theCase[this.caseNum].toTrack;
	for (i=0;i<divs.length;i++){
		//if(divs[i] == divname){return true;}
		this.addClickListener(divs[i]);
		if(this.appendTo == "all" || (this.appendTo == "no_cookie" && !this.cookiesEnabled)){//append links as needed
			appendAllLinks();//adds links which preserve case to all links to this domain
		}
	}
}

//sets cookie expiratin in minutes
Cases.prototype.setCookieTime = function(expiresIn)
{
	this.cookieExpiration = expiresIn;
}

//expire time in minutes
Cases.prototype.setCookie = function(cookieVal)
{
	var c_name = "mitest_"+this.testName;
	//var value = this.caseNum;
	var value = cookieVal;
	var expiresIn = this.cookieExpiration;
	var today = new Date();
	today.setTime( today.getTime() );
	expiresIn = expiresIn * 1000 * 60 ;//minutes
	var expires_date = new Date( today.getTime() + (expiresIn) );
	if(this.cookieDomain != ""){
		document.cookie=c_name+ "=" +escape(value)+((expires_date==null) ? "" : ";expires="+expires_date.toGMTString())+( ( this.cookieDomain ) ? ";domain=" + this.cookieDomain : "" )+";path=/";
	}
	else{
		document.cookie=c_name+ "=" +escape(value)+((expires_date==null) ? "" : ";expires="+expires_date.toGMTString())+";path=/";
	}
}

//get cookie value for case
Cases.prototype.getCookie = function()
{
	var c_name = "mitest_"+this.testName;
	if (document.cookie.length>0){
		c_start=document.cookie.indexOf(c_name + "=");
		if (c_start!=-1){
			c_start=c_start + c_name.length+1;
			c_end=document.cookie.indexOf(";",c_start);
			if (c_end==-1) c_end=document.cookie.length;
			return unescape(document.cookie.substring(c_start,c_end));
		}
	}
	return "";
}


/*
function escapeRegExp(inStr)
{
	inStr = inStr.replace("\\", "\\\\");
	inStr = inStr.replace("\(", "\\(");
	inStr = inStr.replace("\)", "\\)");
	inStr = inStr.replace("\]", "\\\]");
	inStr = inStr.replace("\[", "\\\[");
	inStr = inStr.replace("\}", "\\\}");
	inStr = inStr.replace("\{", "\\\{");
	inStr = inStr.replace("\$", "\\\$");
	inStr = inStr.replace("\^", "\\\^");
	inStr = inStr.replace("\|", "\\\|");
	inStr = inStr.replace("\.", "\\\.");
	inStr = inStr.replace("\?", "\\\?");
	inStr = inStr.replace("\*", "\\\*");
	inStr = inStr.replace("\+", "\\\+");

	return inStr;
}
*/


//input string instr and regex searchPat, if it finds the patter returns true, else returns false
Cases.prototype.regexMatch = function (instr, searchPat)
{
	var switches = "i";
	var searchExp = new RegExp();

	try{
		searchExp.compile(searchPat,switches);
	}
	catch(exception){
		alert(exception.description);
		return false;
	}
	
	if(instr.search(searchExp) == -1){return false;}
	return true;
}

//sees if we are forcing a case
Cases.prototype.findForcedCase = function (urlStr)
{
	if(urlStr.indexOf("mi_tester_force_case=") != -1){
		urlStr = urlStr.replace(/.+mi_tester_force_case=(\d+).*/g, "$1");
		return parseInt(urlStr) ;
	}
	else{return -1;}
	return -1;
}

//adds current page URL to tracking url
Cases.prototype.addPageURL2tracking = function (trackingURL)
{
	var url = document.location.href;
	url = escape(url);
	trackingURL = trackingURL.replace(/\@page_url#/, url);
	return trackingURL;
}

//adds mi omniture page  name to tracking URL
Cases.prototype.addPageName2tracking = function (trackingURL)
{
	var pageName = "";
	//if (typeof(mistats.pagename) != "undefined"){
	//alert("typeof mystats:"+typeof(mistats.pagename));
	if (typeof(mistats) != "undefined"){
		pageName = mistats.pagename;
	}
	pageName = escape(pageName);
	trackingURL = trackingURL.replace(/\@page_name#/, pageName);
	return trackingURL;
}

//given a div ID, returns the human readable label
Cases.prototype.divTrackingLabel = function (divID)
{
	for(var i_track=0;i_track<this.theCase[this.caseNum].toTrack.length;i_track++){
		if(this.theCase[this.caseNum].toTrack[i_track] == divID){return this.theCase[this.caseNum].toTrackNames[i_track];}
	}
	return "";
}

//plugs data into query string
Cases.prototype.makeTrackingURL = function (trackingBase, divID)
{
	trackingBase = trackingBase.replace(/\@test_name#/, this.testName);
	trackingBase = trackingBase.replace(/\@case_name#/, this.theCase[this.caseNum].caseName);
	trackingBase = trackingBase.replace(/\@case_num#/, this.caseNum);
	//trackingBase = trackingBase.replace(/\@click_name#/, divID);//in this cae, 'this' is the object that was clicked on
	var divLabel = this.divTrackingLabel(divID);
	if(divLabel == ""){divLabel = divID;}//if we didn't put a label on this div, use the div id
	trackingBase = trackingBase.replace(/\@click_name#/, divLabel);
	if(this.cookiesEnabled){trackingBase = trackingBase.replace(/\@cookies#/, "yes");}
	else{trackingBase = trackingBase.replace(/\@cookies#/, "no");}
	trackingBase = this.addPageURL2tracking(trackingBase);
	trackingBase = this.addPageName2tracking(trackingBase);
	trackingBase += this.makeErrorOut();
	return trackingBase;
}

//adds errors to string
Cases.prototype.makeErrorOut = function ()
{
	var errStr = this.errorOut;
	var errorEsc = escape(this.errorMsg);
	errStr = errStr.replace(/\@error#/, errorEsc);
	if(errStr != ""){errStr = "&"+errStr;}
	return errStr;
}

//adds tracking and/or case forcing query string to all urls on a page that are linking to the same domain
Cases.prototype.appendAllLinks = function ()
{
	var docdom = document.location.host.toLowerCase();
	var docdom2 = docdom.replace(/.+\.(.+\..+)/g, "$1");//remove subdomains
	var qstring = this.makeTrackingURL(this.trackingAppend, "mi_id_marker");//make a query string, with place holder for the id
	
    $("a").attr("href", function (arr) {//loop through links on this page
		var url = this.href.toLowerCase();
		var url2 = url.replace(/http\:\/\//i, "");
		var domIndex = url.indexOf(docdom2);
		if(domIndex == -1){return this.href;}//not on this domain, don't modify
		else{//check to see if dom is  actually part of a query string
			var markerIndex = url2.indexOf("/");
			if(markerIndex > -1 && domIndex > markerIndex){return this.href;}
			markerIndex = url2.indexOf("?");
			if(markerIndex > -1 && domIndex > markerIndex){return this.href;}
		}
		//var id_qstring = qstring.replace(/mi_id_marker/,"this.id");
		var url3 = this.href;
		if(url3.search(/[\?]/) == -1){url3 +=  "?";}
		else{url3+=  "&";}
		return url3 += qstring;
    });
}

//appends query string to all links in a given div
Cases.prototype.appendLinksDiv = function(divID, queryBase)
{
	var selector = "#"+divID+" a";
	var qstring = this.makeTrackingURL(queryBase, divID);
    $(selector).attr("href", function (arr) {
		var url = this.href;
		if(url.search(/[\?]/) == -1){
			url +=  "?";
		}
		else{url +=  "&";}
		url += qstring;
		//return this.href + "?testing";
		return url;
    });
	return false;
}

//generates a page load tracking URL
Cases.prototype.makeLoadURL = function ()
{
	var loadBase;
	if(this.theCase[this.caseNum].loadURL != ""){
		loadBase = this.theCase[this.caseNum].loadURL;
	}
	else{loadBase = this.loadURL;}
	//return this.makeTrackingURL(this.loadURL, "");
	return this.makeTrackingURL(loadBase, "");
}

//generates a case selection tracking URL
Cases.prototype.makeSelectURL = function ()
{
	var loadBase;
	if(this.theCase[this.caseNum].caseSelectURL != ""){
		loadBase = this.theCase[this.caseNum].caseSelectURL;
	}
	else{loadBase = this.caseSelectURL;}
	return this.makeTrackingURL(loadBase, "");
}

//capgures a click
//optional input for the div being tracked
Cases.prototype.makeClickURL = function ()
{
	var trackingBase = "";
	if(this.theCase[this.caseNum].trackingBase != ""){//use case's custom tracking URL, if there is one
		trackingBase = this.theCase[this.caseNum].trackingBase;
	}
	else{
		trackingBase = this.trackingBase;
	}

	var divID = "";
	if(this.makeClickURL.arguments.length > 0){divID = this.makeClickURL.arguments[0];}
	trackingBase = this.makeTrackingURL(trackingBase, divID);
	return trackingBase;
}

//the onclick function - the dynamically bound function calls this
Cases.prototype.mitest_captureClick = function (divID)
{
	if(!this.cookiesEnabled && !this.trackNoCookies){return;}
	var trackingURL = this.makeClickURL(divID);
	if(this.trackingAlertMode == true){alert(trackingURL);}
	else{$.get(trackingURL);}
}

