//
// +----------------------------------------------------------------------+
// | Unobtrusive Javascript Validation for YUI v2.0 (2007-03-04)          |
// | http://blog.jc21.com                                                 |
// +----------------------------------------------------------------------+
// | Attaches Events to all forms on a page and checks their form         |
// | elements classes to provide some validation.                         |
// +----------------------------------------------------------------------+
// | Copyright: jc21.com 2008                                             |
// +----------------------------------------------------------------------+
// | Licence: Absolutely free. Don't mention it.                          |
// +----------------------------------------------------------------------+
// | Author: Jamie Curnow <jc@jc21.com>                                   |
// +----------------------------------------------------------------------+
//
//



//==================================================================================================================
//  Trim Whitespace
//------------------------------------------------------------------------------------------------------------------
String.prototype.trim=function(){
	return this.replace(/^\s*|\s*$/g,'');
}
String.prototype.ltrim=function(){
	return this.replace(/^\s*/g,'');
}
String.prototype.rtrim=function(){
	return this.replace(/\s*$/g,'');
}

//==================================================================================================================
//  FIC_checkForm
//  Form Input Checking by JC
/*
		Apply these class names to form elements:

		* required (not blank)
		* validate-number (a valid number)
		* validate-digits (digits only, spaces allowed.)
		* validate-alpha (letters only)
		* validate-alphanum (only letters and numbers)
		* validate-date (a valid date value)
		* validate-email (a valid email address)
		* validate-url (a valid URL)
		* validate-date-au (a date formatted as; dd/mm/yyyy)
		* validate-currency-dollar (a valid dollar value)
		* validate-one-required (At least one checkbox/radio element must be selected in a group)
		* validate-not-first (Selects only, must choose an option other than the first)
		* validate-not-empty (Selects only, must choose an option with a value that is not empty)
		* validate-regex (requires the element to have a 'regex=' attribute applied)

		Also, you can specify this attribute for text, passwird and textarea elements:
		* minlength="x" (where x is the minimum number of characters)
*/
//------------------------------------------------------------------------------------------------------------------
function FIC_checkForm(e) {
	var errs = new Array();

	//this function is called when a form is submitted.
	if (typeof(e) == "string") {
		//the id was supplied, get the object reference
		e = xGetElementById(e);
		if (!e) {
			return true;
		}
	}

	var elm=e;
	if (!e.nodeName) {
		//was fired by yahoo
		elm = (e.srcElement) ? e.srcElement : e.target;
	}
	if (elm.nodeName.toLowerCase() != 'form') {
		elm = searchUp(elm,'form');
	}

	var all_valid = true;

	//access form elements
	//inputs
	var f_in = elm.getElementsByTagName('input');
	//selects
	var f_sl = elm.getElementsByTagName('select');
	//textareas
	var f_ta = elm.getElementsByTagName('textarea');

	//check inputs
	for (i=0;i<f_in.length;i++) {
		if (f_in[i].type.toLowerCase() != 'submit' && f_in[i].type.toLowerCase() != 'button' && f_in[i].type.toLowerCase() != 'hidden') {
			if (isVisible(f_in[i])) {
				var cname = ' '+f_in[i].className.replace(/^\s*|\s*$/g,'')+' ';
				cname = cname.toLowerCase();
				alert(cname);
				var inv = f_in[i].value.trim();
				var t = f_in[i].type.toLowerCase();
				var cext = '';
				if (t == 'text' || t == 'password') {
					//text box
					var valid = FIC_checkField(cname,f_in[i]);
				} else if(t == 'radio' || t == 'checkbox'){
					// radio or checkbox
					var valid = FIC_checkRadCbx(cname,f_in[i],f_in);
					cext = '-cr';
				} else {
					var valid = true;
				}

				if (valid) {
					removeClassName(f_in[i],'validation-failed'+cext);
					addClassName(f_in[i],'validation-passed'+cext);
				} else {
					removeClassName(f_in[i],'validation-passed'+cext);
					addClassName(f_in[i],'validation-failed'+cext);
					//try to get title
					if (f_in[i].getAttribute('title')){
						errs[errs.length] = f_in[i].getAttribute('title');
					}
					all_valid = false;
				}
			}
		}
	} //end for i

	//check textareas
	for (i=0;i<f_ta.length;i++) {
		if (isVisible(f_ta[i])) {
			var cname = ' '+f_ta[i].className.replace(/^\s*|\s*$/g,'')+' ';
			cname = cname.toLowerCase();
			var valid = FIC_checkField(cname,f_ta[i]);

			if (valid) {
				removeClassName(f_ta[i],'validation-failed');
				addClassName(f_ta[i],'validation-passed');
			} else {
				removeClassName(f_ta[i],'validation-passed');
				addClassName(f_ta[i],'validation-failed');
				//try to get title
				if (f_ta[i].getAttribute('title')){
					errs[errs.length] = f_ta[i].getAttribute('title');
				}
				all_valid = false;
			}
		}
	} //end for i

	//check selects
	for (i=0;i<f_sl.length;i++) {
		if (isVisible(f_sl[i])) {
			var cname = ' '+f_sl[i].className.replace(/^\s*|\s*$/g,'')+' ';
			cname = cname.toLowerCase();
			var valid = FIC_checkSel(cname,f_sl[i]);
			if (valid) {
				removeClassName(f_sl[i],'validation-failed-sel');
				addClassName(f_sl[i],'validation-passed-sel');
			} else {
				removeClassName(f_sl[i],'validation-passed-sel');
				addClassName(f_sl[i],'validation-failed-sel');
				//try to get title
				if (f_sl[i].getAttribute('title')){
					errs[errs.length] = f_sl[i].getAttribute('title');
				}
				all_valid = false;
			}
		}
	} //end for i

	if (!all_valid) {
		if (errs.length > 0){
			alert("We have found the following error(s):\n\n  * "+errs.join("\n  * ")+"\n\nPlease check the fields and try again");
		} else {
			alert('Some required values are not correct. Please check the items in red.');
		}
		
		e.preventDefault();
		e.stopPropagation();
		
	}
	return all_valid;
} // end FIC_checkForm

