var pageName, pageNav, getElementsByClassName;	// Global variable declarations. Keep the number as low as possible.

/*global document, navigator, window, ServiceForm, LiveValidation, Validate, emailNotice */

/*
	Who: Andrew Noyes, Link Engineering Company
	What: Main JavaScript library for Linkeng.com
	When: August 19th, 2008
	
	Notes: Parts of this document, particularly the contact page, require that
	the jQuery JavaScript library be loaded into the browser before this code
	is executed. jQuery can be acquired for free at http://www.jquery.com/.
*/

function addLoadEvent(fun) {	// Adds window.onload events to current queue
	var oldOnload = window.onload;
	if (typeof window.onload !== 'function') {
		window.onload = fun;
	} else {
		window.onload = function () {
			if (oldOnload) {
				oldOnload();
			}
			fun();
		};
	}
}

addLoadEvent(function () {	// Acquires the body ID
	pageName = document.getElementsByTagName('body')[0].id;
});

/*
	getElementsByClassName Developed by Robert Nyman, http://www.robertnyman.com
	Code/licensing: http://code.google.com/p/getelementsbyclassname/
*/
getElementsByClassName = function (className, tag, elm) {
	if (document.getElementsByClassName) {
		getElementsByClassName = function (className, tag, elm) {
			elm = elm || document;
			var elements = elm.getElementsByClassName(className), nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null, returnElements = [], current, q;
			for (q = 0; q < elements.length; q++) {
				current = elements[q];
				if (!nodeName || nodeName.test(current.nodeName)) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	} else if (document.evaluate) {
		getElementsByClassName = function (className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "), classesToCheck = "", xhtmlNamespace = "http://www.w3.org/1999/xhtml", namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null, returnElements = [], elements, node, 	j;
			for (j = 0; j < classes.length; j++) {
				classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
			}
			try	{
				elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
			} catch (e) {
				elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
			}
			while ((node = elements.iterateNext())) {
				returnElements.push(node);
			}
			return returnElements;
		};
	} else {
		getElementsByClassName = function (className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "), classesToCheck = [], elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag), current, returnElements = [], match, k, l, m;
			for (k = 0; k < classes.length; k++) {
				classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
			}
			for (l = 0; l < elements.length; l++) {
				current = elements[l];
				match = false;
				for (m = 0; m < classesToCheck.length; m++) {
					match = classesToCheck[m].test(current.className);
					if (!match) {
						break;
					}
				}
				if (match) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	return getElementsByClassName(className, tag, elm);
};

var Client = {	// Provides information about the user agent through three properties: browser, version, and os
	dataBrowser: [
		{string: navigator.userAgent, subString: "Chrome", identity: "Chrome"},
		{string: navigator.vendor, subString: "Apple", identity: "Safari"},
		{prop: window.opera, identity: "Opera"},
		{string: navigator.userAgent, subString: "Firefox", identity: "Firefox"},
		{string: navigator.userAgent, subString: "MSIE", identity: "Explorer", versionSearch: "MSIE"},
		{string: navigator.userAgent, subString: "Gecko", identity: "Mozilla", versionSearch: "rv"}
	],
	dataOS: [
		{string: navigator.platform, subString: "Win", identity: "Windows"},
		{string: navigator.platform, subString: "Mac", identity: "Mac"},
		{string: navigator.platform, subString: "Linux", identity: "Linux"}
	],
	searchString: function (data) {
		var k, dataString, dataProp;
		for (k = 0; k < data.length; k++) {
			dataString = data[k].string;
			dataProp = data[k].prop;
			this.versionSearchString = data[k].versionSearch || data[k].identity;
			if (dataString) {
				if (dataString.indexOf(data[k].subString) !== -1) {
					return data[k].identity;
				} else if (dataProp) {
					return data[k].identity;
				}
			}
		}
		return "Unknown";
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index === -1) {
			return undefined;
		}
		return parseFloat(dataString.substring(index + this.versionSearchString.length + 1));
	},
	init: function () {
		this.browser = this.searchString(this.dataBrowser);
		this.version = this.searchVersion(navigator.userAgent);
		this.os = this.searchString(this.dataOS);
	}
};
Client.init();

var Cookies = {		// Creates an object of cookie variables, as well as accessor and mutator methods
	vals: [],
	create: function (name, value, days) {
		var expires, date = new Date();
		if (days) {
			date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
			expires = "; expires =" + date.toGMTString();
		} else {
			expires = "";
		}
		document.cookie = name + " = " + value + "; path=/";
	},
	read: function (name) {
		var nameEQ = name + "=", cookieList = document.cookie.split(';'), n, current;
		for (n = 0; n < cookieList.length; n++) {
			current = cookieList[n];
			while (current.charAt(0) === ' ') {
				current = current.substring(1, current.length);
			}
			if (current.indexOf(nameEQ) === 0) {
				this.vals[name] = current.substring(nameEQ.length, current.length);
				return null;
			}
		}
		return null;
	},
	erase: function (name) {
		this.create(name, "", -1);
	}
};
Cookies.read('link');

var getData = {		// Pulls GET information from the URL and organizes it into vars property and provides an accessor method
	vars: [],
	retrieve: function () {
		var getString = window.location.href.toString().split('?')[1], getVars, m, varSplit;
		if (getString) {
			getVars = getString.split('&');
			for (m = 0; m < getVars.length; m++) {
				varSplit = getVars[m].split('=');
				this.vars[varSplit[0]] = varSplit[1];
			}
		}
	},
	value: function (query) {
		if (query in this.vars) {
			return this.vars[query];
		} else {
			return null;
		}
	}
};
getData.retrieve();

function Navigation(contParent, navParent, first) {	// Navigation class constructor for main page JavaScript navigation
	this.contParent = getElementsByClassName(contParent)[0];
	this.navParent = getElementsByClassName(navParent)[0];
	this.last = 0;
	if (getData.value('page')) {
		this.first = parseInt(getData.value('page'), 0);
		this.last = this.first;
	} else if (Cookies.vals.link) {
		this.first = parseInt(Cookies.vals.link, 0);
		this.last = this.first;
	} else {
		if (first) {
			this.first = first;
		} else {
			this.first = 0;
		}
	}
	if (typeof this.navParent === 'object') {
		this.navLinks = this.navParent.getElementsByTagName('a');
		this.navLinks[this.first].className = 'on';
		this.createNavLinks();
	}
}

Navigation.prototype.indexer = function (childClass, headBool) {	// Indexer method for Navigation class. Creates an object array of child elements and hides the desired elements from view
	var headImgs = getElementsByClassName('headImg'), h2elms = [], i, wrapper;
	this.headBool = headBool;
	this.headings = [];
	this.headings.push(getElementsByClassName('mainHeader')[0]);
	if (typeof this.contParent === 'object') {
		this.index = getElementsByClassName(childClass);
		for (i = 0; i < this.index.length; i++) {
			if (i === this.first) {
				$("div.first").css('display', 'none');
				this.index[i].style.display = 'block';
			}
			if (headBool && i > 0) {
				h2elms[i] = this.index[i].getElementsByTagName('h2')[0];
				this.headings[i] = document.createElement('div');
				this.headings[i].className = 'mainHeader';
				if (headImgs[i]) {
					this.headings[i].appendChild(headImgs[i]);
				}
				if (i !== this.first) {
					this.headings[i].style.display = 'none';
				}
				this.headings[i].appendChild(h2elms[i]);
				wrapper = getElementsByClassName('wrapper')[0];
				wrapper.insertBefore(this.headings[i], this.navParent);
			}
		}
	}
	if (this.first !== 0) {
		this.headings[0].style.display = 'none';
	}
};

Navigation.prototype.swap = function (id) {		// Swap method for Navigation class. Switches view from previous element to called element
	this.index[this.last].style.display = 'none';
	this.navLinks[this.last].className = 'off';
	this.index[id].style.display = 'block';
	this.navLinks[id].className = 'on';
	if (this.headBool) {
		this.headings[this.last].style.display = 'none';
		this.headings[id].style.display = 'block';
	}
	this.last = id;
	Cookies.erase('link');
	Cookies.create('link', id, 1);
};

Navigation.prototype.clickCreator = function (id) {		// Closure function for Navigation Class links
	var navObj = this;	// Required to preserve object scope
	return function () {
		navObj.swap(id);	// Must be used as method of navObj to preserve scope
		return false;
	};
};

Navigation.prototype.createNavLinks = function () {		// Attaches onclick event to Navigation object's menu links
	for (var j = 0; j < this.navLinks.length - 1; j++) {
		this.navLinks[j].onclick = this.clickCreator(j);
	}		
};

addLoadEvent(function () {
	if (pageName === 'index') {
		pageNav = new Navigation('contentwrap', 'tertiaryNav', 0);
		pageNav.indexer('content', true);		
	}
});

function NavGen(parentElm, childClass, navClass) {	// Class constructor for Navigation Generator class. Must happen at window.onload.
	this.last = 0;	
	this.show = 0;
	this.indexer(parentElm, childClass);
	this.createMenu(navClass);
	Cookies.erase('link');
}

NavGen.prototype.indexer = function (parentElm, childClass) {	// Creates an index of content boxes and menu items
	if (getData.value('carpost')) {
		this.show = getData.value('carpost');
		this.last = this.show;
	}
	this.parent = getElementsByClassName(parentElm)[0];
	if (this.parent) {
		this.index = getElementsByClassName(childClass);
	}
	if (this.index) {
		this.headings = [];
		for (var p = 0; p < this.index.length; p++) {
			this.headings[p] = this.index[p].getElementsByTagName('h3');
			if (p !== this.show) {
				this.index[p].style.display = 'none';
			}
		}
	}
};

NavGen.prototype.clickMaker = function (id) {	// Closure function constructor for links
	var thisObj = this;		// Preserves object scope
	return function () {
		thisObj.swap(id);
		return false;
	};
};

NavGen.prototype.swap = function (id) {		// NavGen method for performing a content box swap
	this.index[this.last].style.display = 'none';
	this.index[id].style.display = 'block';
	this.links[this.last].className = 'off';
	this.links[id].className = 'on';
	this.last = id;
};

function Submenu() {	// Submenu constructor, used only for NavGen
	this.list = document.createElement('ul');
	this.list.className = 'level2';
	this.childList = document.createElement('li');
	this.childList.className = 'submenu';
	this.childList.appendChild(this.list);
	this.listItems = [];
}

Submenu.prototype.addListItem = function (link) {	// Mutator method for adding link pointers to object.listItems array
	var thisItem = document.createElement('li');
	thisItem.appendChild(link);
	this.listItems.push(thisItem);
	this.list.appendChild(thisItem);
};

NavGen.prototype.createMenu = function (navClass) {		// Creates navigation menu
	if (this.headings && this.index) {
		this.nav = document.createElement('ul');
		this.nav.className = navClass;
		this.links = [];
		var q, link, headingText, r, subclass = new RegExp('sub'), newList = true, submenus = [], newLi, wrapper;
		for (q = 0; q < this.index.length; q++) {
			link = document.createElement('a');
			headingText = this.headings[q][0].firstChild.nodeValue;
			link.appendChild(document.createTextNode(headingText));
			link.setAttribute('href', '#' + this.index[q].getAttribute("id"));
			link.onclick = this.clickMaker(q);
			this.links.push(link);
		}
		this.links[this.show].className = 'on';
		for (r = 0; r < this.links.length; r++) {
			if (subclass.test(this.index[r].className)) {
				if (newList) {
					submenus.unshift(new Submenu());
				}
				submenus[0].addListItem(this.links[r]);
				newList = false;
				this.nav.appendChild(submenus[0].childList);
			} else {
				newList = true;
				newLi = document.createElement('li');
				newLi.appendChild(this.links[r]);
				this.nav.appendChild(newLi);
			}
		}
		wrapper = getElementsByClassName('wrapper')[0];
		wrapper.insertBefore(this.nav, this.parent);
	}
};

addLoadEvent(
	function () {
		var pages = ['careers', 'quality', 'news', 'about'], t;
		for (t in pages) {
			if (pages[t] === pageName) {
				pageNav = new NavGen('contentwrap', 'content', 'tertiaryNav');
				break;
			}
		}
	}
);

var contactNav = {};	// Navigation for Contact page menu

contactNav.last = 0;	// Last content box to be shown

contactNav.lastanch = 0;	// Last anchor to be called

contactNav.toggle = function (id) {		// Toggles the submenus in navigation menu
	if (id === this.last) {
		return;
	} else if (this.last !== id) {
		var f, count = 0;
		for (f = 0; f < id; f++) {
			count += this.submenus.counts[f];
		}
		this.swap(count);
		$(this.submenus.menus[id]).slideDown('fast');
		this.toggles[id].className = 'on';
		$(this.submenus.menus[this.last]).slideUp('fast');
		this.toggles[this.last].className = 'off';
		this.last = id;
	}
};

contactNav.toggleMaker = function (id) {	// Closure function for creating toggle onclick event listener
	return function () {
		contactNav.toggle(id);
		return false;		
	};
};

contactNav.swap = function (id) {	// Method for swapping content boxes
	this.index[this.lastanch].style.display = 'none';
	this.anchors[this.lastanch].className = 'off';
	this.index[id].style.display = 'block';	
	this.anchors[id].className = 'on';
	this.lastanch = id;
};

contactNav.clickMaker = function (id) {		// Closure function for links in contact navigation menu
	var scope = this;
	return function () {
		scope.swap(id);
		return false;
	};
};

contactNav.init = function (toggleClass, submenuClass, contentClass) {		// Initializes the object. Must happen at window.onload.
	Cookies.erase('link');
	var a, b, c, d, anchArray = [];
	this.submenus = [];
	this.submenus.counts = [];
	this.submenus.menus = getElementsByClassName(submenuClass);
	this.toggles = getElementsByClassName(toggleClass);
	this.index = getElementsByClassName(contentClass);
	this.anchors = [];
	this.submenuHeight = 0;
	if (this.submenus.menus.length > 0 && this.toggles.length > 0) {
		for (a = 0; a < this.submenus.menus.length; a++) {
			if (a !== this.last) {
				this.submenus.menus[a].style.display = 'none';
			} else if (a === this.last) {
				this.toggles[a].className = 'on';
			}
			anchArray = this.submenus.menus[a].getElementsByTagName('a');
			this.submenus.counts.push(anchArray.length);
			for (b = 0; b < anchArray.length; b++) {
				this.anchors.push(anchArray[b]);
			}
			this.toggles[a].onclick = this.toggleMaker(a);
			if ($(this.submenus.menus[a]).height() > this.submenuHeight) {
				this.submenuHeight = $(this.submenus.menus[a]).height();
			}
		}
		for (d = 0; d < this.submenus.menus.length; d++) {
			$(this.submenus.menus[d]).height(this.submenuHeight);
		}
		$(this.submenus.menus[this.submenus.menus.length - 1]).css("border-bottom", "0px");
	}
	if (this.index.length > 0) {
		for (c = 0; c < this.index.length; c++) {
			if (c !== this.last) {
				this.index[c].style.display = 'none';
			}
			else if (c === this.last) {
				this.anchors[c].className = 'on';
			}
			this.anchors[c].onclick = this.clickMaker(c);
		}
	}
};

(function () {	// Flags e-mail links
	if (Client.os === 'Win' && Client.browser === 'Explorer' && Client.version <= 6.0) {
		addLoadEvent(function () {
			var links = document.getElementsByTagName('a'), o;
			for (o = 0; o < links.length; o++) {
				if (links[o].getAttribute('href').slice(0, 6) === 'mailto:') {
					links[o].className = 'email';
				}
			}
		});
	}
})();

(function () {	// Flags PDF Links
	addLoadEvent(function () {
		var links = document.getElementsByTagName('a'), p, href, fileType;
		for (p = 0; p < links.length; p++) {
			href = links[p].getAttribute('href');
			fileType = href.slice(href.length - 4, href.length);
			if (fileType === '.pdf') {
				links[p].target = '_blank';
				links[p].className = 'pdf';
			}
		}
	});
})();

(function () {
	addLoadEvent(function () {
		var links = document.getElementsByTagName('a'), f, href, protocol, fileType, rel;
		for (f = 0; f < links.length; f++) {
			href = links[f].getAttribute('href');
			protocol = href.slice(0, 6);
			fileType = href.slice(href.length - 4, href.length);
			rel = links[f].getAttribute('rel');
			if (href === 'https:' || href.slice(0.5) === 'http') {
				links[f].target = '_blank';
				links[f].className = 'external';
			}
			if (fileType === '.pdf') {
				links[f].target = '_blank';
				links[f].className = 'pdf';
			}
			if (rel === 'external') {
				links[f].target = '_blank';
				links[f].className = 'external';
			}
		}
	});
})();

// Erases the 'link' cookie when the 'homelink' button is clicked
(function () {
	addLoadEvent(function () {
		var homelink = document.getElementById('homelink');
		homelink.onclick = function () {
			Cookies.erase('link');
			return true;	
		};
	});
})();

function serviceFormInit() {	// Requires Live Validation library to be loaded prior. http://www.livevalidation.com/
	addLoadEvent(function () {
		var formRef, lastFieldset, noticeText;
		formRef = document.getElementsByTagName('form')[1];
		lastFieldset = document.getElementById('formActions');
		emailNotice = document.createElement('p');
		noticeText = '* The existence of this address has not been verified, only the format has been examined.';
		emailNotice.appendChild(document.createTextNode(noticeText));
		emailNotice.className = 'notice';
		emailNotice.style.display = 'none';
		formRef.insertBefore(emailNotice, lastFieldset.nextSibling);
		
		// E-mail field
		ServiceForm.email = new LiveValidation('email', {
			validMessage: "Valid*",
			onValid: function () {
				this.insertMessage(this.createMessageSpan());
				this.addFieldClass();
				this.formObj.fields[1].validate();
				$(emailNotice).fadeIn(125);
			},
			onInvalid: function () {
				emailNotice.style.display = 'none';
				this.insertMessage(this.createMessageSpan());
				this.addFieldClass();
			},
			wait: 250,
			onlyOnBlur: false
		});
		ServiceForm.email.add(Validate.Email, {failureMessage: "This is not a valid e-mail address."});
		ServiceForm.email.add(Validate.Presence, {failureMessage: "An e-mail address is required."});
		ServiceForm.email.element.onblur = function () {
			return true;
		};
		
		// E-mail Confirmation Field
		ServiceForm.confirmEmail = new LiveValidation('confemail', {
			validMessage: "Match",
			wait: 500
		});
		ServiceForm.confirmEmail.add(Validate.Presence, {
			failureMessage: "An e-mail address is required."
		});
		ServiceForm.confirmEmail.add(Validate.Confirmation, {
			match: "email"
		});
		ServiceForm.confirmEmail.element.onblur = function () {
			return true;
		};
		
		// Company Field
		ServiceForm.company = new LiveValidation('company', {
			onValid: function () {
				return;
			},
			onlyOnBlur: true,
			onlyOnSubmit: true
		});
		ServiceForm.company.add(Validate.Presence, {
			failureMessage: "Please enter a company name."
		});
		
		// First Name Field
		ServiceForm.firstName = new LiveValidation('firstname', {
			onValid: function () {
				return;
			},
			onlyOnBlur: true,
			onlyOnSubmit: true
		});
		ServiceForm.firstName.add(Validate.Presence, {
			failureMessage: "Please enter your first name."
		});
		
		// Last Name Field
		ServiceForm.lastName = new LiveValidation('lastname', {
			onValid: function () {
				return;
			},
			onlyOnBlur: true,
			onlyOnSubmit: true
		});
		ServiceForm.lastName.add(Validate.Presence, {
			failureMessage: "Please enter your last name."
		});
		
		// Phone Field
		ServiceForm.phone = new LiveValidation('phone', {
			onValid: function () {
				return;
			},
			onlyOnBlur: true,
			onlyOnSubmit: true
		});
		ServiceForm.phone.add(Validate.Presence, {
			failureMessage: "Please enter a phone number."
		});
		ServiceForm.phone.add(Validate.Custom, {
			against: function (value) {
				var inputValue = value.replace(/[^\d]/g, '');
				if (inputValue.length >= 10) {
					return true;
				}
				else {
					return false;
				}
			},
			failureMessage: "The number you entered isn't a valid phone number.",
			onlyOnSubmit: true
		});
		
		// phoneNotice = document.createElement('span');
		// phoneNotice.appendChild(document.createTextNode('Make sure to include any country codes or area codes.'));
		// phoneNotice.className = 'tip';
		// formRef.insertBefore(phoneNotice, ServiceForm.phone.element.nextSibling);
		
		// Submit events
		ServiceForm.submit = document.getElementById('serviceSubmit');
		ServiceForm.submit.onmousedown = function () {
			ServiceForm.submit.className = 'click';
		};
		ServiceForm.submit.onmouseup = function () {
			ServiceForm.submit.className = 'unclick';
		};
		ServiceForm.clear = document.getElementById('serviceClear');
		ServiceForm.clear.onclick = function () {
				ServiceForm.email.removeMessageAndFieldClass();
				ServiceForm.confirmEmail.removeMessageAndFieldClass();
				ServiceForm.company.removeMessageAndFieldClass();
				ServiceForm.firstName.removeMessageAndFieldClass();
				ServiceForm.lastName.removeMessageAndFieldClass();
				ServiceForm.phone.removeMessageAndFieldClass();
				emailNotice.style.display = 'none';
			return true;
		};
	});
}

function highlightScroll($header, duration, color) {
    duration = duration || 2500;
    color = color || '#FFE770';
    $header = $($header);
    
    var $pane = $header.closest('.content'),
        $link = $('ul.tertiaryNav a[href="#' + $pane.attr('id') + '"]'),
        distFromTop;
        
    $($link, $header, $pane).stop(true, true);  // hammertime!
        
    $link
        .click()
        .effect('highlight', { color: color }, duration);
        
    $header.effect('highlight', { color: color }, duration);
    
    distFromTop = $pane.scrollTop() + ($header.offset().top - $pane.offset().top);
    if (jQuery.browser.msie && jQuery.browser.version < 9)
      $pane.scrollTop(distFromTop);
    else
      $pane.animate({ scrollTop: distFromTop }, duration / 5);
}



function loadHash() {
    if (window.location.hash) {
        var ref = "[href=" + window.location.hash + "]";
        $(".tertiaryNav a" + ref).click();
    }
}