function urlManipulator(rawUrl) {
	this.parse = function () {
		if (this.rawUrl && this.rawUrl != "") {
			var queryStringIndex = rawUrl.indexOf('?');
			if (queryStringIndex != -1) {
				var queryString = rawUrl.substring(queryStringIndex, rawUrl.length);
				this.url = rawUrl.substring(0, queryStringIndex);
				this.parametersParser = new parametersParser(queryString);
			}
			else {
				this.url = rawUrl;
				this.parametersParser = new parametersParser();
			}
		}
		this.parsed = true;
	}

	//this.parametersParser = new parametersParser();
	this.parsed = false;
	this.rawUrl = rawUrl;
	this.parametersParser = null;

	this.setQueryParam = function (name, value) {
		if (!this.parsed) {
			this.parse();
		}
		this.parametersParser.setParam(name, value);
	}
	
	
	this.getRawUrl = function () {
		if (!this.parsed) {
			return this.rawUrl; // retrun it as we got it.
		}
		var result = this.url;
		var queryString = this.parametersParser.getQueryString();
		if (queryString && queryString != "") {
			result += '?' + queryString;
		}
		return result;			
	}
}


// Note1: no support for multiple params with the same name
// Note2: parameters names are case sensitive
// Note3: returns an empty string if requested param is missing
function parametersParser(params) {
	this.parse = function () {
		if (this.params && this.params != "") {
			if (this.params.indexOf('?') == 0) {
				this.params = this.params.substring(1, this.params.length);// Remove '?'
			}
			var parts = this.params.split('&');
			for (var i = 0 ; i < parts.length ; i++) {
				var pair = parts[i].split('=');
				this.paramValues[pair[0]] = pair[1];
			}
		}
		this.parsed = true;
	}
  
	this.getParam = function (name) {
		if (!this.parsed) {
			this.parse();
		}
		var res = this.paramValues[name];
		if (res) {
			return res;
		}
		else {
			return "";
		}
	}
	
	this.setParam = function (name, value) {
		if (!this.parsed) {
			this.parse();
		}
		this.paramValues[name] = value;
	}
	
	this.removeParam = function (name) {
		if (!this.parsed) {
			this.parse();
		}
		delete this.paramValues[name];
	}
	
	this.getQueryString = function () {
		if (!this.parsed) {
			return this.params; // retrun it as we got it.
		}
		var result = "";
		for (var p in this.paramValues) {
			result += p + '=' + this.paramValues[p];
			result += '&';
		}
		// Remove last &
		if (result.lastIndexOf("&") == result.length-1) {
			result = result.substring(0, result.length-1);
		}
		
		return result;			
	}
  
	this.paramValues = new Object();
	this.parsed = false;
	this.params = params;
}


// 
// Set default value in an input if it is empty (or has the default value)
//
/*
function setDefaultValue(field, defaultValue)
{
	var val = field.attr('value').replace(/\s/gi, '');
	if (val == '' || val == defaultValue) {
		field.attr('value', defaultValue);
		// Set class for default value
		field.addClass("input-prompt-text");
	}
}
*/

//
// Clear the value in an input if it is the default value
//
/*
function clearIfDefValue(field, defaultValue)
{
	if (field.attr('value') == defaultValue) {
		field.attr('value', '');
		// Remove class for default value
		field.removeClass("input-prompt-text");
	}
}
*/

// Validate mandatory text field. 
function validateMandatoryField(element, errorElement, additionalValidationVisibilityClass)
{
	var valid = true;
	element.removeClass("field-error");
	//errorElement.removeClass("field-validation-visible");
	//if (additionalValidationVisibilityClass != null) {
	//	errorElement.removeClass(additionalValidationVisibilityClass);
	//}
	if (!element.val() || element.val().replace(/^\s+|\s+$/g, "").length == 0) {
		element.addClass("field-error");
		errorElement.addClass("field-validation-visible");
		if (additionalValidationVisibilityClass != null) {
			errorElement.addClass(additionalValidationVisibilityClass);
		}
		valid = false;
	}
	return valid;
}