//==================================================================================================================
//  FIC_checkField
//	c = className
//	e = the element
//------------------------------------------------------------------------------------------------------------------
function FIC_checkField(c,e) {
	var valid = true;
	var t = e.value.trim();

	//search for required
	if (c.indexOf(' required ') != -1 && t.length == 0) {
		//required found, and not filled in
		valid = false;
	}

	//check length
	if (c.indexOf(' required ') != -1){
		//check for minlength.
		var m = e.getAttribute('minlength');
		if (m && Math.abs(m) > 0){
			if (e.value.length < Math.abs(m)){
				valid = false;
			}
		}
	}

	//search for validate-
	if (c.indexOf(' validate-number ') != -1 && isNaN(t) && t.match(/[^\d]/)) {
		//number bad
		valid = false;
	} else if (c.indexOf(' validate-digits ') != -1 && t.replace(/ /,'').match(/[^\d]/)) {
		//digit bad
		valid = false;
	} else if (c.indexOf(' validate-alpha ') != -1 && !t.match(/^[a-zA-Z]+$/)) {
		//alpha bad
		valid = false;
	} else if (c.indexOf(' validate-alphanum ') != -1 && t.match(/\W/)) {
		//alpha bad
		valid = false;
	} else if (c.indexOf(' validate-date ') != -1) {
		var d = new date(t);
		if (isNaN(d)) {
			//date bad
			valid = false;
		}
	} else if (c.indexOf(' validate-email ') != -1 && !t.match(/\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/)) {
		//email bad
		valid = false;
		if (c.indexOf(' required ') == -1 && t.length == 0) {
			valid = true;
		}
	} else if (c.indexOf(' validate-url ') != -1 && !t.match(/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i)) {
		//url bad
		valid = false;
	} else if (c.indexOf(' validate-date-au ') != -1 && !t.match(/^(\d{2})\/(\d{2})\/(\d{4})$/)) {
		valid = false;
//	} else if (c.indexOf(' validate-currency-dollar ') != -1 && !t.match(/^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/)) {
	} else if (c.indexOf(' validate-currency-dollar ') != -1 &&
			(!t.match(/(^(0|[1-9][0-9]*)$)|((^(0?|[1-9][0-9]*)\.(0*[1-9][0-9]*)$)|(^[1-9]+[0-9]*\.0+$)|(^0\.0+$))/) ||
			t.length && 0)) {
		valid = false;
	} else if (c.indexOf(' validate-regex ') != -1) {
        var r = RegExp(e.getAttribute('regex'));
        if (r && ! t.match(r)) {
            valid = false;
        }
    }

	return valid;
}

