SurveyCloud = new function() {
	
	// *********************** CONFIGURATION OPTIONS ***********************
	
	this.emDivisor = 2;
	this.maxEM = 2;	
	this.minEM = .7;
	this.maxTagLength = 25;
	this.profiling  = false;
	this.resultsURL = "/site/PageServer?pagename=MythConversationsResults";
	this.customResultsURL = "/site/Survey?SURVEY_ID=1780&ACTION_REQUIRED=URI_ACTION_VIEW_EXTENDED_REPORTING&QUESTION_ID=1660";
	this.inputOtherID = '3283_1780_3_1660';
	
	/**
	 * This function determines the size of a tag in the cloud
	 *   @param   frequency   The number of occurrences of an individual tag
	 *   @param   maximum     The highest frequency in the whole cloud.
	 *   @return              The size of the tag in EM.
	 */
	this.CalculateSize = function( frequency, maximum ) {
		var size = frequency / ( maximum / SurveyCloud.emDivisor );
		
		if ( size < this.minEM ) return SurveyCloud.minEM;
		if ( size > this.maxEM ) return SurveyCloud.maxEM;
		
		return size;
	}
	
	// ********************* END CONFIGURATION OPTIONS *********************	

	this.$cloud     = null;
	this.$cloudList = null;
	this.$dataNode  = null;
	this.data       = new Array();
	this.badWords   = null;
	this.maxFreq    = 0;
	this.startTime  = null;
	this.profileDiv = null;
	
	this.Initialize = function() {
		
		this.$cloud = $("#ConversationTagcloud");
		this.$cloud.css("textAlign","center");
		
		this.$cloud.parent().css("vertical-align","top");
		this.$cloud.parent().css("textAlign","center");
		
		this.$cloudList = $("<ul>");
		this.$cloudList.css("display","none");
		this.$cloudList.css("lineHeight",this.maxEM+"em");
		this.$cloudList.css("textAlign","center");
		this.$cloudList.appendTo(this.$cloud);
		
		this.$cloud.after("<div id='SurveyDataContainer' style='display:none;background:red;'></div>");
		
		this.$dataNode = $("#SurveyDataContainer");
		
		$.ajax({
			type: "GET",
			url: this.resultsURL,
			dataType: "text",
			cache: false,
			success: this.FetchPresetResponsesCB
		})
	}

	this.AddTagToForm = function(tag) {
		var others=$('#' + this.inputOtherID);
		tag = tag.replace( /&nbsp;/g, ' ' );
		tag = tag.replace( /^\s*(.*?)\s*$/, '$1' );
		var value = others.attr('value');
		if ( value.length>0 ) {
			value += '\n';
		}
		value += tag;
		others.attr( 'value', value );
		others.trigger("onkeyup"); // make the length limiter run
	}
	
	this.FetchPresetResponsesCB = function(data,textStatus) {
				
		if ( SurveyCloud.profiling ) {
			var now = new Date();
			SurveyCloud.startTime = now.getTime();
			var preTime = SurveyCloud.startTime;
			$("<div>").css("height","30px").appendTo(SurveyCloud.$cloud);
			SurveyCloud.profileDiv = $("<div>").css("textAlign","left").css("color","#ccc").appendTo(SurveyCloud.$cloud);
		}
		
		// regex do not work properly with newlines, strip them for now, replacing with tabs for easy reinsertion
		data = data.replace(/\n/g,"\t");
		
		// grab the blocks we actually want from the result, and fix them up a bit before throwing them into the DOM
		var stripped = "" 
		stripped += data.match( /<div id="NBCC_PresetSurveyResponses".*?<\/div>/ )[0].replace(/<script.*?<\/script>/g, "");;
		stripped += data.match( /<div id="NBCC_SurveyBadWordList".*?<\/div>/     )[0].replace(/\t/g,',');		
		SurveyCloud.$dataNode.append(stripped);

		if ( SurveyCloud.profiling ) {
			var now = new Date();
			var endTime = now.getTime();
			$("<div>").text('Parsing: ' + (endTime-preTime) +'ms').appendTo(SurveyCloud.profileDiv);		
			var preTime = endTime;
		}
		
		// Grab all of the preset tags, take their frequencies from the table
		$.each( $("#NBCC_PresetSurveyResponses .ListItemnull"), function() {
			var $tds = $( $(this).children() );
			var node = $($tds[0]).children()[0];
			if ( node ) {
				var tag = node.innerHTML.toLowerCase();
				if ( tag != 'user provided no response' ) { 
					var freq = parseInt( $($tds[2]).children()[0].innerHTML );
					SurveyCloud.data[tag] = freq;
					if ( freq > SurveyCloud.maxFreq ) {
						SurveyCloud.maxFreq=freq;
					}
				}
			}
		});

		if ( SurveyCloud.profiling ) {
			var now = new Date();
			var endTime = now.getTime();
			$("<div>").text('Preset Responses: ' + (endTime-preTime) +'ms').appendTo(SurveyCloud.profileDiv);		
			var preTime = endTime;
		}
		
		// Get the bad words
		var badWords = new Array();
		var badWordsText = $("#NBCC_SurveyBadWordList").text();
		// delimiters can be comma, semi-colon or newline.  newlines are converted to commas earlier
		// and each newline gets <p> tags from the wysiwg editor, so strip those
		badWordsText = badWordsText.toLowerCase().replace(";",",").replace( /<\/?p>/g, '');
		var rawBadWordList = badWordsText.split(",");
		for( i in rawBadWordList ) {
			var badWord = rawBadWordList[i];
			// get rid of surrounding whitespace
			badWord = badWord.replace( /^\s*(.*?)\s*$/, '$1' );
			// throw away very short tags to prevent errors
			if ( badWord.length>2 ) {
				// Remove any bad user input to prevent breaking the regexp
				badWord = RegExp.escape(badWord);
				// But do allow * wildcards.  Precompile the regex for later
				var badWordRE = new RegExp( badWord.replace('*','.*') );
				badWords.push( badWordRE );
			}
		}
		
		SurveyCloud.badWords = badWords;
		
		if ( SurveyCloud.profiling ) {
			var now = new Date();
			var endTime = now.getTime();
			$("<div>").text('Bad Words: ' + (endTime-preTime) +'ms').appendTo(SurveyCloud.profileDiv);		
			var preTime = endTime;
			SurveyCloud.step1End = preTime;
		}
		
		
		
		// and fetch custom results
		$.ajax({
			type: "GET",
			url: SurveyCloud.customResultsURL,
			dataType: "text",
			cache: false,
			success: SurveyCloud.FetchUserResponsesCB				
		})		
		
	}
	
	this.FetchUserResponsesCB = function(data,textStatus) {
		
		if ( SurveyCloud.profiling ) {
			var now = new Date();
			var preTime = now.getTime();
			SurveyCloud.startTime = SurveyCloud.startTime + preTime - SurveyCloud.step1End;
		}
		
		data = data.replace(/\n/g,"\t");
		var stripped = data.match( /<table.*?<\/table>/ )[0].replace(/>\t+</g,'><').replace(/\t/g,',');
		SurveyCloud.$dataNode.append('<div id="NBCC_UserResponses">'+stripped+'</div>');
		var badWords = SurveyCloud.badWords;

		if ( SurveyCloud.profiling ) {
			var now = new Date();
			var endTime = now.getTime();
			$("<div>").text('Custom Tag Parsing: ' + (endTime-preTime) +'ms').appendTo(SurveyCloud.profileDiv);		
			var preTime = endTime;
		}
		
		// Now we do all the custom tags.
		$.each( $("#NBCC_UserResponses .ListItem1"), function() {
			var $tds = $($(this).children());
			var node = $tds[1]; //.children()[0];
			if ( node ) {
				// Convio puts linebreaks/nonbreaking spaces here for some reason
				var tags = node.innerHTML.toLowerCase(); //.replace( /<br>&nbsp;/g, '' );
				// Delimiters can be semi-colons or commas
				// If they try to use "and" with a serial comma we throw the and away
				tags = tags.replace(/\t/g,',');
				tags = tags.replace(/;/g,',');
				tags = tags.replace(', and ',',');
				var tagArr = tags.split(',');
				for( var x=0; x<tagArr.length; x++ ) {
					var tag = tagArr[x];
					if ( tag && ( tag != 'user provided no response' ) ) {
						// strip outer whitespace
						tag = tag.replace( /^\s*(.*?)\s*$/, '$1' );
						
						// Run it against the bad words
						var isBadWord=false;
						for( b in badWords ) {
							if ( tag.match( badWords[b] ) ) {
								isBadWord=true;
								break;
							}
						}
						if ( !isBadWord ) {
							if ( SurveyCloud.data[tag] === undefined ) {
								// if it's a new tag, add it to the array properly
								SurveyCloud.data[tag]=0;
							}
							SurveyCloud.data[tag]++;
							if ( SurveyCloud.data[tag] > SurveyCloud.maxFreq ) {
								SurveyCloud.maxFreq=SurveyCloud.data[tag];
							}
						}
					}
				}
			}
		});
		
		if ( SurveyCloud.profiling ) {
			var now = new Date();
			var endTime = now.getTime();
			$("<div>").text('Custom Tags: ' + (endTime-preTime) +'ms').appendTo(SurveyCloud.profileDiv);		
			var preTime = endTime;
		}
		
		SurveyCloud.GenerateTagCloud();		
	}
	
	this.GenerateTagCloud = function() {

		if ( SurveyCloud.profiling ) {
			var now = new Date();
			var preTime = now.getTime();
		}
		
		// build a tag array that we can mangle for randomizing the tag cloud
		var tags = new Array();
		for( tag in SurveyCloud.data ) {
			tags.push(tag);
		}
	
		var listString = '';
		while(tags.length>0) {
			// Splice out a random element until the tag array is empty
			var n = Math.floor(Math.random()*tags.length);
			var tag = tags.splice(n,1)[0];
			var freq = SurveyCloud.data[tag];
			var size = SurveyCloud.CalculateSize( freq, SurveyCloud.maxFreq );
			if ( tag.length<SurveyCloud.maxTagLength) {
				tag = tag.replace(/ /g,'&nbsp;');
				// Adding to a string is much faster than adding it to the DOM directly at this point
				if ( SurveyCloud.profiling ) {
					tag = freq + ':"' + tag + '"';
				}
				listString += "<li style='cursor:pointer;font-size:"+size+"em;list-style-type:none;display:inline;background-image:none;' onclick='SurveyCloud.AddTagToForm(this.innerHTML);'> " + tag + " </li>";
			}
			
		}
		// Attach it to the DOM in bulk
		SurveyCloud.$cloudList.append(listString);

		if ( SurveyCloud.profiling ) {
			var now = new Date();
			var endTime = now.getTime();
			$("<div>").text('Tag Cloud Generation: ' + (endTime-preTime) +'ms').appendTo(SurveyCloud.profileDiv);		
			var preTime = endTime;
		}
		
		// Show it, and we're done!
		$("#ConversationTagHead").css('display','block');
		SurveyCloud.$cloudList.css("display","block");
		
		if ( SurveyCloud.profiling ) {
			var now = new Date();
			var endTime = now.getTime();
			$("<div>").text('Render: ' + (endTime-preTime) +'ms').appendTo(SurveyCloud.profileDiv);		
			var preTime = endTime;
			
			var now = new Date();
			var endTime = now.getTime();
			$("<div>").text('Total: ' + (endTime-SurveyCloud.startTime) +'ms').appendTo(SurveyCloud.profileDiv);
		}		
		
	}
	
}

RegExp.escape = function(text) {
	if (!arguments.callee.sRE) {
		var specials = [
			'/', '.', '+', '?', '|',
			'(', ')', '[', ']', '{', '}', '\\'
		];
		arguments.callee.sRE = new RegExp(
			'(\\' + specials.join('|\\') + ')', 'g'
			);
	}
	return text.replace(arguments.callee.sRE, '\\$1');
}

$(document).ready(function() {
	SurveyCloud.Initialize();
	if ( document.location.href.match(/&debug/) ) {
		SurveyCloud.profiling = true;
	}
});