///////////////////////////////////////////////////////////////////////////////////////
// InsideSales.com Analytics Start
///////////////////////////////////////////////////////////////////////////////////////

window.IS = {

	SESSION: null,

	// manage settings
	// object holding boolean values for
	// enables or disabled functions
	modules: {
		// enable/disable page stay time tracking
		pages: false,

		// enable/disable user link click tracking
		clicks: false,

		// enable/disable browser information tracking
		browser: false,

		// enable/disable promo code to lead source
		promotions: false
	},

	init: function () {
		var d = new Date;
		
		// first check the visitor id
		if (!this.cookie.check(this.cookie.cookie_types.visitor_id))
			this.cookie.cook(this.cookie.cookie_types.visitor_id, 
				(d.getTime().toString() + Math.round(Math.random() * 10000)), 400000);
		
		if (this.modules.promotions) this.data.promotions = true;

		if (this.modules.pages) this.analytics.pages();

		if (this.modules.clicks) this.analytics.clicks();

		this.url = document.URL;

		if (this.cookie.check(this.cookie.cookie_types.session_id))
			this.SESSION = this.cookie.check(this.cookie.cookie_types.session_id);
		else {
			this.SESSION = d.getTime().toString() + Math.round(Math.random() * 10000);

			// save session id
			this.cookie.cook(this.cookie.cookie_types.session_id, this.SESSION);

			// save session start time
			this.cookie.cook(this.cookie.cookie_types.website_enter, (
				d.getFullYear() +
				(d.getMonth() + 1 < 10 ? "0" + (d.getMonth() + 1) : d.getMonth() + 1) +
				(d.getDate() < 10 ? "0" + d.getDate() : d.getDate()) +
				(d.getHours() < 10 ? "0" + d.getHours() : d.getHours()) +
				(d.getMinutes() < 10 ? "0" + d.getMinutes() : d.getMinutes()) +
				(d.getSeconds() < 10 ? "0" + d.getSeconds() : d.getSeconds())
			));
			
			// running for the first time, initialize browser and engine methods
			this.analytics.engines();

			if (this.modules.browser) this.analytics.browser();
		}
		
		IS.cookie.cook(IS.cookie.cookie_types.form_url, location.href.replace(location.search, ""));
		IS.cookie.cook(IS.cookie.cookie_types.form_name, "");

		this.data.dump();

		return this;
	},

	/**
	 *
	 * Methods and variables for cookie object:
	 *	(String)	path:			cookie store path, default is root directory
	 *	(Number)	path:			cookie expiration time, default to 0 for session expiration
	 *	(Object)	cookie_types:	object holder for analytics cookie's names. name may be edited
	 *								using IS's method 'cookie_rename'
	 *	(Function)	cook:			creates a new cookie
	 *	(Function)	check:			returns a cookie's value
	 *	(Function)	query:			returns an array of cookies whose name matches the RegEx object
	 *	(Function)	throw_out:		deletes a cookie
	 *
	 */
	cookie: {
		// cookie store path, default is the root directory
		path: "/",
		
		// default expiration (x minutes from now)
		exp: 0,
		
		External_ID: {
			"is_cookie": 		"Analytics_Jeremiah_session_id",
			"external_cookie": 	"session_id"
		},

		// stores names used in search engine cookies
		cookie_types: {
			visitor_id:			"Analytics_Visitor_id",
			session_id:			"Analytics_Session_id",
			search_url:			"Analytics_Search_referrer_url",
			search_keyword:		"Analytics_Search_search_keyword",
			search_engine:		"Analytics_Search_search_engine_name",
			search_type:		"Analytics_Search_type",
			affiliate_id:		"Analytics_Affiliate_id",
			affiliate_name:		"Analytics_Affiliate_name",
			default_affiliate:	"Analytics_Affiliate_default",
			referrere_name:		"Analytics_Referrer_name",
			website_enter:		"Analytics_Website_enter",
			page_log:			"Analytics_Page_log",
			page_log_temp:		"Analytics_Page_log_TEMP",
			page_log_temp_2:	"Analytics_Page_log_TEMP2",
			lead_source_id:		"Analytics_Source_id",
			lead_source_name:	"Analytics_Source_name",
			promo_code:			"Analytics_Promotion_code",
			promo_name:			"Analytics_Promotion_name",
			user_browser_name:	"Analytics_User_browser_name",
			user_os:			"Analytics_User_platform",
			user_lang:			"Analytics_User_platform_language",
			form_url:			"Analytics_Form_url",
			form_name:			"Analytics_Form_name"
		},

		cookie_prefix: {
			ppc:				"Analytics_PPC_",
			link:				"Analytics_Link_",
			page:				"Analytics_Page_"
		},
		
		search_types: {
			ppc: 				"PPC",
			organic: 			"Organic"
		},

		// set a cookie with a name, value
		// and expiration date (in minutes)
		// name = name of cookie, required
		// val = value of cookie, required
		// min_exp = number value of minutes until expiration, optional
		cook: function (name, val, min_exp) {
			var date = new Date(),
				expiration = "",
				MILLI_SECOND = 60000;
				
			// if min_exp was not definded, check if we have a default set
			if (!min_exp && this.exp)
				min_exp = this.exp;

			if (min_exp && !isNaN(min_exp)) {
				date.setTime(date.getTime() + min_exp * MILLI_SECOND);
				expiration = "; expires=" + date.toGMTString();
			}

			document.cookie = name + "=" + escape(val) + expiration + ";path=" + this.path;

			return this;
		},

		// returns a cookie's value
		// returns false if cookie is not found
		// name = cookie's name, required
		check: function (name) {
			var cookie_name = name + "=",
				cookie_batch = document.cookie.split(';'),
				cookie = "";

			for (var i = 0; i < cookie_batch.length; i++) {
				cookie = cookie_batch[i];

				while (cookie.charAt(0) === ' ')
					cookie = cookie.substring(1, cookie.length);

				if (cookie.indexOf(cookie_name) === 0)
					return unescape(cookie.substring(cookie_name.length, cookie.length));
			}

			return "";
		},

		// works much like the check method, except
		// it uses regular expression to look for
		// cookies and it returns and array of results
		// returns an empty array if not cookies match search
		// query = RegEx object used in search
		query: function (query) {
			var cookie_batch = document.cookie.split(';'),
				cookie = "",
				cookies = [];

			for (var i = 0; i < cookie_batch.length; i++) {
				cookie = cookie_batch[i];

				while (cookie.charAt(0) === ' ')
					cookie = cookie.substring(1, cookie.length);

				if (query.test(cookie)) {
					cookies[cookies.length] = [];
					cookies[cookies.length - 1][0] = cookie.split("=", 1)[0];
					cookies[cookies.length - 1][1] = unescape(IS.cookie.check(cookie.split("=", 1)[0]));
				}
			}

			return cookies;
		},

		// clear a cookie
		// name = cookie's name, required
		throw_out: function (name) {
			this.cook(name, "", -1);

			return this;
		}
	},

	/**
	 *
	 * Methods and variables for search engine data management:
	 *  Search methods and variables:
	 *	(String)	engine:						search engine's name
	 *	(String)	q:							search engine's search query paramenter
	 *	(String)	referrers:					copy of DOM's document.referrer
	 *	(String)	domain:						website's domain
	 *	(Object)	search_engines:				object holding all possible search engines
	 *											along with their full name and search parameter.
	 *											search engines can be added using IS's 'add_search_engine' method
	 *	(Object)	search_engine_analytics:	object holding search engine analytics parameters.
	 *											this object must be managed with IS's 'add_analytics' method
	 *	(String)	aff_param:					affiliate id parameter
	 *	(Object)	sources:					lead source ids for organic searches, ppc searches, affiliate links
	 *                                          and default option. lead soruces can be added using IS's 'set_sources' method
	 *	(Object)	defaults:					if no search engine if found, and no affiliate is found
	 *											either, script will default to this object in search of a referrer
	 *	(String)	ppc_prefix:					prefix added to all PPC cookies
	 *	(Function)	engines:					parses referrers string for search engine and search
	 *											keyword information
	 *
	 *  Click tracing methods and variables:
	 *	(String)	analytics_links:			class name given to links for tracking
	 *	(Function)	clicks:						adds a click method to all 'a' tags with a valid href
	 *											attribute and a class name of this.analytics_links
	 *	(Function)	tick_click:					tracks clicks made to an analytics link
	 *
	 *  Page stay time tracing methods and variables:
	 *	(Number)	load:						enter page
	 *	(Number)	unload:						exit page
	 *	(Function)	pages:						method for calculating page stay time and
	 *											storing it in a cookie
	 *
	 *	Browser tracking method:
	 *	(Function)	browser:					method used to store basic browser and computer data
	 *
	 */
	analytics: {

		// search engine
		engine: "",

		// seach engine's search varlue parameter
		// default is 'q'
		param: "q",

		// current localtion referrer
		referrer: document.referrer,

		// we use this so we do not capture referrer
		// data when in our own domain
		domain: location.host,

		// holder for search engines data
		// name: required
		// para: optional
		search_engines: {
			// http://www.google.com/
			google:		{name: "Google"},
			
			// http://www.bing.com/
			bing:		{name: "Bing"},
			
			// http://www.alexa.com/
			alexa:		{name: "Alexa"},
			
			// http://www.ask.com/
			ask:		{name: "Ask"},
			
			// http://www.altavista.com/
			altavista:	{name: "AltaVista"},
			
			// http://www.lycos.com/
			lycos:		{name: "Lycos", param: "query"},
			
			// http://www.lycos.com/
			yahoo:		{name: "Yahoo", param: "p"}
		},

		// holder for search engine analytics
		search_engine_analytics: {},

		// default affiliate search parameter
		aff_param: "a",

		// holder for default referrers
		defaults: {},

		// lead sources
		sources: {
		
			// organic search lead sources
			org: {},
			
			// ppc search lead sources
			ppc: {},
			
			// referral search lead sources
			ref: {},
			
			// affiliate search lead sources
			aff: {},
			
			// promotion search lead sources
			pro: {},
			
			// default search lead source
			non: { "default": { name: "Unknown", id: 0 }, "direct": { name: "Direct", id: 0 } }
		},
		
		engines: function () {
			var default_affiliate = source_type = source_name = source_sufix = "";

			// now set the search engine and reset
			// the query search variable is needed
			for (var eng in this.search_engines)
				if (this.referrer.indexOf(eng) > -1) {
					this.engine = this.search_engines[eng].name;
					if ("param" in this.search_engines[eng])
						this.param = this.search_engines[eng].param;

					source_type = "org";
					source_name = this.engine.toLowerCase();

					break;
				}

			if (this.engine) {
				IS.url = this.referrer;
				
				// save the search type
				IS.cookie.cook(IS.cookie.cookie_types.search_type, IS.cookie.search_types.organic);

				// if we found a search engine, save it
				IS.cookie.cook(IS.cookie.cookie_types.search_engine, this.engine);

				// if the referrer has a search query
				// save it as well
				if (IS.get(this.param))
					IS.cookie.cook(IS.cookie.cookie_types.search_keyword, unescape(IS.get(this.param)));

				// after storing search engine and search data
				// check if this engine has an anaytics tool enabled
				if (this.engine in this.search_engine_analytics) {
					IS.url = location.href;
					
					// loop through the analytics object and store the data
					for (var ana in this.search_engine_analytics[this.engine])
						if (IS.get(this.search_engine_analytics[this.engine][ana])) {
							IS.cookie.cook(IS.cookie.cookie_prefix.ppc + ana, 
								unescape(IS.get(this.search_engine_analytics[this.engine][ana])));
							source_type = "ppc";
							// re-set the search type
							IS.cookie.cook(IS.cookie.cookie_types.search_type, IS.cookie.search_types.ppc);
						}
				}
			}

			else {
				// if no engine was found, check affiliates
				// first check for a hardcoded affiliate, then check the url
				IS.url = location.href;
				
				// if the url has a paramenter used by
				// our affiliates, save the affiliate id
				if (IS.get(this.aff_param) || IS.cookie.check(IS.cookie.cookie_types.default_affiliate)) {
					source_type = "aff";
					default_affiliate = IS.get(this.aff_param).substr(0, 6) || IS.cookie.check(IS.cookie.cookie_types.default_affiliate);
					
					// get the affiliate source
					if (default_affiliate in this.sources.aff)
						source_name = default_affiliate;
					else
						source_name = "default";
					
					// save the affiliate id
					IS.cookie.cook(IS.cookie.cookie_types.affiliate_id, unescape( IS.get(this.aff_param) ));
					
					// if the affiliate id is also stored as a lead source,
					// save it's affiliate name as well
					if ("affiliate" in this.sources.aff[source_name])
						IS.cookie.cook(IS.cookie.cookie_types.affiliate_name, this.sources.aff[source_name].affiliate);
				}
				
				// before defaulting, check for websites providing ppc
				else {
					// loop through all analytic engines
					for (var ana_engine in this.search_engine_analytics) {
					// loop through the analytics object and store the data
						for (var ana in this.search_engine_analytics[ ana_engine ]) {
							if (IS.get(this.search_engine_analytics[ ana_engine ][ ana ])) {
								IS.cookie.cook(IS.cookie.cookie_prefix.ppc + ana, 
									unescape(IS.get(this.search_engine_analytics[ ana_engine ][ ana ])));
								
								source_type = "ppc";
								source_name = "Google" /* ana_engine */;
								source_sufix = " Partner";
								
								// re-set the search type
								IS.cookie.cook(IS.cookie.cookie_types.search_type, IS.cookie.search_types.ppc);
							}
						}
					}
				}
				
				// if the affiliate id was not found, and we're not
				// working with PPC, default to our defaults list
				if (source_type === '') {
					for (var def in this.defaults) {
						if (this.referrer.indexOf(def) > -1) {
							IS.cookie.cook(IS.cookie.cookie_types.referrere_name, this.defaults[def]);
							source_type = "ref";
							source_name = this.defaults[def];
							break;
						}
					}
				}
			}

			if (!source_type || !source_name) {
				source_type = "non";
				
				// check for direct hits
				if (!this.referrer)
					source_name = "direct";
				else
					source_name = "default";
			}

			source_name = source_name.toLowerCase();
			
			// create lead source cookie
			if (source_type in this.sources) {
				if (source_name in this.sources[source_type]) {
					if ("id" in this.sources[source_type][source_name])
						IS.cookie.cook(IS.cookie.cookie_types.lead_source_id, this.sources[source_type][source_name].id);
					if ("name" in this.sources[source_type][source_name])
						IS.cookie.cook(IS.cookie.cookie_types.lead_source_name, this.sources[source_type][source_name].name + source_sufix);
				}
			}
			else {
				IS.cookie.cook(IS.cookie.cookie_types.lead_source_id, this.sources.non["default"].id);
				IS.cookie.cook(IS.cookie.cookie_types.lead_source_name, this.sources.non["default"].name);
			}
			
			// create a blank promo name and code cookies
			IS.cookie.cook(IS.cookie.cookie_types.promo_name, "");
			IS.cookie.cook(IS.cookie.cookie_types.promo_code, "");
			
			// create a blank log cookie
			IS.cookie.cook(IS.cookie.cookie_types.page_log, "");
			
			// finally save the referral url
			IS.cookie.cook(IS.cookie.cookie_types.search_url, unescape(this.referrer));
			
			return IS;
		},

		// used in track_click method
		// this is the class name the method
		// looks for before adding click event
		// handler. leave blank to tag all a
		// tags with a click event
		analytics_links: "analytics_link",

		// adds click tracking to links that
		// have a class of the value of the
		// this.analytics_links and have a value for href
		clicks: function () {
			var links = document.getElementsByTagName('a');
			for (var i = 0; i < links.length; i++)
				if (links[i].className.search(this.analytics_links) > -1 && links[i].href) {
					window.____new_click_handler____ = function (event) {
						IS.analytics.tick_click(event.target || event.srcElement);
					}

					if ("addEventListener" in links[i])
						links[i].addEventListener("click", window.____new_click_handler____, false);
					else if (links[i].attachEvent)
						links[i].attachEvent("onclick", window.____new_click_handler____);
				}
		},

		// when node is clicked, save the
		// event as a cookie
		tick_click: function (link) {
			// first find the link
			while (link.nodeName !== "A")
				link = link.parentNode;
			
			// create a click log
			var date = new Date,
				log = "Link: " + date.toLocaleTimeString() + " " + IS.timezone.init() + " " +
					(date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "/" +
					(date.getDate() < 10 ? "0" + date.getDate() : date.getDate()) + "/" +
					date.getFullYear() + " " + (link.title ? link.title : link.href);

			// update cookie
			if (IS.cookie.check(IS.cookie.cookie_types.page_log_temp_2))
				IS.cookie.cook(IS.cookie.cookie_types.page_log_temp_2, log + "\n" + 
					IS.cookie.check(IS.cookie.cookie_types.page_log_temp_2));
			else
				IS.cookie.cook(IS.cookie.cookie_types.page_log_temp_2, log);
		},

		// when user enters page
		load: (new Date).getTime(),

		// when user leaves page
		unload: null,
		
		// page log limit
		// 0 for unlimited (default)
		log_limit: 0,

		// for tracking page stay time
		pages: function () {
			var date = new Date,
				log = "Page: " + date.toLocaleTimeString() + " " + IS.timezone.init() + " " +
					(date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "/" +
					(date.getDate() < 10 ? "0" + date.getDate() : date.getDate()) + "/" +
					date.getFullYear() + " " + location.href.replace(location.search, '');
		
			// first log this page
			IS.cookie.cook(IS.cookie.cookie_types.page_log_temp, log);

			// define unload handler
			window.____new_unload_handler____ = function () {
				// declare scope's variables
				// page_cookie: is the name used to store page's stay time
				// past_time: is used to store a past stay time value
				var page_cookie = IS.cookie.cookie_prefix.page + 
						document.location.protocol + "//" + 
						document.location.hostname + 
						document.location.pathname,
					total_time = "",
					stay_time = "",
					page_log = "",
					past_time = 0,
					second = 60 * 24;

				// get the time of page unload
				IS.analytics.unload = (new Date).getTime();

				// first check is we have a cookie with a past stay time
				if (IS.cookie.check(page_cookie)) {
					// if so, save that stay time
					past_time = Number(IS.cookie.check(page_cookie)) * second;
					// and delete the old cookie
					IS.cookie.throw_out(page_cookie);
				}
				
				total_time = ((IS.analytics.unload - IS.analytics.load + past_time) / second).toFixed(2);
				stay_time = Number((IS.analytics.unload - IS.analytics.load) / second).toFixed(2);
				
				// alert("old time: " + past_time/second);
				// alert("stay time: " + stay_time);
				// alert("now time: " + total_time);
				
				// convert stay time to hh:mm:ss format
				stay_time = [stay_time, stay_time, stay_time];
				stay_time[0] = stay_time[0] / 60 / 60 > 1 ? Number((stay_time[1] / 60 / 60).toString().split(".")[0]) : 0;
				stay_time[1] = stay_time[1] / 60 > 1 ? (Number((stay_time[1] / 60).toString().split(".")[0]) - (stay_time[0] * 60)) : 0;
				stay_time[2] = Number((stay_time[2] - (stay_time[1] * 60) - (stay_time[0] * 60 * 60)).toFixed(0));
				stay_time[0] = stay_time[0] < 10 ? "0" + stay_time[0] : stay_time[0].toString();
				stay_time[1] = stay_time[1] < 10 ? "0" + stay_time[1] : stay_time[1].toString();
				stay_time[2] = stay_time[2] < 10 ? "0" + stay_time[2] : stay_time[2].toString();
				stay_time = stay_time.join(":");
				
				if (arguments.length && arguments[0] === true)
					return stay_time;

				// finally create a new cookie with the total stay time
				// and combing all the temp cookies as well
				
				// note: removed on 2011 02 18 due to request header limit being exceeded
				// IS.cookie.cook(page_cookie, total_time);
				
				// and add that time to the page log
				page_log = 	(IS.cookie.check(IS.cookie.cookie_types.page_log_temp_2) ? 
								IS.cookie.check(IS.cookie.cookie_types.page_log_temp_2) + "\n" : "") +
							(IS.cookie.check(IS.cookie.cookie_types.page_log_temp) ? 
								IS.cookie.check(IS.cookie.cookie_types.page_log_temp) + " " + stay_time + "\n" : "") + 
							IS.cookie.check(IS.cookie.cookie_types.page_log);
					
				// before storing the new cookie check it's size
				if (IS.analytics.log_limit && page_log.split("\n").length - 1 > IS.analytics.log_limit) {
					// remove first two logs
					page_log = page_log.split("\n");
					page_log.pop();
					page_log.pop();
							
					// add a note to the end
					page_log.push(" -- Session history truncated -- ");
							
					// convert bato to string
					page_log = page_log.join("\n");
				}
				
				// now store truncated log
				IS.cookie.cook(IS.cookie.cookie_types.page_log, page_log);
				
				// then delete the temp cookies
				IS.cookie.throw_out(IS.cookie.cookie_types.page_log_temp);
				IS.cookie.throw_out(IS.cookie.cookie_types.page_log_temp_2);
			};

			if ("addEventListener" in window)
				window.addEventListener("unload", window.____new_unload_handler____, false);
			else if (window.attachEvent)
				window.attachEvent("onunload", window.____new_unload_handler____);
			else {
				if (typeof window.onunload === "function") {
					window.____old_unload_handler____ = window.onunload;
					window.onunload = function () {
						window.____old_unload_handler____();
						window.____new_unload_handler____();
					};
				}
			}
		},

		// for tracking browser used
		browser: function () {
			var n = window.navigator;

			// system's platform
			IS.cookie.cook(IS.cookie.cookie_types.user_os, n.platform);
			
			// browser's name, sample: Gecko/Google Inc.
			if ("appName" in n && n.appName !== "Netscape")
				IS.cookie.cook(IS.cookie.cookie_types.user_browser_name, n.appName);
			else if ("vendor" in n && n.vendor)
				IS.cookie.cook(IS.cookie.cookie_types.user_browser_name, unescape(n.product + "/" + n.vendor));
			else
				IS.cookie.cook(IS.cookie.cookie_types.user_browser_name, unescape(n.appCodeName));
				
			// system's language
			if ("language" in n)
				IS.cookie.cook(IS.cookie.cookie_types.user_lang, n.language);
			else if ("browserLanguage" in n)
				IS.cookie.cook(IS.cookie.cookie_types.user_lang, n.browserLanguage);
		}
	},

	/**
	 *
	 * Methods and variables for data object
	 *	(String)	form_class:		class name given to forms used in posting
	 *								analytics cookie data
	 *	(RegExp)	cookie_search:	regular expression used in searching for
	 *								cookies created by IS
	 *	(Function)	dump:			method looks for webform with a class name of
	 *								this.form_class, when found, it will add hidden
	 *								fields for each of the cookies. additionally it will
	 *								add a submit event handler to manage promotional information
	 *
	 */
	data: {
		// class used in forms where we can add
		// out cookie's data to
		form_class: "analytics_form",

		promotions: false,

		form_promotion: "promo",

		// regex patter used in searching for analytics cookies
		cookie_search: /Analytics_/,

		// function that searches document for forms
		// and adds hidden input fields with all
		// of the data gathered so far
		dump: function () {
			var home = window.document,
				forms = home.getElementsByTagName("form"),
				cookies = [],
				input_field;

			if (!forms.length)
				return false;

			// loop though all forms in document
			// for each form check if they have our class name
			// if so, append a hidden field for each Analytics cookie
			for (var i = 0; i < forms.length; i++) {
				if (forms[i].className.indexOf(this.form_class) !== -1) {
					// first re-set the form name cookie
					IS.cookie.cook(IS.cookie.cookie_types.form_name, forms[i].name ? forms[i].name : "");
					
					// re-set the cookie search
					cookies = IS.cookie.query(this.cookie_search)
				
					for (var j = 0; j < cookies.length; j++) {
						input_field = document.createElement("input");
						input_field.setAttribute("type", "hidden");
						input_field.setAttribute("name", cookies[j][0]);
						input_field.setAttribute("value", cookies[j][1]);
						forms[i].appendChild(input_field);
					}

					// if promotions are enabled, set submit
					// event handler as well
					if (this.promotions) {
						// define submit handler
						window.____new_submit_handler____ = function () {
							try {
								var inputs = this.getElementsByTagName ? this.getElementsByTagName("input") : 
									document.getElementsByTagName("input"), input_field;
								for (var i = 0; i < inputs.length; i++) {
									if (inputs[i].name === IS.data.form_promotion) {
										if (inputs[i].value.toLowerCase() in IS.analytics.sources.pro) {
											// update the hidden field
											var fields = [
												document.getElementsByName(IS.cookie.cookie_types.lead_source_id),
												document.getElementsByName(IS.cookie.cookie_types.lead_source_name),
												document.getElementsByName(IS.cookie.cookie_types.promo_name),
												document.getElementsByName(IS.cookie.cookie_types.promo_code)
												], temp_field_holder = [];
												
											// ------------------------------------------------------------------------------------------------------------------
											// -------------------------------------------- start IE 5, 6, and 7 fix -------------------------------------------- 
											if (fields[0].length === 0) {
												fields[0] = [];
												temp_field_holder = document.getElementsByTagName("input");
												for (var f = 0; f < temp_field_holder.length; f++) {
													if (temp_field_holder[f].getAttribute("name") === IS.cookie.cookie_types.lead_source_id)
														fields[0][fields[0].length] = temp_field_holder[f];
												}
											}
											if (fields[1].length === 0) {
												fields[1] = [];
												temp_field_holder = document.getElementsByTagName("input");
												for (var f = 0; f < temp_field_holder.length; f++) {
													if (temp_field_holder[f].getAttribute("name") === IS.cookie.cookie_types.lead_source_name)
														fields[1][fields[1].length] = temp_field_holder[f];
												}
											}
											if (fields[2].length === 0) {
												fields[2] = [];
												temp_field_holder = document.getElementsByTagName("input");
												for (var f = 0; f < temp_field_holder.length; f++) {
													if (temp_field_holder[f].getAttribute("name") === IS.cookie.cookie_types.promo_name)
														fields[2][fields[2].length] = temp_field_holder[f];
												}
											}
											if (fields[3].length === 0) {
												fields[3] = [];
												temp_field_holder = document.getElementsByTagName("input");
												for (var f = 0; f < temp_field_holder.length; f++) {
													if (temp_field_holder[f].getAttribute("name") === IS.cookie.cookie_types.promo_code)
														fields[3][fields[3].length] = temp_field_holder[f];
												}
											}
											// -------------------------------------------- end IE 5, 6, and 7 fix -------------------------------------------- 
											// ---------------------------------------------------------------------------------------------------------------- 

											// update source id
											for (var a = 0; a < fields[0].length; a++) {
												fields[0][a].setAttribute("value", IS.analytics.sources.pro[inputs[i].value.toLowerCase()].id);
											}
											
											// update source name
											for (var a = 0; a < fields[1].length; a++) {
												fields[1][a].setAttribute("value", IS.analytics.sources.pro[inputs[i].value.toLowerCase()].name);
											}
											
											// update promo name
											for (var a = 0; a < fields[2].length; a++) {
												if ("promotion" in IS.analytics.sources.pro[inputs[i].value.toLowerCase()])
													fields[2][a].setAttribute("value", IS.analytics.sources.pro[inputs[i].value.toLowerCase()].promotion);
											}
											
											// update promo code
											for (var a = 0; a < fields[3].length; a++) {
												fields[3][a].setAttribute("value", inputs[i].value);
											}
											
											// then update the cookie
											IS.cookie.cook(IS.cookie.cookie_types.lead_source_id, IS.analytics.sources.pro[inputs[i].value.toLowerCase()].id);
											IS.cookie.cook(IS.cookie.cookie_types.lead_source_name, IS.analytics.sources.pro[inputs[i].value.toLowerCase()].name);
											
											// create a new cookie to store the promo code as well
											IS.cookie.cook(IS.cookie.cookie_types.promo_code, inputs[i].value.toLowerCase());
											
											// if the promotion has a name, store it as well
											if ("promotion" in IS.analytics.sources.pro[inputs[i].value.toLowerCase()])
												IS.cookie.cook(IS.cookie.cookie_types.promo_name, IS.analytics.sources.pro[inputs[i].value.toLowerCase()].promotion);
										}
										// if the promo code is not found, it is still saved
										else {
											IS.cookie.cook(IS.cookie.cookie_types.promo_code, inputs[i].value);
											for (var a = 0; a < document.getElementsByName(IS.cookie.cookie_types.promo_code).length; a++)
												document.getElementsByName(IS.cookie.cookie_types.promo_code)[a].value = inputs[i].value
										}
									}
								}
							} catch (err) {}
						};

						// now add the submit handler for promos
						if ("addEventListener" in forms[i])
							forms[i].addEventListener("submit", window.____new_submit_handler____, false);
						else if (forms[i].attachEvent)
							forms[i].attachEvent("onsubmit", window.____new_submit_handler____);
						else {
							if (typeof forms[i].onsubmit === "function") {
								window.____old_submit_handler____ = forms[i].onsubmit;
								forms[i].onsubmit = function () {
									window.____old_submit_handler____();
									window.____new_submit_handler____();
								};
							}
							else
								forms[i].onsubmit = window.____new_submit_handler____;
						}
					}
					
					// event listerner for concatinating log, logtemp, and logtemp2 cookies
					window.____concat_submit_handler____ = function () {
						try {
							var logs = this.getElementsByName ? this.getElementsByName(IS.cookie.cookie_types.page_log) : 
								document.getElementsByName(IS.cookie.cookie_types.page_log), log = "",
								temps = [
									this.getElementsByName ? this.getElementsByName(IS.cookie.cookie_types.page_log_temp) : 
										document.getElementsByName(IS.cookie.cookie_types.page_log_temp), 
									this.getElementsByName ? this.getElementsByName(IS.cookie.cookie_types.page_log_temp_2) : 
										document.getElementsByName(IS.cookie.cookie_types.page_log_temp_2)
									];
							log = 	(IS.cookie.check(IS.cookie.cookie_types.page_log_temp_2) ? 
										IS.cookie.check(IS.cookie.cookie_types.page_log_temp_2) + "\n" : "") +
									IS.cookie.check(IS.cookie.cookie_types.page_log_temp) + " " + window.____new_unload_handler____(true) + "\n" + 
									IS.cookie.check(IS.cookie.cookie_types.page_log),
							// for IE fix
							temp_field_holder = [];
									
							// -----------------------------------------------------------------------------------------------------------------
							// -------------------------------------------- start IE 5, 6 and 7 fix --------------------------------------------
							if (logs.length === 0) {
								temp_field_holder = document.getElementsByTagName("input");
								for (var i = 0; i < temp_field_holder.length; i++) {
									if (temp_field_holder[i].getAttribute("name") === IS.cookie.cookie_types.page_log) {
										temp_field_holder[i].setAttribute("value", log);
									}
								}
							}
							// -------------------------------------------- end IE 5, 6 and 7 fix --------------------------------------------
							// ---------------------------------------------------------------------------------------------------------------
							else {
								// update fields
								for (var i = 0; i < logs.length; i++)
									logs[i].setAttribute("value", log);
								
								// finally delete the temp fields
								for (var i = 0; i < temps.length; i++)
									for (var j = 0; temps[i].length; j++)
										document.body.removeChild(temps[i][j]);
							}
						} catch (err) {}
						
						
						// one last thing, check we're
						// posting Jeremiah's session id
						var all_fields = document.getElementsByTagName("input"), session_id_fields = [];
						for (var i = 0; i < all_fields.length; i++)
							if (all_fields[i].getAttribute("name") === IS.cookie.External_ID.is_cookie)
								session_id_fields.push(all_fields[i]);
						
						if (session_id_fields.length) {

							for (var i = 0; i < session_id_fields.length; i++)
								if (!session_id_fields[i].value)
									session_id_fields[i].value = IS.cookie.check(IS.cookie.External_ID.external_cookie);
						}
					};

					// now add the submit handler
					if ("addEventListener" in forms[i])
						forms[i].addEventListener("submit", window.____concat_submit_handler____, false);
					else if (forms[i].attachEvent)
						forms[i].attachEvent("onsubmit", window.____concat_submit_handler____);
					else {
						if (typeof forms[i].onsubmit === "function") {
							window.____old_submit_handler____ = forms[i].onsubmit;
							forms[i].onsubmit = function () {
								window.____old_submit_handler____();
								window.____concat_submit_handler____();
							};
						}
						else
							forms[i].onsubmit = window.____concat_submit_handler____;
					}
				}
			}

			return true;
		}
	},
	
	// timezone information
	timezone: {
		// get the user's timezone offset
		offset: -(new Date).getTimezoneOffset(),
		
		// for zone references
		offsets: {
			"-12":	 "Eniwetok",
			"-11":	 "Samoa",
			"-10":	 "Hawaii",
			"-9":	 "Alaska",
			"-8":	 "PST",
			"-7":	 "MST",
			"-6":	 "CST",
			"-5":	 "EST",
			"-4":	 "Atlantic, Canada",
			"-3":	 "Brazilia, Buenos Aries",
			"-2":	 "Mid-Atlantic",
			"-1":	 "Cape Verdes",
			"0":	 "Greenwich Mean Time, Dublin",
			"1":	 "Berlin, Rome",
			"2":	 "Israel, Cairo",
			"3":	 "Moscow, Kuwait",
			"4":	 "Abu Dhabi, Muscat",
			"5":	 "Islamabad, Karachi",
			"6":	 "Almaty, Dhaka",
			"7":	 "Bangkok, Jakarta",
			"8":	 "Hong Kong, Beijing",
			"9":	 "Tokyo, Osaka",
			"10":	 "Sydney, Melbourne, Guam",
			"11":	 "Magadan, Soloman Is.",
			"12":	 "Fiji, Wellington, Auckland"
		},
		
		dls: function () {
			var dls, today = this.offset, tomorrow = new Date();
			
			for (var m = 0; m < 13; m++)
				if (-tomorrow.getTimezoneOffset() !== today)
					return -tomorrow.getTimezoneOffset() > today
				else
					tomorrow.setMonth(tomorrow.getMonth() + 1);
			
			return null;
		},
		
		// calculate the timezone
		init: function () {
			if (this.dls() === false)
				this.offset = String((+this.offset / 60 - 1) * 60);
		
			if ((this.offset / 60).toString() in this.offsets)
				return this.offsets[this.offset / 60];
			
			return new Date;
		}
	},

	// this is set as a variable to allow us to
	// use the get method with other urls/strings
	// window.URL is the default
	url: document.URL,

	// method for getting a url parameter's value
	// returns false if parameter is not found
	get: function (variable) {
		// first, we check if we can work with the url
		if (this.url.split('?').length === 1)
			return false;

		// in case there is an un-escaped question
		// mark in the url variable we use substring
		// to strip out the whole query string
		// and not parts of it
		var par_val_array = this.url.substring(this.url.indexOf('?') + 1, this.url.length).
			split('&');

		// loop through each variable/value pair
		// and find our parameter
		for (var i = 0; i < par_val_array.length; i++)
			if (par_val_array[i].split("=").length === 1)
				continue;
			else if (par_val_array[i].split("=")[0] === variable)
				return par_val_array[i].split("=")[1];

		// no match found, end here
		return false;
	},

	// add a search engine to the Analytics object
	// sample: IS.new_engine("google", "Google", "q");
	new_engine: function (key_name, full_name, parameter) {
		this.analytics.search_engines[key_name] = {};
		this.analytics.search_engines[key_name]["name"] = full_name;
		if (parameter)
			this.analytics.search_engines[key_name]["param"] = parameter;

		return this;
	},

	// add a default to the defaults list
	// sample: IS.new_default("domain.net", "Domain");
	new_default: function (key_name, full_name) { this.analytics.defaults[key_name] = full_name; return this; },

	// sets the parameter used for affiliate checking
	// sample: IS.set_affiliate("aff");
	set_affiliate: function (str) { this.analytics.aff_param = str; return this; },
	
	// sets the css class used for link tracking
	// sample: IS.set_link("analyticLinks");
	set_link: function (str) { this.analytics.analytics_links = str; return this; },

	// set the css class used for form tracking
	// sample: IS.set_form("contactUs");
	set_form: function (str) { this.data.form_class = str; return this; },

	// set the promo code field's name
	// sample: IS.set_promo("promoCode");
	set_promo: function (str) { this.data.form_promotion = str; return this; },

	// add a search engine to the analytics object
	// sample: IS.add_analytics("Google", { keyword: "k", ad: "a", etc... });
	add_analytics: function (engine_name, analytics_object) {
		for (var ana in this.analytics.search_engines)
			if (this.analytics.search_engines[ana].name === engine_name) {
				this.analytics.search_engine_analytics[engine_name] = analytics_object;
				return this;
			}

		return false
	},
	
	// enable modules
	// sample: IS.enable(IS.clicks);
	enable: function (module) {
		if (module in this.modules)
			this.modules[module] = true;
		else
			return "invalid module";
		
		return this;
	},
	
	// IS variables used for IS's enable method
	pages:		"pages",
	clicks:		"clicks",
	browser:	"browser",
	promotions:	"promotions",

	// set lead sources
	// sample: IS.set_sources(IS.ppc, {"Google": { id: 1, name: "Google PPC" }, "Bing": { id: 2, name: "Bing PPC" }})
	// note: IS.affiliate and IS.promotion require a promo code or affiliate id
	// note: IS.affiliate and IS.promotion require a "affiliate" or
	// "promotion" variable to be included in the source object
	// sample: IS.set_sources(IS.affiliate, {"fg3jk2": { id: 3, name: "Source Name", affiliate: "Affiliate's Name" }})
	set_sources: function (type, source_object) {
		if (!(type in this.analytics.sources))
			return false;
		else
			for (var source in source_object)
				this.analytics.sources[type][source.toString().toLowerCase()] = source_object[source];

		return this;
	},

	// source types used in IS's set_sources method
	organic:	"org",
	ppc:		"ppc",
	referrer:	"ref",
	affiliate:	"aff",
	promo:		"pro",
	none:		"non",
	
	// set the default cookie expiration (minutes)
	// sample: IS.cookie_expiration(10000);
	// default: session (0 minutes)
	cookie_expiration: function (num) {
		if (isNaN(Number(num)))
			this.cookie.exp = 0;
		else
			this.cookie.exp = Number(num);
		
		return this;
	},
	
	// set the default cookie store path/location
	// sample: IS.cookie_path("/dir");
	// default: root (/)
	cookie_path: function (str) { this.cookie.path = str; return this; },
	
	// request header limit fix
	// the page log cookie can exceed the request header max size
	// giving the user a 'Bad Request'/400 error page
	// Apache server setting: LimitRequestFieldSize (default: 8190 bytes)
	log_limit: function (lines) { this.analytics.log_limit = lines; return this; },
	
	// set a default affiliate per page
	default_affiliate: function (affiliate) {
		if (affiliate in IS.analytics.sources.aff) {
			IS.cookie.cook(IS.cookie.cookie_types.affiliate_id, affiliate);
			IS.cookie.cook(IS.cookie.cookie_types.default_affiliate, affiliate);
			IS.cookie.cook(IS.cookie.cookie_types.affiliate_name, IS.analytics.sources.aff[affiliate].affiliate);
		}
		
		return this;
	},
	
	// short cut to a basic IS.cookie.cook method
	// short cut to IS.cookie.check method
	// short cut to IS.cookie.throw_out method
	// sample (cook): 		IS.chef("name", "IS Object");
	// sample (check): 		IS.chef("name");
	// sample (throw_out):	IS.chef("name", false);
	chef: function (name, value) { return value ? IS.cookie.cook(name, value) : (value === false ? IS.cookie.throw_out(name) : IS.cookie.check(name)); }
};

///////////////////////////////////////////////////////////////////////////////////////
// InsideSales.com Analytics End
///////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////
// InsideSales.com Analytics Settings Start
///////////////////////////////////////////////////////////////////////////////////////

// enable the modules we want to use
IS.enable(IS.pages);
IS.enable(IS.clicks);
IS.enable(IS.browser);
IS.enable(IS.promotions);

// add a new search engines
IS.new_engine("linkedin.com", "LinkedIn");
IS.new_engine("facebook.com", "Facebook");

// set class for link tracking links
IS.set_link("analyticsTracking");

// set class for cookie enabled form
IS.set_form("analyticsForm");

// set name for promotion code input field
IS.set_promo("promo_code");

// set affiliate parameter
IS.set_affiliate("a");

// add analitics parameters for Google search engine
IS.add_analytics(
    "Google", {
	category: 	"category",
	keyword: 	"keyword",
	network: 	"network",
	match_type: 	"match_type",
	position: 	"position",
	ad_id: 		"ad",
	placement:	"placement"
    }
);

IS.add_analytics(
    "LinkedIn", {
	category:	"category",
	ad_id:	        "ad_id"
    }
);

IS.add_analytics(
    "Facebook", {
	category:	"category",
	ad_id:	        "ad_id"
    }
);

// set lead organic sources
IS.set_sources(IS.organic, {
	"Google":		{id: 0, name: "Organic - Google"},
	"Yahoo":		{id: 0, name: "Organic - Yahoo"},
	"AltaVista":	        {id: 0, name: "Organic - AltaVista"},
	"Ask":			{id: 0, name: "Organic - Ask.com"},
	"LinkedIn":        	{id: 0, name: "Web Referral - LinkedIn"},
	"Facebook":        	{id: 0, name: "Web Referral - Facebook"},
	"Bing":			{id: 0, name: "Organic - Bing"}
});

// set pay-per-click sources
IS.set_sources(IS.ppc, {
	"LinkedIn":		{id: 0, name: "PPC - LinkedIn"},
	"Facebook":		{id: 0, name: "PPC - Facebook"},
	"Google":		{id: 0, name: "PPC - Google"}
});

// set referrer
IS.set_sources(IS.referrer, {
	"salesforce.com":			{id: 0, name: "Web Referral - Salesforce"},
	"business.com":				{id: 0, name: "Web Referral - Business.com"},
	"hbr.org":	  			{id: 0, name: "Web Referral - HBR"},
	"b2bonline.com":			{id: 0, name: "Web Referral - B2B Online"},
	"youtube.com":				{id: 0, name: "Web Referral - YouTube"},
	"leadresponsemanagement.org":		{id: 0, name: "Web Referral - LRM.org"}
});

IS.new_default("salesforce.com", "salesforce.com");
IS.new_default("business.com", "business.com");
IS.new_default("hbr.org", "hbr.org");

// set promotions
IS.set_sources(IS.promo, {
	"dream421":		{id: 0, name: "Tradeshow - Dreamforce 2010", promotion: "Dreamforce 2010 Coupon"},
	"meclabs42":		{id: 0, name: "Webinar - Meclabs 2011-07", promotion: "Meclabs Webinar (2011-07-19)"}
});

// set the affiliate id
IS.set_sources(IS.affiliate, {

	// Partner Affiliate Codes
	"inv355":	{id: 0, name: "Referral - Partner", affiliate: "David Ortiz"},
	"voe550":	{id: 0, name: "Referral - Partner", affiliate: "Ken Goldstein"},
	"ntz526":	{id: 0, name: "Referral - Partner", affiliate: "Adelita McGrath"},

	// Cactus Sky Email Affiliate Codes
	"csk855":	{id: 0, name: "Email - Cactus Sky", affiliate: "Cactus Sky"},
	"csk856":	{id: 0, name: "Email - Cactus Sky", affiliate: "Cactus Sky"},
	"csc541":	{id: 0, name: "Email - Cactus Sky", affiliate: "Cactus Sky"},
	"csc545":	{id: 0, name: "Email - eNewsletter", affiliate: "Cactus Sky"},

	// Banner Ad Affiliate Codes
	"b2b986":        	{id: 0, name: "Ad - B2B Magazine", affiliate: "B2B Magazine"},

	// Email Affiliate Codes
	"act779":	{id: 0, name: "Email - Executive Briefing",		affiliate: "Marketing Email"},
	"act780":	{id: 0, name: "Email - Executive Briefing",		affiliate: "Marketing Email"},
	"act781":	{id: 0, name: "Email - Executive Briefing",		affiliate: "Marketing Email"},
	"act782":	{id: 0, name: "Email - Executive Briefing",		affiliate: "Marketing Email"},
	"act783":	{id: 0, name: "Email - Executive Briefing",		affiliate: "Marketing Email"},
	"act784":	{id: 0, name: "Email - Executive Briefing",		affiliate: "Marketing Email"},
        "act785":	{id: 0, name: "Email - Executive Briefing",		affiliate: "Marketing Email"},
        "act786":	{id: 0, name: "Email - Executive Briefing",		affiliate: "Marketing Email"},
        "act787":	{id: 0, name: "Email - Shootout Challenge",		affiliate: "Marketing Email"},
        "act788":	{id: 0, name: "Email - Shootout Challenge",		affiliate: "Marketing Email"},
        "act789":	{id: 0, name: "Email - Shootout Challenge",		affiliate: "Marketing Email"},
        "act790":	{id: 0, name: "Email - Dreamforce 2011",		affiliate: "Marketing Email"},
        "act791":	{id: 0, name: "Email - Zoom Sneak Peek",		affiliate: "Marketing Email"},
        "act792":	{id: 0, name: "Email - Why and Challenge",		affiliate: "Marketing Email"},
        "act793":	{id: 0, name: "Email - See a Demo",			affiliate: "Marketing Email"},
        "act793":	{id: 0, name: "Email - See a Demo for a Hoodie",	affiliate: "Marketing Email"},
        "act794":	{id: 0, name: "Email - See a Demo for a Hoodie",	affiliate: "Marketing Email"},
        "act796":	{id: 0, name: "Email - Lead Response Summary 2012",	affiliate: "Marketing Email"},
        "act797":	{id: 0, name: "Email - Free Trial",	                affiliate: "Marketing Email"},
        "act798":	{id: 0, name: "Email - Webinar Promotion",              affiliate: "Marketing Email"},
        "act799":	{id: 0, name: "Email - PowerDialer for Salesforce",     affiliate: "Marketing Email"},

	// Default (Unrecognized Affiliate Code)
	"default":	{id: 0, name: "Referral - Other", affiliate: ""}
});

// for leads that can not be tracked back to
// a source, set a default
IS.set_sources(IS.none, {
	"default":	{id: 0, name: "Web Referral"},
	"direct":	{id: 0, name: "Web Direct"}
});

// set the cookie expiration
IS.cookie_expiration(0);

// set the default store path
IS.cookie_path("/");

// set the page log to a maximum of 20 pages
IS.log_limit(20);

// store a session id
IS.cookie.cook("Analytics_Jeremiah_session_id", IS.cookie.check("session_id"));

// start
IS.init();


///////////////////////////////////////////////////////////////////////////////////////
// InsideSales.com Analytics Settings End
///////////////////////////////////////////////////////////////////////////////////////
