/*******************************************************************************
	Filename		: UCM.Main.js

	Called by		: 

	Created			: 21 June 2011
	Created by		: Rick Holmes
	Last Updated	: 21 June 2011

	Required files	: 

	Comments	: This is the main js file that calls everything else.
*******************************************************************************/	


var UCM = (function($){
	//'use strict';
/********************************* Utilities (private): some of these are 'revealed' below for use elsewhere *********************************/
	
	// debug: removes try/catch to see errors
	var debug = true,
		loadedList = [];
	
   // cookie functions
	var Cookie = {
		create: function(name, value, days) { 
			var expires,
				date;
			
			if (days) {
				date = new Date();
				date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
				expires = "; expires=" + date.toGMTString();
			} else {
				expires = "";
			}
			document.cookie = name + "=" + value + expires + "; path=/";
		},
		
		read: function(name) {
			var nameEQ = name + "=",
				ca = document.cookie.split(';'),
				i, c;
				
			for (i = 0; i < ca.length; i++) {
				c = ca[i];
				while (c.charAt(0) === ' ') {
					c = c.substring(1, c.length);
				}
				if (c.indexOf(nameEQ) === 0) {
					return c.substring(nameEQ.length, c.length);
				}
			}
			return null;
		},
		
		erase: function(name){
			document.cookie = name + "= ; max-age=-1; path=/";
		},
		
		test: function(){
			// try to create a cookie
			this.create('test', 'testing');
			// then read it
			if (this.read('test') === 'testing') {
				this.erase('test');
				return true;
			}
			else {
				return false;
			}
		}
	},
    
	MyArray = { // because jQuery's array methods don't seem to work right!
		inArray: function(needle, haystack) {
			for (var i=0, max = haystack.length; i < max; i += 1) {
				if (haystack[i] === needle) {
					return true;
				}
			}
		},
		
		isArray: function(array) {
			var array_string = '[object Array]',
				ops = Object.prototype.toString;
				
			return ops.call(array) === array_string;
		},
				
		removeByElement: function(arrayName, arrayElement) {
			for (var i=0, max = arrayName.length; i < max; i += 1) { 
				if (arrayName[i] === arrayElement) {
					arrayName.splice(i, 1);
					return true;
				}			 
			} 
			return false;	
		}
	},	

	// allow console.logging to stay for troubleshooting on live site
	// should remove them when done in any case
	console = {
		log: function(tolog){
			if (typeof window.console !== 'undefined' && typeof window.console.log === 'function') {
				return window.console.log(tolog);
			}
		}
	};
	// end var

/********************************* Helpers (private) *********************************/
	
	// helper for plugin loader
	function createCallback(methodName) {
		var that = this;
		(that[methodName]());
	}
 
	// preloads regular images
	function preloadImages(src) {
		$('<img>').attr('src', src);
	}
    		
	/***************************** Other Private Methods *****************************/	   		

		
	// add to the loaded list
	function addLoaded(file) {
		loadedList.push(file); 
	}

	/*******************************************************************************************
    	PUBLIC PROPERTIES AND METHODS
   *******************************************************************************************/
		
	return {
		
		// page identifiers
		pageId: '',		
		pageClasses: '',
		
		// site urls, SITE_URL is written in template.php to equal base_url(), need public for access by other modules
		SITE_URL: '',
		SITE_URL2: '',
		GRAPHICS_URL: '',		
		SCRIPTS_URL: '',
		STYLES_URL: '',
		AJAX_URL: '',

		/***************************** Namespace Helper Methods *****************************/	 
		
		// namespacing function, called for objects below and by method in loaded files
		Namespace: function(ns_string) { //console.log(ns_string);
			var parts = ns_string.split('.'),
				parent = UCM,
				i, 
				max;
					
			// strip redundant leading global
			if (parts[0] === 'UCM') {
				parts = parts.slice(1);
			}
		
			for (i = 0, max = parts.length; i < max; i += 1) {
				// do not try namespacing non-SIM files
				if (parts[i].indexOf('UCM') !== -1) { 
					
					// create a property if it doesn't exist
					if (typeof parent[parts[i]] === 'undefined') {
						parent[parts[i]] = {};
					}
					parent = parent[parts[i]];
				}		
			}
			return parent;
		},

		
		/***************************** Truly Global Methods *****************************/	 
		
		// put the page id and page classes into "globals" for access whenever needed
		getPageIdentities: function() { 
			var pageClass = $(document.body).attr('class'); 
			try {
				this.pageId = $(document.body).attr('id'); 
				this.pageClasses = pageClass.split(' ');
			} catch (e) {
				// in case there aren't any
			}
				
		},
		

		// open links outside site in new window
		bindExternalLinks: function() { 
			$('a.external, a[rel~="external"]').each(function(){
				$(this).click(function(){
					var href = $(this).attr('href');	
									
					window.open(href, '', 'width=1000,height=700,resizable,scrollbars');
					
					return false;
				});
			});	
		},	
		// input placeholders, add as global
		placeholder: function() { 
			// for inputs 
			$(':text').each(function(){
				// quit if there's support for html5 placeholder
				//if ($this[0] && 'placeholder' in document.createElement('input')) return;
				
				// quit if there isn't a placeholder
				if (!$(this).attr('placeholder')) { return; }	
				
				// set the attribute in the data() cache
				$(this).data('placeholder', $(this).attr('placeholder'));
				// and its color
				$(this).data('placeholder_color', $(this).css('color')); 
				
				// set the initial value
				if ($(this).val() === '')
				{
					$(this).val($(this).data('placeholder'));
				}				
				
			}).live('focusin', function(){
				if ($(this).val() === $(this).data('placeholder')) {
					$(this).val('');
					$(this).css({color: '#000'});
				}
			}).live('focusout', function(){
				if ($(this).val() === '') {
					$(this).val($(this).data('placeholder'));
					$(this).css({color: $(this).data('placeholder_color')});
				}
			});
		},
		
		fixAutocomplete: function() { 
			if ($.browser.mozilla) {
				try {
					$('form').attr('autocomplete', 'off');	
				} catch(ac) {
					// just catch it			
				} 			
			}
		},
			        
		// print the current page
		printPage: function() {
			$('a[rel~="print"]').click(function(){
				window.print();
				
				return false;
			});
		},
		      
		/***************************** Init Methods *****************************/	 
		
		// give me a name so i can test for it later
		nameMe: function() {
			this.name = 'UCM';
		},
		
		// namespace known stuff
		doNamespacing: function() {
			this.Namespace('UCM.Config'); 
			this.Namespace('UCM.PageFunctions');
			this.Namespace('UCM.Loader');
		},
		
		// load the paths, can be called from anywhere
		loadPaths: function() {
			var paths = this.Config.paths;
			
			this.SITE_URL = site_url;
			this.SITE_URL2 = site_url.replace('https://', 'http://');
			this.STYLES_URL = this.SITE_URL + paths.styles_url;
			this.SCRIPTS_URL = this.SITE_URL + paths.scripts_url;
			this.GRAPHICS_URL = this.SITE_URL + paths.graphics_url;
			this.AJAX_URL = this.SITE_URL + paths.ajax_url;
			this.RESOURCES_URL = this.SITE_URL + paths.resources_url;
		},
		
		// and the method that runs them		
		runGlobals: function() { 
			var i, max,
				fns = this.Config.globalFunctions;
			
			for (i = 0, max = fns.length; i < max; i += 1) {
				if (typeof this[fns[i]] === 'function') {
					try {
						this[fns[i]]();
					} catch (ex) {
						alert('function ' + fns[i] + ' not found or has an error');
					}				
				}
			}
		},
				
		// load any css and js required by page and not loaded globally
		// listing in SIM.Config below by pageId
		loadPageDependencies: function() { //console.log('in loadPageDependencies()');
			var i,
				max,
				pageData,
				pageFiles,
				jsFiles = [],
				cssFiles = [];
			
			if (typeof this.Config.pageData[this.pageId] !== 'undefined') {
				pageData = this.Config.pageData[this.pageId];
				if (typeof pageData.pageFiles !== 'undefined') {
					pageFiles = pageData.pageFiles;
					if (typeof pageFiles.jsFiles !== 'undefined') {
						jsFiles = pageFiles.jsFiles;
					}
					if (typeof pageFiles.cssFiles !== 'undefined') {
						cssFiles = pageFiles.cssFiles;
					}
				}
			}
			
			for (i = 0, max = cssFiles.length; i < max; i += 1) {
				this.Loader.loadByTag(cssFiles[i]);
			}	
			
			for (i = 0, max = jsFiles.length; i < max; i += 1) { //console.log(jsFiles[i]);
				this.Loader.loadByTag(jsFiles[i]);
			}			
		},
		
		// run any page functions listed in SIM.Config, may also be an init() in a dependency		
		runPageFunctions: function() {
			var i,
				max,
				pageData,
				fns = [];
			
			if (typeof this.Config.pageData[this.pageId] !== 'undefined') {
				pageData = this.Config.pageData[this.pageId];
				if (typeof pageData.pageFunctions !== 'undefined') {
					fns = pageData.pageFunctions;
				}
			}
			
			for (i = 0, max = fns.length; i < max; i += 1) {
				// only the functions in the PageFunctions module below are handled here
				// all of the others are handled in the module itself			
				if (typeof UCM.PageFunctions[fns[i]] === 'function') { 	
					// these functions are below 
					try {
						this.PageFunctions[fns[i]]();
					} catch (e) {
						alert('function ' + fns[i] + ' not found or has error');
					}						
				}
			}
		},
		
		dummy: function() {
			// do nothing, cause sometimes you just need a dummy function
		},
		
		// this is called from the individual modules to load what's needed when all their dependencies are loaded
		loadPageMethods: function(module) { 
			var i,
				max,
				pageData,
				fns,
				parts;
			
			if (typeof this.Config.pageData[this.pageId] !== 'undefined') {
				pageData = this.Config.pageData[this.pageId];
				if (typeof pageData.pageFunctions !== 'undefined') {
					fns = pageData.pageFunctions;
					for (i = 0, max = fns.length; i < max; i += 1) {
						if (fns[i].indexOf(module) !== -1) {
							parts = fns[i].split('.');
							this[module][parts[1]]();
						}				
					}					
				}
			}					
		},
		
		checkLoaded: function() { 
			var pageData, pageFiles, jsFiles; //window.console.log('in checkLoaded');
			
			if (typeof this.Config.pageData[this.pageId] !== 'undefined') { 
				pageData = this.Config.pageData[this.pageId]; 
				if (typeof pageData.pageFiles !== 'undefined') { 
					pageFiles = pageData.pageFiles;
					if (typeof pageFiles.jsFiles !== 'undefined') { 
						jsFiles = pageFiles.jsFiles; //window.console.log('jsFiles.length='+jsFiles.length+', loadedList.length='+loadedList.length);
						//if (jsFiles.length === loadedList.length) {
						if (loadedList.length >= jsFiles.length) { // cause i don't feel like figuring it out right now
							return true;
						} else {
							return false;
						}
					}
				}
			}
		},
		
		checkDependencies: function(dependencies) {
			var i,
				max = dependencies.length;
				
			for (i = 0; i < max; i += 1) {
				if (typeof dependencies[i] === 'undefined') {
					console.log(dependencies[i] + ' not loaded');
					return false;
				} else {
					console.log(dependencies[i] + ' is loaded');
				}
			}
			return true;
		},
		
		// reveals
		Cookie: Cookie,
		preloadImages: preloadImages,
		loadedList: loadedList,
		MyArray: MyArray,
		console: console,
		addLoaded: addLoaded,
		
		// the timeouts
		timout: {
			'GMM' : 0,
			'FM' : 0,
			'IVM' : 0,
			'PVM' : 0,
			'UM' : 0
		},	
		
		// start it all out
		init: function() { 
			// give me a name!
			this.nameMe();
			
			// run the namespacing function, not necessary?
			this.doNamespacing();
			
			// load the paths
			this.loadPaths();
			
			// truly global functions
			this.runGlobals();
			
			// load any additional files needed for particular page, as determined by config
			this.loadPageDependencies();
			
			// page functions below, as determined by config
			this.runPageFunctions();

		}	
	};

}(jQuery));