//==================================================================================================================
//  FIC_checkRadCbx
//	c = className
//	e = this element, radio or checkbox
//	f = input fields dom element
//------------------------------------------------------------------------------------------------------------------
function FIC_checkRadCbx(c,e,f){
	var valid = true;

	//search for required
	if (c.indexOf(' validate-one-required ') != -1) {
		//required found
		//check if other checkboxes or radios have been selected.
		valid = false;
		for (var i=0;i<f.length;i++){
			if(f[i].name.toLowerCase() == e.name.toLowerCase() && f[i].checked){
				valid = true;
				break;
			}
		}
	}

	return valid;
}

//==================================================================================================================
//  FIC_checkSel
//	c = className
//	e = this select element
//------------------------------------------------------------------------------------------------------------------
function FIC_checkSel(c,e){
	var valid = true;
	//search for validate-
	if (c.indexOf(' validate-not-first ') != -1 && e.selectedIndex == 0) {
		//bad
		valid = false;
	} else if (c.indexOf(' validate-not-empty ') != -1 && e.options[e.selectedIndex].value.length == 0) {
		//bad
		valid = false;
	}
	return valid;
}

//==================================================================================================================
//  addClassName
//------------------------------------------------------------------------------------------------------------------
function addClassName(e,t) {
	if (typeof e == "string") {
		e = xGetElementById(e);
	}
	//code to change and replace strings
	var ec = ' ' + e.className.replace(/^\s*|\s*$/g,'') + ' ';
	var nc = ec;
	t = t.replace(/^\s*|\s*$/g,'');
	//check if not already there
	if (ec.indexOf(' '+t+' ') == -1) {
		//not found, add it
		nc = ec + t;
	}
	//return the changed text!
	e.className = nc.replace(/^\s*|\s*$/g,''); //trimmed whitespace
	return true;
}

//==================================================================================================================
//  removeClassName
//------------------------------------------------------------------------------------------------------------------
function removeClassName(e,t) {
	if (typeof e == "string") {
		e = xGetElementById(e);
	}
	//code to change and replace strings
	var ec = ' ' + e.className.replace(/^\s*|\s*$/g,'') + ' ';
	var nc = ec;
	t = t.replace(/^\s*|\s*$/g,'');
	//check if not already there
	if (ec.indexOf(' '+t+' ') != -1) {
		//found, so lets remove it
		nc = ec.replace(' ' + t.replace(/^\s*|\s*$/g,'') + ' ',' ');
	}
	//return the changed text!
	e.className = nc.replace(/^\s*|\s*$/g,''); //trimmed whitespace
	return true;
}

//==================================================================================================================
//  attachToForms
//------------------------------------------------------------------------------------------------------------------
function attachToForms(e) {
	//search dom for all forms
	var frms = document.getElementsByTagName('form');
	for(var i=0;i<frms.length;i++) {
		//YAHOO.util.Event.addListener(frms[i], "submit", FIC_checkForm);
		if(frms[i].addEventListener){
			frms[i].addEventListener("submit", FIC_checkForm, false);  //Modern browsers
		}else if(frms[i].attachEvent){
			frms[i].attachEvent('onsubmit', FIC_checkForm);            //Old IE
		}
	}
}