// Validate phone number (length and characters)
function validatePhoneField(element, errorElement, additionalValidationVisibilityClass, allowedLengths)
{
	var valid = true;
	
	element.removeClass("field-error");
	//errorElement.removeClass("field-validation-visible");
	//if (additionalValidationVisibilityClass != null) {
	//	errorElement.removeClass(additionalValidationVisibilityClass);
	//}
	// Allow only digits and: " ", "(", ")", ".", "-", "+"
	// Allowed lengths: as defined in parameter, but counting only digits (or other non supported characters - which will fail validation later)
	var digitsOnlyValue = element.val().replace(/[\s\(\)\.\-\+]/g, ""); 
	var nDigitsInValue = digitsOnlyValue.length;
	var isLengthInvalid = true;
	for (var i = 0; i < allowedLengths.length; i++) {
		if (nDigitsInValue == allowedLengths[i]) {
			isLengthInvalid = false;
			break;
		}
	}
	
	if (!/^[\d\s\(\)\.\-\+]*$/.test(element.val()) || isLengthInvalid) {
		element.addClass("field-error");
		errorElement.addClass("field-validation-visible");
		if (additionalValidationVisibilityClass != null) {
			errorElement.addClass(additionalValidationVisibilityClass);
		}
		valid = false;
	}
	
	return valid;
}


// Validate email format (algorithm based on contact-me jquery plugin validation) 
function validateEmailField(element, errorElement, additionalValidationVisibilityClass)
{
	var valid = true;
	
	element.removeClass("field-error");
	//errorElement.removeClass("field-validation-visible");
	//if (additionalValidationVisibilityClass != null) {
	//	errorElement.removeClass(additionalValidationVisibilityClass);
	//}

	var email = element.val(); 
	var at = email.lastIndexOf("@");

	// Make sure the at (@) sybmol exists and  
	// it is not the first or last character
	if (at < 1 || (at + 1) === email.length)
		valid = false;

	// Make sure there aren't multiple periods together
	if (valid && /(\.{2,})/.test(email))
		valid = false;

	// Break up the local and domain portions
	var local = email.substring(0, at);
	var domain = email.substring(at + 1);

	// Check lengths
	if (valid && (local.length < 1 || local.length > 64 || domain.length < 4 || domain.length > 255))
		valid = false;

	// Make sure local and domain don't start with or end with a period
	if (valid && (/(^\.|\.$)/.test(local) || /(^\.|\.$)/.test(domain)))
		valid = false;

	// Check for quoted-string addresses
	// Since almost anything is allowed in a quoted-string address,
	// we're just going to let them go through
	if (valid && !/^"(.+)"$/.test(local)) {
		// It's a dot-string address...check for valid characters
		if (!/^[-a-zA-Z0-9!#$%*\/?|^{}`~&'+=_\.]*$/.test(local))
				valid = false;
	}

	// Make sure domain contains only valid characters and at least one period
	if (valid && (!/^[-a-zA-Z0-9\.]*$/.test(domain) || domain.indexOf(".") === -1))
		valid = false;

	
	if (!valid) { 
		element.addClass("field-error");
		errorElement.addClass("field-validation-visible");
		if (additionalValidationVisibilityClass != null) {
			errorElement.addClass(additionalValidationVisibilityClass);
		}
	}
	
	
	return valid;
}

//LH from http://forums.asp.net/p/1050695/1483799.aspx
function getViewportScrollX() {
    var scrollX = 0;
    if( document.documentElement && document.documentElement.scrollLeft ) {
        scrollX = document.documentElement.scrollLeft;
    }
    else if( document.body && document.body.scrollLeft ) {
        scrollX = document.body.scrollLeft;
    }
    else if( window.pageXOffset ) {
        scrollX = window.pageXOffset;
    }
    else if( window.scrollX ) {
        scrollX = window.scrollX;
    }
    return scrollX;
}
function getViewportScrollY() {
    var scrollY = 0;
    if( document.documentElement && document.documentElement.scrollTop ) {
        scrollY = document.documentElement.scrollTop;
    }
    else if( document.body && document.body.scrollTop ) {
        scrollY = document.body.scrollTop;
    }
    else if( window.pageYOffset ) {
        scrollY = window.pageYOffset;
    }
    else if( window.scrollY ) {
        scrollY = window.scrollY;
    }
    return scrollY;
}


function formatAutoCompleteItem(inputText, itemText)
{
	return itemText.replace(new RegExp("\\b"+inputText, "gi"), "<span class=\"autocomplete-match\">" + inputText + "</span>");
}