// loader that may be from called anywhere
UCM.Loader = (function(APP, $){
	'use strict';
	var parent = UCM;
	
	function loadByTag(file, callback) { 
		var p = file.lastIndexOf('.'),
			ext = file.slice(p + 1),
			head = document.getElementsByTagName('head')[0],
			body = document.getElementsByTagName('body')[0],
			link,
			script,
			parts,
			basename,
			fullpath;
			
		switch (ext) {
		case 'js':
			if (file.indexOf('//') === -1) {
				fullpath = APP.SCRIPTS_URL + file;
			} else {
				fullpath = file;
			}
			script = document.createElement('script');
			script.src = fullpath;
			script.type = 'text/javascript';
			script.async = true;
			
			script.onreadystatechange = function() {
				if (script.readyState === 'loaded' || script.readyState === 'complete') {
					script.readystatechange = null;
					APP.addLoaded(file);
					if (callback) {
						callback();						
					}					
				}
			};
			script.onload = function() {
				APP.addLoaded(file); 
				if (callback) {
					callback();
				}
			};
			
			head.appendChild(script);
			/* if (file.indexOf('UCM.') === -1) {
				head.appendChild(script);
			} else {
				body.appendChild(script);
			} */
			// namespace it if 'UCM' is found
			if (file.indexOf('UCM.') !== -1) {
				parts = file.split('/');
				basename = parts[parts.length-1].replace('.js', '');
				APP.Namespace(basename);
			}
			break;
		case 'css':
			if (file.indexOf('//') === -1) {
				fullpath = APP.STYLES_URL + file;
			} else {
				fullpath = file;
			}
			link = document.createElement('link');
			link.href = fullpath;
			link.rel = 'stylesheet';
			head.appendChild(link);
			APP.addLoaded(file);	
			break;		
		default:
			// this could be a script with a get
			if (file.indexOf('//') === -1) {
				fullpath = APP.SCRIPTS_URL + file;
			} else {
				fullpath = file;
			}
			script = document.createElement('script');
			script.src = fullpath;
			script.type = 'text/javascript';
			script.async = true;
			
			script.onreadystatechange = function() {
				if (script.readyState === 'loaded' || script.readyState === 'complete') {
					script.readystatechange = null;
					APP.addLoaded(file);
					if (callback) {
						callback();						
					}					
				}
			};
			script.onload = function() {
				APP.addLoaded(file); 
				if (callback) {
					callback();
				}
			};
			
			head.appendChild(script);
			//body.appendChild(script);
			break;
		}	
	}
	
	function loadByXHR(file, callback) {
		var parts,
			fullpath = APP.SCRIPTS_URL + file;
		
		if (file.indexOf('.js') === -1) {
			return;
		}		
		$.getScript(fullpath, function(){
         if (callback) {
				// gotta split this up so it works
				parts = callback.split('.');
				if (parts.length > 1) {
					APP[parts[0]][parts[1]]();
				} else {
					APP[parts[0]]();
				}
			}
     });
	}
						
	return {
		
		// reveals
		loadByTag : loadByTag,
		loadByXHR : loadByXHR
	};
}(UCM, jQuery));