//==================================================================================================================
//  isVisible
//------------------------------------------------------------------------------------------------------------------
function isVisible(e) {
	//returns true is should be visible to user.
	if (typeof e == "string") {
		e = xGetElementById(e);
	}
	while (e.nodeName.toLowerCase() != 'body' && e.style.display.toLowerCase() != 'none' && e.style.visibility.toLowerCase() != 'hidden') {
		e = e.parentNode;
	}
	if (e.nodeName.toLowerCase() == 'body') {
		return true;
	} else{
		return false;
	}
}


//==================================================================================================================
//  searchUp
//------------------------------------------------------------------------------------------------------------------
function searchUp(elm,findElm,debug) {
	//this function searches the dom tree upwards for the findElm node starting from elm.
	//check if elm is reference

	if(typeof(elm) == 'string') {
		elm = xGetElementById(elm);
	}
	//search up
	//get the parent findElm
	while (elm && elm.parentNode && elm.nodeName.toLowerCase() != findElm && elm.nodeName.toLowerCase() != 'body') {
		elm = elm.parentNode;
	}
	return elm;
}

//==================================================================================================================
//  xGetElementById
//------------------------------------------------------------------------------------------------------------------
function xGetElementById(e) {
	if(typeof(e)!='string') return e;
	if(document.getElementById) e=document.getElementById(e);
	else if(document.all) e=document.all[e];
	else e=null;
	return e;
}

//YAHOO.util.Event.addListener(window, "load", attachToForms);


//==================================================================================================================
//  TO HIDE THE LANGUAGE CONVERSION OPTION IN A PAGE
//------------------------------------------------------------------------------------------------------------------

function fnHideLangConversion() {	
	$("[href*='/c/portal/update_language']").parent().hide().next(":contains(|)").hide();
	$('[name="changeLanguageLink"]').parent().hide().next(":contains(|)").hide();
}

