//GENERIC UTILITY FUNCTIONS
var GlobalCounter = function() {};
GlobalCounter.value = 0

diagnostic = false;
function alertOnce(what){
	if(!diagnostic){
		alert(what);
		diagnostic = true;
	}
}
function stripHTML(HTMLString){
	strippedHTML = HTMLString.replace(/<\S[^>]*>/gi, "");
	return strippedHTML;
}

function stripPadding(HTMLString){
	strippedHTML = HTMLString.replace(/^\s*(.*)\s*$/gi, "$1");
	return strippedHTML;
}

function setPageName(pageName){
	document.getElementById(pageName).disabled = false;
}

// confirmation utility
function confirmSubmit(msg) {
	var agree=confirm(msg);
	if (agree)
		return true;
	else
		return false;
}


//HIDE SHOW FOR NOTES
//find the y position of an html dom object
function findPosY(obj){
	var curtop = 0;
	if (obj.offsetParent){
		while (obj.offsetParent){
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}

//find the x position of an html dom object
function findPosX(obj){
	var curleft = 0;
	if (obj.offsetParent){
		while (obj){
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	} else if (obj.x) {
		curleft += obj.x;
	}
	return curleft;
}

function getMouseX(e) {
	if (document.all) { // grab the x-y pos.s if browser is IE
		tempX = event.clientX + document.body.scrollLeft
	} else {  // grab the x-y pos.s if browser is NS
		tempX = e.pageX
	}
	// catch possible negative values in NS4
	if (tempX < 0){
		tempX = 0;
	}
	return tempX;
}

function getMouseXInterleaved(e) {
	if (document.all) { // grab the x-y pos.s if browser is IE
		tempX = e.clientX + window.parent.document.body.scrollLeft
	} else {  // grab the x-y pos.s if browser is NS
		tempX = e.pageX
	}
	// catch possible negative values in NS4
	if (tempX < 0){
		tempX = 0;
	}
	return tempX;
}

//show note
function show_note(myNote, alignment){
	var objectNote = document.getElementById(myNote);
	var myMarker = document.getElementById(myNote + "_marker");
	objectNote.style.visibility='visible';

	var myY = findPosY(myMarker);
	var myX = findPosX(myMarker);
	if(myY>18){
		objectNote.style.top=(myY - 5) + "px";
	}else{
		objectNote.style.top=0 + "px";
	}
	if(alignment == "left"){
		objectNote.style.left=(myX - 220) + "px";
	} else {
		objectNote.style.left=(myX + 15) + "px";
	}
	overSource = true;
}

//get id of clicked element or id of first ancestor with id
function getAncestorID(e){
	if(!e){
		e = window.event;
	}
	var clickedObject = getClickedElement(e);
	var tempObject = clickedObject;
	var objectID = null;
	while(tempObject && (objectID == null)){
		//avoids issue with getAttribute returning error at top node
		if(tempObject.parentNode){
			objectID = tempObject.getAttribute('id');
		}
		tempObject = tempObject.parentNode;
	}
	return objectID;
}

//check to see if has ancestor with id of...
function isAncestorOf(e, testID){
	if(!e){
		e = window.event;
	}
	var clickedObject = getClickedElement(e);
	var tempObject = clickedObject;
	var objectID = null;
	while(tempObject && (objectID != testID)){
		//avoids issue with getAttribute returning error at top node
		if(tempObject.parentNode && tempObject.id){
			objectID = tempObject.getAttribute('id');
		}
		if(objectID == testID){
			return true;
		}
		tempObject = tempObject.parentNode;
	}
	return false;
}

//get the clicked element
function getClickedElement(e){
	if(!e){
		e = window.event;
	}
	if(e.target){
		clickedElement = e.target;
	} else if(e.srcElement){
		clickedElement = e.srcElement;
	}
	// defeat Safari bug
	if (clickedElement.nodeType == 3){
		clickedElement = clickedElement.parentNode;
	}
	return clickedElement;
}

function clickOutside(e, note, noteToggle){
	if(!e){
		e = window.event;
	}
	/*
	if(e.target){
		clickedElement = e.target;
	} else if(e.srcElement){
		clickedElement = e.srcElement;
	} else {
		//alert(e + " event handling does not appear to work");
		clickedElement = "badEvent";
	}
	// defeat Safari bug
	if (clickedElement.nodeType == 3){
		clickedElement = clickedElement.parentNode;
	}
	clickedElement = clickedElement.nodeName;
	alert(clickedElement);
	*/
	//get first parent of clicked object with and ID
	var clickedObject = getAncestorID(e);
	if(!isAncestorOf(e, note.id) && clickedObject != noteToggle.id){
		if(note.style.display == "block"){
			note.style.display = "none";
		}
	}
}


function popupNote(toggle, note){
	//prepender for all id's related to this rating utility - id's must follow naming convention
	var _note = document.getElementById(note);
	//width of images used for repeating backgrounds
	var _noteToggle = document.getElementById(toggle);

	//flag for whether the user is dragging or hovering
	var _noteVisible = false;

	this.clickToggle = function(){
		//if visible, hide it
		if(_note.style.display == "block"){
			_note.style.display = "none";
		//if user has triggered from the toggle and isn't already appearing, show
		} else {
			inputY = findPosY(_noteToggle);
			inputX = findPosX(_noteToggle);
			_note.style.top = inputY + _noteToggle.offsetHeight;
			_note.style.left = inputX;
			_note.style.display = "block";
		}
	}

	this.clickOutside = function(e){
		if(!e){
			e = window.event;
		}
		//get first parent of clicked object with and ID
		var clickedObject = getAncestorID(e);
		//if event is a child of calendarSelectSurround or is the toggle do nothing, else close calendar
		if(!isAncestorOf(e, _note.id) && clickedObject != _noteToggle.id){
			if(_note.style.display == "block"){
				_note.style.display = "none";
			}
		}
	}

	//initialize the rating bar including setting the size and attaching any appropriate events
	this.init = function () {
		//attache events to the document for drag outside behaviors
		if (document.all) { //ie
			document.attachEvent("onclick", this.clickOutside);
			_noteToggle.attachEvent("onclick", this.clickToggle);
		} else {
			_noteToggle.addEventListener("click", this.clickToggle, true);
			document.addEventListener('click', this.clickOutside, false);
		}
	}
}

function popupNoteInterleaved(toggle, note){
	//prepender for all id's related to this rating utility - id's must follow naming convention
	var _note = window.parent.document.getElementById(note);
	//width of images used for repeating backgrounds
	var _noteToggle = window.parent.document.getElementById(toggle);

	if (_noteToggle == undefined && _note == undefined) {
		_note = document.getElementById(note);
		_noteToggle = document.getElementById(toggle);
	}

	//flag for whether the user is dragging or hovering
	var _noteVisible = false;

	this.setNote = function (note) {
		_note = note;
	}

	this.setNoteToggle = function (noteToggle) {
		_noteToggle = noteToggle;
	}

	this.clickToggle = function(){
		//if visible, hide it
		if(_note.style.display == "block"){
			_note.style.display = "none";
		//if user has triggered from the toggle and isn't already appearing, show
		} else {
			inputY = findPosY(_noteToggle);
			inputX = findPosX(_noteToggle);
			_note.style.top = inputY + _noteToggle.offsetHeight;
			_note.style.left = inputX;
			_note.style.display = "block";
		}
	}

	this.clickOutside = function(e){
		if(!e){
			e = window.parent.event;
		}
		//get first parent of clicked object with and ID
		//alert("clickOutside event: "+e);
		var clickedObject = getAncestorID(e);
		//if event is a child of calendarSelectSurround or is the toggle do nothing, else close calendar
		if(!isAncestorOf(e, _note.id) && clickedObject != _noteToggle.id){
			if(_note.style.display == "block"){
				_note.style.display = "none";
			}
		}
	}

	//initialize the rating bar including setting the size and attaching any appropriate events
	this.init = function () {
		//attache events to the document for drag outside behaviors
		if (window.parent.document.all) { //ie
			window.parent.document.attachEvent("onclick", this.clickOutside);
			_noteToggle.attachEvent("onclick", this.clickToggle);
		} else {
			_noteToggle.addEventListener("click", this.clickToggle, true);
			window.parent.document.addEventListener('click', this.clickOutside, false);
		}
	}
}

/*
** Class used for the initialization and manipulation of a javascript interleaved rating bar
** TO DO:
** 1. implement double click to unset rating
** 2. provide better sample animation
*/

function ratingBarInterleaved(ratedItem){
	//prepender for all id's related to this rating utility - id's must follow naming convention
	var _prepend = ratedItem;
	//width of images used for repeating backgrounds
	var _BGWidth = 13;
	//height of images used for repeating backgrounds
	var _BGHeight = 15;
	//specificity of scores, recommended values are .5 or 1
	var _specificity = .5;
	//maximum rating, this controls the size of the rating bar as well as allowable maximum score
	var _maxRating = 5;
	//minimum rating, this controls the size of the rating bar as well as allowable minimum score
	var _minRating = 0;
	//type of rating - used in string appender for displaying rating in text format
	var _ratingType = "Stars";

	var _ratingTypeSingular = "Star";
	//current rating
	var _rating;
	//path used for "sparkle image"
	var _imagePath = "";

	//overrides for id's of rating display and input item bound to score
	//should just using naming conventions unless there is a good reason to do otherwise
	var _displayItemOverride;
	var _inputItemOverride;

	//flag for whether the user is dragging or hovering
	var _isMouseDown = false;
	//flag for whether a value has been set and the hover animation should be disabled
	var _hasValueSet = false;

	//set width of background image
	this.setSpecificity = function (specificity) {
		_specificity = specificity;
	}

	//set width of background image
	this.setBGWidth = function (width) {
		_BGWidth = width;
	}

	//set height of background image
	this.setBGHeight = function (height) {
		_BGWidth = height;
	}

	//set maximum rating - changes the number of background images displayed
	this.setMaxRating = function (maxRating) {
		_maxRating = maxRating;
	}

	//set minimum rating - limits min score
	this.setMinRating = function (minRating) {
		_minRating = minRating;
	}

	//set path used for "sparkle image"
	this.setImagePath = function (path) {
		_imagePath = path;
	}


	this.initializeValue = function (givenValue) {
		_hasValueSet = true;
		ratingValue = (Math.ceil(givenValue/_specificity)* 100 *_specificity)/100;
		if(ratingValue > _maxRating){
			ratingValue = _maxRating;
		} else if(ratingValue < _minRating){
			ratingValue = _minRating;
		}
		_rating = ratingValue;
		tableWidth = ratingValue * _BGWidth;
		window.parent.document.getElementById(ratedItem + "Filled").style.width = tableWidth + "px";
		//set the value to the bound input
		if(_inputItemOverride != null){
							alert(2);
			if(window.parent.document.getElementById(_inputItemOverride)){

				window.parent.document.getElementById(_inputItemOverride).value = _rating;
			}
		} else if(window.parent.document.getElementById(_prepend + 'Value')) {
			window.parent.document.getElementById(_prepend + 'Value').value = _rating;
		}
		//set the display value
		if(_displayItemOverride != null){
			if(document.getElementById(_displayItemOverride)){
				if (_rating == 1){

					window.parent.document.getElementById(_displayItemOverride).innerHTML = _rating + " " + _ratingTypeSingular;
				} else {

					window.parent.document.getElementById(_displayItemOverride).innerHTML = _rating + " " + _ratingType;
				}
			}
		} else if(document.getElementById(_prepend + 'Display')){
			if (_rating == 1){
				window.parent.document.getElementById(_prepend + 'Display').innerHTML = _rating + " " + _ratingTypeSingular;
			} else {
				window.parent.document.getElementById(_prepend + 'Display').innerHTML = _rating + " " + _ratingType;
			}
		}
	}

	//resize function for use with the hover and filled tables
	//returns the current rating value
	this.resizeTable = function (event, table) {
		//browser even access fix
		if(!event){
			event = window.parent.event;
		}
		//get width of rating table, should be set by class properties and initialization function
		tableWidth = window.parent.document.getElementById(_prepend + 'RatingBar').style.width;
		//get the user selected value in pixels
		scaleAmt = getMouseXInterleaved(event) - findPosX(window.parent.document.getElementById(_prepend + 'RatingBar'));
		//convert pixel value to rating units, rounding to specificity designated for class
		ratingValue = (Math.ceil(scaleAmt/_BGWidth/_specificity) * 100 * _specificity)/100;
		//if the rating value is out of bounds for some reason, set to bound limits
		if(ratingValue > _maxRating){
			ratingValue = _maxRating;
		} else if(ratingValue < _minRating){
			ratingValue = _minRating;
		}
		//get the width that the table should be resized to
		tableWidth = ratingValue * _BGWidth;
		//because tables cannot be of size 0, set to 1 pixel when the rated value is 0
		if(tableWidth < 1){
			tableWidth = 1;
		}
		//set table width
		window.parent.document.getElementById("r_rating").value=ratingValue;
		window.parent.document.getElementById(table).style.width = tableWidth + "px";
		//return rating
		_rating = ratingValue;
	}

	//set the rated value
	this.setRating = function (event) {
		this.updateRating(event, _prepend + 'Filled');
		//set flag that a value is now set and the hover state should disable
		_hasValueSet = true;
		//set the filled image to be a "sparkle" image - an animated version of the filled state that animates once and does not loop
		backgroundPath = _imagePath + 'sparkle.gif?i=' + GlobalCounter.value++;
		window.parent.document.getElementById(_prepend + 'Filled').style.background = "url(" + backgroundPath +")";
	}
	
	//update rating value and display
	this.updateRating = function (event, table, ignoreInput) {
		//reset the size of the given table
		this.resizeTable(event, table);
		//set the value of the input bound to this rating
		if(ignoreInput == null){
			if(_inputItemOverride != null){
				alert(3);
				if(window.parent.document.getElementById(_inputItemOverride)){
					window.parent.document.getElementById(_inputItemOverride).value = _rating;
				}
			} else if(window.parent.document.getElementById(_prepend + 'Value')) {
				window.parent.document.getElementById(_prepend + 'Value').value = _rating;
				//alert(window.parent.document.getElementById(_prepend + 'Value').value);
			}
		}
		//set the display value
		if(_displayItemOverride != null){
			if(document.getElementById(_displayItemOverride)){
				if (_rating == 1){
					window.parent.document.getElementById(_displayItemOverride).innerHTML = _rating + " " + _ratingTypeSingular;
				} else {
					window.parent.document.getElementById(_displayItemOverride).innerHTML = _rating + " " + _ratingType;
				}	
			}
		} else if(document.getElementById(_prepend + 'Display')){
			if (_rating == 1){
				window.parent.document.getElementById(_prepend + 'Display').innerHTML = _rating + " " + _ratingTypeSingular;
			} else {
				window.parent.document.getElementById(_prepend + 'Display').innerHTML = _rating + " " + _ratingType;
			}	
		}
	}
	
	//user is dragging the bar, set flag to indicate the drag has started
	this.startSlide = function () {
		_isMouseDown = true;
	}
	
	//user has stopped dragging, reset flag
	this.stopSlide = function () {
		if(_isMouseDown){
			//set the filled image to be a "sparkle" image - an animated version of the filled state that animates once and does not loop
			backgroundPath = _imagePath + 'sparkle.gif?i=' + GlobalCounter.value++;
			window.parent.document.getElementById(_prepend + 'Filled').style.background = "url(" + backgroundPath +")";
			_isMouseDown = false;
		}
	}

	//user is mousing over rating bar, check to see if hover or drag behavior is appropriate
	this.doSlide = function (event) {
		//if the mouse is down, update the value
		if(_isMouseDown){
			this.updateRating(event, _prepend + "Filled");
			//set flag that a value is now set and the hover state should disable
			_hasValueSet = true;
		//if the mouse is not down and the value has not been set, preview set value
		} else if(!_hasValueSet){
			this.updateRating(event, _prepend + "Hover", true);
		}
	}
	
	//set the hover table to width of 1, clear the display value if no value has been set
	this.resetHover = function () {
		//set width to minimum
		window.parent.document.getElementById(_prepend + "Hover").style.width = '1px';
		//clear display value if not set
		if(!_hasValueSet){
			if(_displayItemOverride != null){
				if(window.parent.document.getElementById(_displayItemOverride)){
					window.parent.document.getElementById(_displayItemOverride).innerHTML = "";
				}
			} else if(window.parent.document.getElementById(_prepend + 'Display')){
				window.parent.document.getElementById(_prepend + 'Display').innerHTML = "";
			}
		}
	}
	
	//initialize the rating bar including setting the size and attaching any appropriate events
	this.init = function () {
		//initialize rating table size
		tableWidth = _BGWidth * _maxRating;
		window.parent.document.getElementById( _prepend + "RatingBar").style.width = tableWidth + "px";
		window.parent.document.getElementById( _prepend + "Filled").style.height = _BGHeight + "px";
		
		//attache events to the document for drag outside behaviors
		if (window.parent.document.all) { //ie
			window.parent.document.attachEvent("onmouseup", this.stopSlide);
		} else {
			window.parent.document.addEventListener("mouseup", this.stopSlide, true);
		}
	}
}

function showNetPromoterBody(chk) {
	var np_body = document.getElementById('BVnetPromoterBodyId');
	if (np_body) {
		if (!chk.checked) {
			np_body.style.display = 'none';
		} else {
			np_body.style.display = 'block';
		}
	} else {
		return;
	}
}

function setOpenerLocation(url) {
	if (opener) {
		if (opener.closed)
			window.open(url, "");
		else
			opener.location.href = url;
		return false;
	}
	return true;
}