// config, controls everything!
UCM.Config = {
	// paths needed in order to load files
	paths : {
		styles_url : 'assets/css/',
		scripts_url : 'assets/js/',
		graphics_url : 'assets/graphics/site/',
		ajax_url : 'ajax/',
		resources_url : 'assets/resources/'	
	},
	
	// truly global functions that reside in main UCM
	globalFunctions : ['getPageIdentities', 'bindExternalLinks', 'placeholder', 'fixAutocomplete', 'printPage'],
	
	// page specific stuff, grouped by controller
	pageData : {
		// welcome controller
		'home' : {
			pageFiles : {
				jsFiles : ['jquery.gorillabox-min.js', 'jquery.securityplugins.min.js', 'UCM.GMapMethods.js'],
				cssFiles : ['gorillabox.css']	
			},
			pageFunctions : ['do_scroller', 'demoPopup'] // GMapMethods.getMapData, 'GMapMethods.getUserLocation'
		},
		
		'contact' : {
			pageFiles : {
				jsFiles : ['jquery.gorillabox.js'],
				cssFiles : ['gorillabox.css']	
			}	
		},

		// auth controller
		/*'login' : {
			pageFiles : {
				jsFiles : ['jquery.formplugins.min.js', 'additional-methods-min.js', 'UCM.FormMethods-min.js']
				//jsFiles : ['basicform-062811.js']
			},
			pageFunctions : ['checkCookieAvailability']
		},*/
		
		'create_account' : {
			pageFiles : {
				jsFiles : ['jquery.formplugins.min.js', 'additional-methods-min.js', 'UCM.FormMethods.js', 'jquery.gorillabox-min.js'],
				//jsFiles : ['basicform-062811.js', 'jquery.gorillabox-min.js'],
				cssFiles : ['gorillabox.css']				
			},
			pageFunctions : ['demoPopup', 'bindCreateAccountFunctions']
		},
			
		'create_account2' : {
			pageFiles : {
				jsFiles : ['jquery.formplugins.min.js', 'additional-methods-min.js', 'UCM.FormMethods.js', 'jquery.gorillabox-min.js'],
				//jsFiles : ['basicform-062811.js', 'jquery.gorillabox-min.js'],
				cssFiles : ['gorillabox.css']				
			},
			pageFunctions : ['demoPopup', 'bindCreateAccountFunctions']
		},
		
		// users controller
		'dashboard' : {
			pageFiles : {
				//jsFiles : ['jquery.formplugins.min.js', 'jquery.securityplugins.min.js', 'jquery.gorillabox-min.js', 'jquery-ui-1.8.10.draggable.min.js', 'UCM.InventoryViewMethods-min.js', 'UCM.GMapMethods.js'],
				jsFiles : ['UCM.InventoryViewMethods.js', 'UCM.SearchMethods.js', 'jquery.formplugins.min.js', 'jquery.securityplugins.min.js', 'jquery.gorillabox-min.js', 'jquery-ui-1.8.10.draggable.min.js', 'UCM.GMapMethods.js'], //
				//jsFiles : ['dashboard-062811.js'],
				cssFiles : ['gorillabox.css']				
			},
			pageFunctions : ['InventoryViewMethods.ajaxContact', 'InventoryViewMethods.ajaxBidRequest', 'GMapMethods.getUserLocation'] // , 'SearchMethods.ajaxSelects', 'SearchMethods.resetParams'
		},
		
		'profile' : {			
			pageFunctions : ['fadeMessage']
		},
		
		'edit-profile' : {
			pageFiles : {
				jsFiles : ['swfobject.js', 'jquery.uploadify.v2.1.4.min.js', 'jquery.securityplugins.min.js', 'jquery-ui-1.8.6.custom.min.js', 'UCM.UploadifyMethods.js'],
				cssFiles : ['uploadify.css']
			},
			pageFunctions : ['UploadifyMethods.logo_uploadify', 'UploadifyMethods.avatar_uploadify']
		},
		
		'edit-preferences' : {
			pageFunctions : ['checkAll', 'smsTest']
		},
		
		'edit-creditcard' : {
			//pageFunctions : ['showCCImgs', 'bindCCVHelp']
			pageFunctions : ['bindCreateAccountFunctions'] // contains wht we need
		},
		
		'create-subuser' : {
			pageFunctions : ['ajaxPermissions']
		},
		
		// vehicles_post controller
		'post_wholesale' : {
			pageFiles : {
				jsFiles : ['jquery.formplugins.min.js', 'UCM.FormMethods.js', 'jquery.securityplugins.min.js', 'UCM.PostVehicleMethods.js']
			},
			pageFunctions : ['PostVehicleMethods.checkVIN', 'PostVehicleMethods.setFocus', 'PostVehicleMethods.hideTextareas', 'PostVehicleMethods.ajaxReports', 'PostVehicleMethods.optionalPrice', 'PostVehicleMethods.infoHover']
		},
		
		'add_photos' : {
			pageFiles : {
				jsFiles : ['swfobject.js', 'jquery.uploadify.v2.1.4.min.js', 'jquery.securityplugins.min.js', 'jquery-ui-1.8.6.custom.min.js', 'UCM.UploadifyMethods.js'],
				cssFiles : ['uploadify.css']
			},
			pageFunctions : ['UploadifyMethods.photos_uploadify']
		},
		'post_vehicle_wanted' : {
			pageFiles : {
				jsFiles : ['jquery.formplugins.min.js', 'additional-methods-min.js', 'UCM.FormMethods.js', 'jquery.securityplugins.min.js', 'UCM.PostVehicleMethods.js']
			},
			pageFunctions : ['PostVehicleMethods.ajaxSelects']
		},
		
		'post_vehicle_trade' : {
			pageFiles : {
				jsFiles : ['jquery.formplugins.min.js', 'additional-methods-min.js', 'UCM.FormMethods.js', 'jquery.securityplugins.min.js', 'UCM.PostVehicleMethods.js']
			},
			pageFunctions : ['PostVehicleMethods.checkVIN', 'PostVehicleMethods.ajaxSelects', 'PostVehicleMethods.hideTextareas']
		},
		
		// vehicles_view controller
		'view-vehicle' : {
			pageFiles : {
				jsFiles : ['jquery.formplugins.min.js', 'jquery.securityplugins.min.js', 'jquery.gorillabox-min.js', 'jquery-ui-1.8.11.custom.min.js', 'UCM.SearchMethods.js', 'UCM.InventoryViewMethods.js'],
				cssFiles : ['gorillabox.css']
			},
			pageFunctions : ['InventoryViewMethods.bindDelete', 'InventoryViewMethods.bindOVE', 'InventoryViewMethods.ajaxContact', 'InventoryViewMethods.ajaxBidRequest', 'InventoryViewMethods.loadHoverIntent'] // 'preloadImgs', 'changePhoto','InventoryViewMethods.changePhoto', 	
		},
		
		'my-inventory' : {
			pageFiles : {
				jsFiles : ['jquery-ui-1.8.11.custom.min.js', 'jquery.securityplugins.min.js', 'UCM.SearchMethods.js', 'UCM.InventoryViewMethods.js']
			},
			pageFunctions : ['InventoryViewMethods.makeTabs', 'InventoryViewMethods.bindDelete', 'InventoryViewMethods.bindOVE']
		},
		
		'user-inventory' : {
			pageFiles : {
				jsFiles : ['jquery.formplugins.min.js', 'jquery.securityplugins.min.js', 'UCM.SearchMethods.js', 'jquery.gorillabox-min.js', 'jquery-ui-1.8.11.custom.min.js', 'UCM.InventoryViewMethods.js'],
				cssFiles : ['gorillabox.css']
			},
			pageFunctions : ['InventoryViewMethods.makeTabs', 'InventoryViewMethods.ajaxContact', 'InventoryViewMethods.ajaxBidRequest']
		},
		
		'inventory' : {
			pageFiles : {
				jsFiles : ['jquery.formplugins.min.js', 'jquery.securityplugins.min.js', 'UCM.SearchMethods.js', 'jquery.gorillabox-min.js', 'jquery-ui-1.8.11.custom.min.js', 'UCM.InventoryViewMethods.js'],
				cssFiles : ['gorillabox.css']
			},
			pageFunctions : ['InventoryViewMethods.inventoryFilter', 'InventoryViewMethods.ajaxContact', 'InventoryViewMethods.ajaxBidRequest']
		},
		// this should be the same as the inventory page above
		'search' : {
			pageFiles : {
				jsFiles : ['jquery.formplugins.min.js', 'jquery.securityplugins.min.js', 'UCM.SearchMethods.js', 'jquery.gorillabox-min.js', 'jquery-ui-1.8.11.custom.min.js', 'UCM.InventoryViewMethods.js'],
				cssFiles : ['gorillabox.css']
			},
			pageFunctions : ['InventoryViewMethods.inventoryFilter', 'InventoryViewMethods.ajaxContact', 'InventoryViewMethods.ajaxBidRequest']
		},
		
		'admin-utilities' : {
			pageFiles : {
				jsFiles : ['jquery.securityplugins.min.js', 'UCM.GMapMethods.js']
			},
			pageFunctions : ['GMapMethods.bindGeocodeButton']
		},

		'admin-users' : {
			pageFiles : {
				jsFiles : ['jquery.formplugins.min.js', 'UCM.FormMethods.js', 'UCM.AdminMethods.js']
			},
			//pageFunctions : ['AdminMethods.userSearch'],
			ajaxFormCallbacks : {
				'user-search' : 'AdminMethods.writeSearchData'
			}
		}
	},
	
	formData : {
		'login' : {
			'loginform' : {
				formRules : {
					cookie_available : {required: true},
					email : {required: true, email: true},
					password : {required: true}
				},
				formMessages : {
					cookie_available : 'Please enable first-party cookies and reload this page.',
					email : 'Your email address is required.',
					password : 'Your password is required.'
				}				
			}
		},
		
		'create_account' : {
			'create_user_form' : {
				formRules : {
					dealername : {required: true},
					dealertype : {required: true},
					first_name : {required: true},
					last_name : {required: true},
					job_title : {required: true},
					address : {required: true},
					city : {required: true},
					state : {required: true, maxlength: 2},
					zip: {required: true, uszip: true},
					email: {required: true, email: true},
					phone: {required: true, phoneUS: true},
					password: {required: true, minlength: 6, maxlength: 10},
					password_confirm: {required: true, equalTo: "#password"},
					terms: {required: true},
					ts : {required : true,
								remote : {
									type : 'post',
									url : UCM.SITE_URL + 'ajax/token',
									data : {
										hash : function() {
											return Cookie.read('token');
										}
									}
								}
					}
				},
				formMessages : {
					dealername : 'Your dealership name is required.',
					dealertype : 'The type of your dealership is required.',
					first_name : 'Your first name is required.',
					last_name : 'Your last name is required.',
					job_title : 'Your job title is required.',
					address : 'Your street address is required.',
					city : 'Your city or town is required.',
					state : 'Your state is required.',
					zip : 'Your zipcode is required.',
					
					phone : 'Your phone number is required.',
					password: 'Please enter a password 6-10 characters long.',
					password_confirm : 'Your passwords do not match.',
					terms : 'Please read the UCM Link terms and conditions and check the checkbox if you agree.'	
				}
			}
		},
		
		'create_account2' : {
			'create_user_form2' : {
				formRules : {
					dealername : {required: true},
					dealertype : {required: true},
					first_name : {required: true},
					last_name : {required: true},
					job_title : {required: true},
					address : {required: true},
					city : {required: true},
					state : {required: true, maxlength: 2},
					zip: {required: true, uszip: true},
					email: {required: true, email: true},
					phone: {required: true, phoneUS: true},
					password: {required: true, minlength: 6, maxlength: 10},
					password_confirm: {required: true, equalTo: "#password"},
					terms: {required: true},
					ts : {required : true,
								remote : {
									type : 'post',
									url : UCM.SITE_URL + 'ajax/token',
									data : {
										hash : function() {
											return Cookie.read('token');
										}
									}
								}
					},
					cc_cardholder_fn : {required: true},
					cc_cardholder_ln : {required: true},
					cc_number : {required: true},
					cc_exp_month : {required: true},
					cc_exp_year : {required: true},
					cc_ccv : {required: true}
				},
				formMessages : {
					dealername : 'Your dealership name is required.',
					dealertype : 'The type of your dealership is required.',
					first_name : 'Your first name is required.',
					last_name : 'Your last name is required.',
					job_title : 'Your job title is required.',
					address : 'Your street address is required.',
					city : 'Your city or town is required.',
					state : 'Your state is required.',
					zip : 'Your zipcode is required.',
					
					phone : 'Your phone number is required.',
					password: 'Please enter a password 6-10 characters long.',
					password_confirm : 'Your passwords do not match.',
					terms : 'Please read the UCM Link terms and conditions and check the checkbox if you agree.',
					
					cc_cardholder_fn : "The credit-card owner's first name is required.",
					cc_cardholder_ln : "The credit-card owner's last name is required.",
					cc_number : "A valid credit card is required.",
					cc_exp_month : "The credit card's expiration month is required.",
					cc_exp_year : "The credit card's expiration year is required.",
					cc_ccv : "The credit card's security code is required."	
				}
			}
		},
		
		'contact' : {
			'contact_form' : {
				formRules : {
					email : {required: true, email: true},
					message : {required: true},
					ts : {required : true,
								remote : {
									type : 'post',
									url : UCM.SITE_URL + 'ajax/token',
									data : {
										hash : function() {
											return Cookie.read('token');
										}
									}
								}
					}
				},
				formMessages : {
					email : 'A valid email address is required',
					message : 'Please type a message',
					ts : 'Please enable cookies on your browser, reload the page and try again'	
				}
			}
		},
		
		'post_vehicle_wanted' : {
			'wanted_post' : {
				formRules : {
					start_year : {required: true},
					end_year : {required: true},
					make : {required: true},
					model : {required: true}	
				},
				formMessages : {
					start_year : 'The start-year field is required.',
					end_year : 'The end-year field is required.',
					make : 'The make field is required.',
					model : 'The model field is required.'		
				}
			}	
		},
		
		'post_vehicle_trade' : {
			'trade_post' : {
				formRules : {
					year : {required: true},
					make : {required: true},
					model : {required: true},
					mileage : {required: true}
					//price_needed : {required: true}	
				},
				formMessages : {
					year : 'The vehicle year is required.',
					make : 'The vehicle make is required.',
					model : 'The vehicle model is required.',
					mileage : 'The vehicle\'s mileage is required.'
					//price_needed : 'The price you need is required.'	
				}
			}	
		},
		
		'post_wholesale' : {
			'wholesale_post' : {
				formRules : {
					vin : {required: true},
					year : {required: true},
					make : {required: true},
					model : {required: true},
					mileage : {required: true},
					wholesale_price : {required: true}	
				},
				formMessages : {
					vin : 'The vehicle\'s VIN is required and must be checked before you can continue.',
					year : 'The vehicle year is required.',
					make : 'The vehicle make is required.',
					model : 'The vehicle model is required.',
					mileage : 'The vehicle\'s mileage is required.',
					wholesale_price : 'The wholesale-price field is required.'		
				}
			}
		},
		
		'admin-users' : {
			'user-search' : {
				formRules : {
					search_param : {required: true},
					searchby : {required: true}
				},
				formMessages : {
					search_param : 'You need to enter a search parameter',
					searchby : 'What would you like to search for?'
				},
				ajaxCallback : 'UCM.AdminMethods.writeSearchData'
			}
		}
	}
};