//================================================================================
//----------------------------------------------------------------------------------
//==================================================================================================================
//  jQuery prototypes
//------------------------------------------------------------------------------------------------------------------
jQuery.fn.extend({
	//------------------------------------------------------------------------------------------------------------------
	//  locate the input group (returns the ancestor containing the Group class or the parent of the current element)
	//------------------------------------------------------------------------------------------------------------------
	inputGroup: function() {
		var $rv = $();
		this.each(function() {
			$rv = $rv.add($($(this).closest("."+$(this).attr("id")+"Group")[0] ||
			                $(this).closest("."+$(this).attr("name")+"Group")[0] ||
			                $(this).parent()[0]));
		});
		return $rv;
	},
	
	//------------------------------------------------------------------------------------------------------------------
	//  addError to input (returns the elements that have had errors added)
	//------------------------------------------------------------------------------------------------------------------
	addInputError: function(errorMessage, alert) {
		alert = (alert !== undefined) ? alert : true; 
		errorMsg = (errorMessage !== undefined) ? errorMessage : this.attr('error-msg');
		
		var $rv = $();
		this.each(function () {
			var alertRoleAttr = alert?' role="alert"':'';
	        if(!$(this).attr("aria-invalid")){
	        	$rv=$rv.add($(this));
	            fieldErrorId = typeof ($(this).attr("name")) !== 'undefined' ? $(this).attr("name") + "Error" : "";
	            $(this).inputGroup().children(".validation-error").length
	                            ? $(this).inputGroup().children(".validation-error")
	                            : $(this).inputGroup().append('<div id="' + fieldErrorId + '" class="validation-error"' + alertRoleAttr + '></div>');
	            var error = $(this).inputGroup().children(".validation-error");
	            $(this).attr("aria-invalid", "true");
	            $(this).inputGroup().addClass("has-validation-error");
	            error.html('<span class="message-icon"><svg data-name="Outline" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">' +
	            '<path d="M18.67,17.67l-8-16a.79.79,0,0,0-1.34,0l-8,16A.75.75,0,0,0,2,18.75H18a.75.75,0,0,0,.67-1.08ZM3.21,17.25,10,3.68l6.79,13.57ZM9.25,8h1.5v5H9.25Zm1.46,6.29a1.15,1.15,0,0,1,.21.33.94.94,0,0,1,0,.76,1.15,1.15,0,0,1-.21.33,1,1,0,0,1-1.63-1.09,1,1,0,0,1,.21-.33,1,1,0,0,1,.9-.27.6.6,0,0,1,.19.06l.18.09Z"/>' +
	            '</svg></span><p>' + errorMessage + '</p>');
	        }
		});
		return $rv;
    },

	//------------------------------------------------------------------------------------------------------------------
	//Check for Errors (returns the elements have are invalid)
	//------------------------------------------------------------------------------------------------------------------
	checkForErrors: function() {
		var $rv = $();
		this.each(function() {
			var isValid=false;
			if(this.validity.valid){
			    var visibleId = $(this).attr('id');
			    if(visibleId && visibleId.match("^visible")){
			        var hiddenInput = $(this).next();
			        if(hiddenInput.length && hiddenInput[0].validity.valid){
			            isValid=true;
			        }
			    } else {
			        isValid=true;
			    }
			}
			if(!isValid){
	        	$rv=$rv.add($(this));
			    $(this).trigger( "invalid" );
			}
		});
		return $rv;
	},
	
	//==================================================================================================================
	//  Remove Errors
	//------------------------------------------------------------------------------------------------------------------
	removeErrors: function() {
		var $rv = $();
		this.each(function () {
		    $(this).inputGroup().children(".validation-error").remove();
		    $(this).inputGroup().removeClass("has-validation-error");
	        $(this).removeAttr( "aria-invalid" );
        	$rv=$rv.add($(this));
		});
		return $rv;
	},

	//==================================================================================================================
	//  add focus class from FORM LABEL
	//------------------------------------------------------------------------------------------------------------------
	addFocusClass: function() {
		this.inputGroup().children("label").removeClass("input-label").addClass("input-focus-label");
		return this;
	},
	
	//==================================================================================================================
	//  remove focus class from FORM LABEL
	//------------------------------------------------------------------------------------------------------------------
	removeFocusClass: function() {
		var $rv = this.filter(function () {
			if (this.value) {return false;}
			if ($(this).prevAll(".input-group-addon")[0]) {return false;}
			return $(this).is('input:not([type="date"],[type="hidden"],[type="checkbox"],[type="radio"],[type="button"],[type="submit"]),:not(select)');
		});
		$rv.inputGroup().children("label").addClass("input-label").removeClass("input-focus-label");
		return $rv;
	},
	
	//==================================================================================================================
	//  Initialize focus class for FORM LABEL
	//------------------------------------------------------------------------------------------------------------------
	initializeFocusClass: function() {
		return this.addFocusClass().removeFocusClass();
	},

	//==================================================================================================================
	//  Return whether the first element is required,
	//  OR
	//  Set the required attribute for all elements, show/hide the Helper text if it is "(Optional)", 
	//    and check for errors, which may show or hide a field level error message.
	//------------------------------------------------------------------------------------------------------------------
	required: function(isRequired) {
		if (isRequired == undefined) {
			// return the value of the required property for the first matched field.
			return $(this).first().prop("required");
		}
		// add/remove the required attribute, set/remove the (Optional) helper text, and fire the change method
		$(this).inputGroup().children("[id$="+$(this).attr("id")+"Help]").filter(":contains(Optional),:contains(Opcional)").toggle(!isRequired);
		if (isRequired) {
			return $(this).filter(function(index){return !$(this).prop("required")}).attr("required",true).removeErrors().checkForErrors();
		} else {
			return $(this).filter(function(index){return $(this).prop("required")}).removeAttr("required").removeErrors().checkForErrors();
		}
	}
});

//==================================================================================================================
//  addError to input.  This function is suitable for using in a jQuery event handler
//------------------------------------------------------------------------------------------------------------------
function addInputError(errorField, errorMsg){
	errorMsg = (typeof errorMsg !== undefined) ? errorMsg : "";
    if(errorField.originalEvent instanceof Event || (typeof errorField === 'object' && errorField.type == 'invalid')) {
        $(this).addInputError($(this).attr('error-msg') ? $(this).attr('error-msg') : $(this)[0].title ? $(this)[0].title : $(this)[0].validationMessage, true);
    } else {
        $(this).addInputError(errorMsg, false);
    }
}

//==================================================================================================================
//  Check for Errors.  This function is suitable for using in a jQuery event handler
//------------------------------------------------------------------------------------------------------------------
function checkForErrors(){
	$(this).checkForErrors();
    return true;
}

//==================================================================================================================
//  Remove Errors.  This function is suitable for using in a jQuery event handler
//------------------------------------------------------------------------------------------------------------------
function removeErrors(){
	$(this).removeErrors();
}

//==================================================================================================================
//  add focus class from FORM LABEL.  This function is suitable for using in a jQuery event handler
//------------------------------------------------------------------------------------------------------------------
function addFocusClass(){
    $(this).addFocusClass();
}

//==================================================================================================================
//  remove focus class from FORM LABEL.  This function is suitable for using in a jQuery event handler
//------------------------------------------------------------------------------------------------------------------
function removeFocusClass(){
    $(this).removeFocusClass();
}

//==================================================================================================================
//  Initialize focus class for FORM LABEL.  This function is suitable for using in a jQuery event handler
//------------------------------------------------------------------------------------------------------------------
function initializeFocusClass(){
    $(this).initializeFocusClass();
}

//==================================================================================================================
//  Format Currency amount to two decimal points for FORM INPUT
//------------------------------------------------------------------------------------------------------------------
function formatCurrencyAmount(num) {
    if (num == '') {return '';}

    num = Number(num.toString().replace(/\$|\,/g, ''));
    num = Math.round((num + Number.EPSILON) * 100) / 100;
    if (isNaN(num)) {
        return "0.00";
    }
    return num.toFixed(2);
}

//==================================================================================================================
//  Apply Standard focus class to FORM LABEL
//------------------------------------------------------------------------------------------------------------------
$(document).ready(function() {
    $('input:not([type="date"],[type="hidden"],[type="checkbox"],[type="radio"],[type="button"],[type="submit"])').initializeFocusClass();
    $("[id^=visible]").initializeFocusClass();
    $('input:not([type="date"],[type="hidden"],[type="checkbox"],[type="radio"],[type="button"],[type="submit"])').focus(addFocusClass);
    $('input:not([type="date"],[type="hidden"],[type="checkbox"],[type="radio"],[type="button"],[type="submit"])').focusout(removeFocusClass);
    $('input, select, textarea').focus(removeErrors);
    $('input, select, textarea').blur(checkForErrors);
    $('input, select, textarea').on('invalid', addInputError);
});

/* makeURLAbsolute is cribbed from jQuery Mobile, and modified to suit our needs.*/
/*!
* jQuery Mobile 1.4.5
* Git HEAD hash: 68e55e78b292634d3991c795f06f5e37a512decc <> Date: Fri Oct 31 2014 17:33:30 UTC
* http:/ /jquerymobile.com
*
* Copyright 2010, 2014 jQuery Foundation, Inc. and other contributors
* Released under the MIT license.
* http:/ /jquery.org/license
*
*/