// this object has methods that are common to several pages but do not fit into any category
// it also has homepage and create-account functionality
UCM.PageFunctions = (function(APP, $){
	
/***************************** Private Properties *****************************/	

	var pageId = APP.pageId,
		pageClasses = APP.pageClasses, // local versions
		user_id = 0, // set by ajax for security reasons if needed
		userData = {},
		logindata = {},
		main_img = {
			'src' : '',
			'temp' : 1
		},
	
	// types of credit cards accepted format is 'valid first digit' : 'image file'
		cc_types = {
			'3' : 'img_amex',
			'4' : 'img_visa',
			'5' : 'img_mc',
			'6' : 'img_discvr',
			'img_amex'	:	'3',
			'img_visa'	:	'4',
			'img_mc'	:	'5',
			'img_discvr':	'6'	
			},
		valid_promos = ['UCM30FREE', 'UCM60FREE', 'UCM9040', 'UCMVIPFREE'],
		
		filters = {
			'view' : [],
			'types' : [],
			'makes' : []
		},

		youtube_embeds = {
			//'home' : '<iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/fhwVXU1wA4I?rel=0" frameborder="0" allowfullscreen></iframe>',
			'home' : '<iframe title="YouTube video player" width="640" height="390" src="http://www.youtube.com/embed/EYHFJCHaYdA?rel=0" frameborder="0" allowfullscreen></iframe>',
			
			'create_account' : '<iframe title="YouTube video player" width="640" height="390" src="https://www.youtube.com/embed/GuBKamihy4Q" frameborder="0" allowfullscreen></iframe>',
			'create_account2' : '<iframe title="YouTube video player" width="640" height="390" src="https://www.youtube.com/embed/GuBKamihy4Q" frameborder="0" allowfullscreen></iframe>'
						
		},
		timout; // for external file loads
		// end vars

/***************************** Private Methods *****************************/	
function purge(d) {
    var a = d.attributes, i, l, n;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            n = a[i].name;
            if (typeof d[n] === 'function') {
                d[n] = null;
            }
        }
    }
    a = d.childNodes;
    if (a) {
        l = a.length;
        for (i = 0; i < l; i += 1) {
            purge(d.childNodes[i]);
        }
    }
}
	//animator function for scroller (homepage)  
	function animator(currentItem) { 
 		//work out new anim duration  
		//var distance = 70;
		var distance = currentItem.height();
		//var duration = 2800;
		var duration = (distance - Math.abs(parseInt(currentItem.css("marginTop"), 10))) / 0.025; 
		
		// move last to top and give it negative margin
		currentItem.prependTo(currentItem.parent()).css('marginTop', -distance);
		// animate it
		currentItem.animate({ marginTop: 0 }, duration, function(){
			// recurse after pause
			setTimeout(function(){ return animator(currentItem.parent().children(':last')); }, 1000);
		});
	}
		
	return {		
		// homepage scroller(s)
		do_scroller: function() { 
			$('.scroller').css('overflow', 'hidden');
			
			$('.scroller').each(function(){
				$(this).css('overflow', 'hidden');
				animator($(this).children(':last'));
			});	
			// $(this).mouseenter(function(){
				//	scroller.children().stop();
				//});
				//$(this).mouseleave(function(){
			//		animator($(this).children(':first'));
			//	});
			
		},
		
		// demo video popup
		demoPopup: function() { 
			if (typeof jQuery.fn.gorillabox !== 'undefined') {
				clearTimeout(timout);
				var html = youtube_embeds[APP.pageId];
				$('a[rel*="gorillabox"]').gorillabox({
					html: html,
					width: 640,
					height: 390				
				});
			} else {
				timout = setTimeout(UCM.PageFunctions.demoPopup, 100);
			}
		},
		
		// make sure cookies are available to be able to login!
		checkCookieAvailability: function() {
			var html;
			if (APP.Cookie.test() === true)
			{
				html = '<input type="hidden" name="cookie_available" value="true" />';	
			} else {
				html = '<input type="hidden" name="cookie_available" value="" />';
			}
			$('#loginform fieldset').append(html);
		},
		
		// credit card img functions
		bindCreateAccountFunctions: function() {			
			var t1, t2,
				placeholder_type, cardnum,
				cc_images = $('#cc_images img'),
				input = $('#cc_number'),
				placeholder = input.attr('placeholder'),
				code,
				promoCode = $('#promo_code'),
				billed = $('#billed_amount'),
				discount = $('#discount');
			
			// show the help for the ccv # for create account
			$('#ccv_show_help').mouseover(				
				function(){
					t1 = setTimeout(function(){$('.help_ccv').fadeIn();}, 500); 
					//$('.help_vin').fadeIn();
			}); 
			$('#ccv_show_help').mouseout(
				function(){
					clearTimeout(t1);
					$('.help_ccv').fadeOut();
			});
			
			// show the account cancellation policy
			$('#show-policy').click(function(){
				t2 = setTimeout(function(){$('.help_cancel').fadeIn();}, 500); 				
				return false;
			});
			// hide it by clicking it 
			$('.help_cancel').click(function(){
				clearTimeout(t2);
				$(this).fadeOut();
			});
			// hide it by clicking body
			$('body').click(function(){
				clearTimeout(t2);
				$('.help_cancel').fadeOut();
			});
			
			// changes transparency of credit-card images depending on valid first digit of credit-card number
			// get the initial cc type of placeholder so can revert
			cc_images.each(function(){
				if ($(this).hasClass('opaque')) {
					placeholder_type = $(this).attr('id'); 
				}
			});
			input.bind('keyup paste change', function(e){ 
				cardnum = input.val().substr(0, 1); 
				if (cardnum !== '') {
					cc_images.each(function(){
						if ($(this).attr('id') === cc_types[cardnum]) {
							$(this).attr('class', 'opaque');
						} else {
							$(this).attr('class', 'transparent');
						}
					});
				} else if (placeholder) {
					cc_images.each(function(){  
						if ($(this).attr('id') === placeholder_type) { 
							$(this).attr('class', 'opaque');
						} else {
							$(this).attr('class', 'transparent');
						}
					});
				}	
			});
			// change transparency of clicked img and set focus to input
			$('#cc_images img').each(function(){
				$(this).bind('click', function(){
					val = input.val();
					if ((val !== '') && (val !== placeholder)) {
						return;
					} else {
						// clear the placeholder
						input.val('');
						$('#cc_images img').attr('class', 'transparent');
						$(this).attr('class', 'opaque');						
						//$('#cc_number').val(types[$(this).attr('id')]);
						input.focus();	
					}					
				});
			});
			
			// user ui for promo code for creating account
			// on load
			code = jQuery.trim(promoCode.val());
			if (code !== '' && APP.MyArray.inArray(code, valid_promos)) { 
				if (code === 'UCM9040') { 
					billed.html('$50.00');
					discount.html('-$40.00');
				} else { 
					billed.html('$00.00');
					discount.html('-$99.00');
				}							
			} else {
				billed.html('$99.00');
				discount.html('&nbsp;');
			}

			// on keyup
			promoCode.bind('keyup paste', function(){ 
				var code = $(this).val().toUpperCase();
				$(this).val(code);
//				if (code.length > 7) { 
					if (APP.MyArray.inArray(jQuery.trim(code), valid_promos)) { 
						if (code === 'UCM9040') { 
							billed.html('$50.00');
							discount.html('-$40.00');
						} else { 
							billed.html('$00.00');
							discount.html('-$99.00');
						}							
					} else {
						billed.html('$99.00');
						discount.html('&nbsp;');
					}				 
//				}
			});
		},

		// check/uncheck all the makes on the user preferences page
		checkAll: function() { 
			$('fieldset.makes input:checkbox').each(function(){ 
				$(this).click(function(){ 
					if ($(this).is(':checked')) {
						$('#allmakes').removeAttr('checked');
					}
				}); 					
			});
			// also, make the "other makes" uncheck the allmakes
			$('#othermakes').focus(function(){
				$('#allmakes').removeAttr('checked');
			});
			$('#othermakes').blur(function(){
				if ($(this).val() === '') {
					$('#allmakes').attr('checked', 'checked');
				}
			});
		},
		
		// test the user's sms settings on preference page
		smsTest: function() {
			$('#sms_test').click(function(){
				var mobilephone = $('#mobilephone').val();
				var mobile_carrier_domain = $('#mobile_carrier_domain').val();
				if (mobilephone === '' || mobile_carrier_domain === '')	{
					alert('Both your mobile phone number and carrier domain must be set to run a test.');
				} else {
					jQuery.ajax({
						cache: false,
						url: AJAX_URL + 'sms_test',
						type: 'post',
						data: 'mobilephone=' + mobilephone + '&mobile_carrier_domain=' + mobile_carrier_domain,
						success: function(data){
							if (data === 'success') {
								alert('A message was sent to your phone.');
							} else {
								alert('There was a problem with the test');
							}
						}
					});
				}
			});
		},
		
		// fade out the user messages
		fadeMessage: function() { 
			setTimeout(function(){
				$('#user-message').fadeOut('slow');
			}, 1000);
			
		}

	};
}(UCM, jQuery));


// load the js only if jQuery is available
var timout;
(function loadJS() { 
	if (window.jQuery) {
		clearTimeout(timout);
		$(document).ready(function() { 
			UCM.init();
		});
	} else {
		timout = setTimeout(loadJS, 100);	
	}
}());