/*Parse a URL into a structure that allows easy access to
all of the URL components by name.*/
function parseUrl( url ) {
	var matches = new RegExp('^\\s*(((([^:\\/#\\?]+:)?(?:(\\/\\/)((?:(([^:@\\/#\\?]+)(?:\\:([^:@\\/#\\?]+))?)@)?(([^:\\/#\\?\\]\\[]+|\\[[^\\/\\]@#?]+\\])(?:\\:([0-9]+))?))?)?)?((\\/?(?:[^\\/\\?#]+\\/+)*)([^\\?#]*)))?(\\?[^#]+)?)(#.*)?').exec( url || "" ) || [];

	/* Create an object that allows the caller to access the sub-matches
	   by name. Note that IE returns an empty string instead of undefined,
	   like all other browsers do, so we normalize everything so its consistent
	   no matter what browser we're running on. */
	return {
		href:         matches[  0 ] || "",
		hrefNoHash:   matches[  1 ] || "",
		hrefNoSearch: matches[  2 ] || "",
		domain:       matches[  3 ] || "",
		protocol:     matches[  4 ] || "",
		doubleSlash:  matches[  5 ] || "",
		authority:    matches[  6 ] || "",
		username:     matches[  8 ] || "",
		password:     matches[  9 ] || "",
		host:         matches[ 10 ] || "",
		hostname:     matches[ 11 ] || "",
		port:         matches[ 12 ] || "",
		pathname:     matches[ 13 ] || "",
		directory:    matches[ 14 ] || "",
		filename:     matches[ 15 ] || "",
		search:       matches[ 16 ] || "",
		hash:         matches[ 17 ] || ""
	};
}

/*Turn relPath into an asbolute path. absPath is
an optional absolute path which describes what
relPath is relative to.*/
function makePathAbsolute( relPath, absPath ) {
	var absStack,
		relStack,
		i, d;

	if ( relPath && relPath.charAt( 0 ) === "/" ) {
		return relPath;
	}

	relPath = relPath || "";
	absPath = absPath ? absPath.replace( /^\/|(\/[^\/]*|[^\/]+)$/g, "" ) : "";

	absStack = absPath ? absPath.split( "/" ) : [];
	relStack = relPath.split( "/" );

	for ( i = 0; i < relStack.length; i++ ) {
		d = relStack[ i ];
		switch ( d ) {
			case ".":
				break;
			case "..":
				if ( absStack.length ) {
					absStack.pop();
				}
				break;
			default:
				absStack.push( d );
				break;
		}
	}
	return "/" + absStack.join( "/" );
}

/*Turn the specified relative URL into an absolute one. This function
can handle all relative variants (protocol, site, document, query, fragment).
 modified to omit the search and hash part of the URL.*/
function makeUrlAbsolute( relUrl, absUrl ) {
	var relObj = parseUrl( relUrl );
	if (relObj.protocol !== "") {
		return relUrl;
	}
	if ( absUrl === undefined ) {
		absUrl = window.location.href;
	}
	var absObj = parseUrl( absUrl );


	var protocol = relObj.protocol || absObj.protocol;
	var doubleSlash = relObj.protocol ? relObj.doubleSlash : ( relObj.doubleSlash || absObj.doubleSlash );
	var authority = relObj.authority || absObj.authority;
	var hasPath = relObj.pathname !== "";
	var pathname = makePathAbsolute( relObj.pathname || absObj.filename, absObj.pathname );

	return protocol + doubleSlash + authority + pathname;
}

function compareURLs(url1, url2) {
	var absUrl1 = makeUrlAbsolute(url1);
	var absUrl2 = makeUrlAbsolute(url2);
	return absUrl1 === absUrl2;
}

function injectlinks(source, target) {
	/* iterate over all source links.*/ 
	$("#"+source+" li>a").each(function() {
		/* check for duplicate href.*/
		var sourceHref = $( this ).attr('href');
		if (sourceHref != "") {
			var inject = true;
			$("#mobileNavbar > ul > ul > li>a").each(function() {
				if (compareURLs(sourceHref,$( this ).attr('href'))) {
					inject=false;
				}
			});
			/* inject non-duplicates.*/
			if (inject) {
			    var injectedLinks = $( this ).clone();
                injectedLinks.attr("id", "mobile" + this.id);
                $("#"+target).append($(injectedLinks).wrap("<li></li>").parent());
				$(document).trigger("linkInjected", this);
			}
		}

	});
}
