/*******************************
        Debug & Console
*******************************/

// Allow for console.log to not break IE
if (typeof console == "undefined" || typeof console.log == "undefined") {
	var console = { 
		log: function() {}
	};
}

/*******************************
		  FAV4 Config
*******************************/

// object stub (see methods for reference)

if(typeof(window.fav4) == 'undefined') {
	window.fav4 = {};	
}
// recursively merge
$.extend(true, fav4, {
	footer: {},
	scroll: {},
	icon: {},
	lights: {},
	search: {},
	settings: {},
	utils: {},
	user: {}
});


$.extend(fav4, {
	// delay before following link to wait for cookie to set
	cookieDelay: 250,
	currentVersion: 2,
	showUpdate: false,
	cookie: {
		icons: 'myFavFour',
		colors: 'myColors',
		urls: 'myUrls',
		theme: 'theme',
		searchEngine: 'searchEngine',
		searchFocus: 'searchFocus',
		newWindow: 'useNewWindow',
		searchLocation: 'searchLocation',
		version: 'siteVersion',
		sortable: 'sortable',
		layout: 'layout',
		numRows: 'numRows',
		iconsPerPage: 'iconsPerPage',
		pageBreaks: 'pageBreaks',
		fromFav4: 'fromFav4',
		rightClick: 'rightClick',
		enableKeyboard: 'enableKeyboard',
		shortcutType: 'shorcutType',
		
		/* New V2 */
		username: 'username',
		oid: 'oid',
		iconType: 'iconType',
		
		sheen: 'sheen',
		
		dismissNag: 'dismissNag',
		
		cookieOptions: {
			path: '/', 
			expires: 360,
			domain: '.myfav.es'
		}
	},
	defaultColor: 'black',
	colors: [
		'transparent', 
		'silver', 
		'bright-blue', 
		'blue', 
		'black', 
		'red', 
		'green', 
		'orange', 
		'pink', 
		'purple', 
		'yellow'
	],
	lightThemes: [
		'wood-birch', 
		'gradient-watercolors',
		'metal-white',
		'subtle-45degreee-fabric',
		'subtle-60degree-gray',
		'subtle-beige-paper',
		'subtle-bright-square',
		'subtle-brushed-aluminum-light',
		'subtle-concrete-wall2',
		'subtle-concrete-wall3',
		'subtle-cork1',
		'subtle-double-lined',
		'subtle-exclusive-paper',
		'subtle-fabric1',
		'subtle-grunge-wall',
		'subtle-handmade-paper',
		'subtle-leather1',
		'subtle-light-honeycomb',
		'subtle-little-plusses',
		'subtle-noisy',
		'subtle-old-math',
		'subtle-paper1',
		'subtle-paper2',
		'subtle-paper3',
		'subtle-pinstripe',
		'subtle-rocky-wall',
		'subtle-smooth-wall',
		'subtle-soft-wallpaper',
		'subtle-freckles',
		'subtle-orange',
		'subtle-vichy',
		'subtle-wavecut',
		'subtle-white-carbon',
		'subtle-white-sand'
	],
	darkThemes: [
		'wood-mahogany', 
		'wood-weatheredelm', 
		'gradient-nebula', 
		'gradient-blueglow', 
		'gradient-moonlight', 
		'gradient-nuclearnight',
		'gradient-pinkeclipse',
		'metal-slate',
		'subtle-always-grey',
		'subtle-black-denim',
		'subtle-black-linen',
		'subtle-black-mamba',
		'subtle-black-paper',
		'subtle-brushed-aluminum-dark',
		'subtle-carbon-fibre',
		'subtle-concrete-wall',
		'subtle-crossed-stripes',
		'subtle-dark-stripes',
		'subtle-gray-sand',
		'subtle-green-fibers',
		'subtle-micro-carbon',
		'subtle-padded',
		'subtle-random-gray',
		'subtle-tactile-noise',
		'subtle-wood'
	],
	urlPrompt: '',
	iconWidth: 181,
	searchHeight: 32,
	autoCompleteHeight: 32,
	scroller: {
		showDuration: 400,
		padding: 100,
		minPadding: 125
	},
	flip: {
		// conversion multiple for card's aspect ratio in card flip
		ratio: 5.15,
		// duration of flip
		duration: 500,
		// easing
		easing: {
			scale: 'easeInOutQuad',
			rotate: 'easeInOutQuad',
			fadeIn: 'easeInQuad'
		}
	},
	
	searchFocus: false,
	enableKeyboard: true,
	shortcutType: 'numbers',
	rightClick: 'none',
	
	searchEngines: {
		google: {
			url: 'http://www.google.com/search',
			method: 'get'
		},
		bing: {
			url: 'http://www.bing.com/search',
			method: 'get'
		},
		yahoo: {
			url: 'http://search.yahoo.com/search',
			method: 'get'
		},
		imdb: {
			url: 'http://www.imdb.com/find',
			method: 'post'
		},
		wikipedia: {
			url: 'http://www.wikipedia.org/search-redirect.php',
			method: 'get'
		}
	},
	fancyConfig: {
		'autoDimensions': false,
		'width': 770,
		'height': 400,
		'titleShow': false,
		'autoScale': false
	},
	
	// default settings for customizations
	noKeyboardMode: false,
	noScrollMode: false,
	dancing: false,
	useNewWindow: false,
	
	layout: 'pages',
	numRows: 1,
	iconsPerPage: 'auto',
	
	iconType: 'shadow',
	searchPromptText: 'Start typing your search...'	
});
	
	
/*******************************
		 FAV4 Events
*******************************/

fav4.onLoad = function() {
	if(fav4.section == 'settings') {
		// nav continuity
		fav4.settings.navContinuity();	
	}
};
$(window).bind('load', fav4.onLoad);

fav4.onReady = function() {	

	fav4.initOfflineCache();

	// Read essential cookies early
	fav4.initCookies();
	
	// are you on a foreign profile?
	fav4.foreignProfile = false;
	if(fav4.user && fav4.user.settings && typeof(fav4.user.settings.foreign) != 'undefined' && fav4.user.settings.foreign == 1) {
		fav4.foreignProfile = true;	
	}
	
	// device detect
	fav4.iPad = fav4.isiPad();
	fav4.iPhone = fav4.isiPhone();
	
	// navigation animations
	var downEvent = 'mousedown';
	var upEvent = 'mouseleave';
	if(fav4.iPad || fav4.iPhone) {
		downEvent = 'touchstart';
		upEvent = 'touchend';	
	}
	
	// jq cache
	var $body = $('body');
		
	// which page are we on, add tag for layout specific css		
	var section = fav4.section = $body
		.attr('id')
	;
	 
	// jq cache
	var $content = $('#content');
	
	
	// Protect from being run externally
	fav4.protect();
	
	// Check for upgrades
	fav4.checkUpgrades();
	
	$('a.openid')
		.bind('click', fav4.loginPanel)
	;
	
	/********* Init Icons *********/		
	if(section == 'home') {
		
		// add layout class to body
		$body.addClass(fav4.layout);
		
		var fromFav4 = $.storage(fav4.cookie.fromFav4);
		// check for cookie
		if($.storage(fav4.cookie.icons)){
			
			// special init for pages 
			if(fav4.layout == 'pages') {
				fav4.pages.bundleIcons();
			}
			else {
				// iterate over each icon
				fav4.eachIcon(function(icon, index) {
					fav4.track('grid', 'icon', icon.shorthand, 1);
					fav4.icon.create(icon.shorthand, icon.url, index);
				});			
			}
			// special message for first viewing
			/*
			if(fromFav4) {
				$body
					.addClass('welcome');
				$('<h2 />')
					.html('Fav4.org is now MyFaves! <a href="settings/">See what\'s new</a>.')
					.appendTo($body)
				;
				$.storage(fav4.cookie.fromFav4, null, fav4.cookie.cookieOptions);
			}
			$("#footer a").addClass("settingsCookie");
			*/
		
		}
		// Load default page
		else {	
			$body
				.removeClass(fav4.layout)
				.addClass('welcome');
			if(!fromFav4) {
				$('<h2 />')
					.html('What are your faves? <a href="settings/">Customize</a> this page now. No account needed.')
					.appendTo($('body'))
				;
			}
			fav4.icon.create('facebook', './settings/', 1);
			fav4.icon.create('gmail', './settings/', 2);
			fav4.icon.create('flickr', './settings/', 3);	
			fav4.icon.create('twitter', './settings/', 4);
			fav4.icon.create('customize', './settings/', 5);
			return;
		}
	}
	/********* Cookie Customizations *********/	
	
	// add customizations
	fav4.customize();
		
	
	/********* Fav4 Init *********/
	if(section == 'home') {
		
		// add icon type class
		$body
			.addClass(fav4.iconType)	
			.addClass(fav4.sheen)
		;		
				
		/********* Init Layouts *********/	
		
		// init scroll
		if(fav4.layout == 'magiscroll') {	
			fav4.scroll.positionMenu();
			fav4.scroll.bindEvents();
		}
		else if(fav4.layout == 'pages') {
			//fav4.pages.positionMenu();
			//fav4.pages.bindEvents();	
		}
		else if(fav4.layout == 'polygon') {
			fav4.polygon.init();
		}
		
		/********** Search **********/
		$('#search input[type=text]')
			.hover(function() {
				$(this).addClass('hover');						
			},function() {
				$(this).removeClass('hover');
			})
			.bind('focus', function() {
				$(this).addClass('focus');	
				fav4.noKeyboardMode = true;						
			})
			.bind('blur', function() {		
				$(this).removeClass('focus');					   
				fav4.noKeyboardMode = false;	
			})
		;
			   
		// rigth click context
		if(fav4.rightClick != 'none') {
			$content
				.find('.content')
					.rightClick(function() {
						if(!$(this).hasClass('animating')) {
							if($(this).find('.front').visible()) {
								if(!$('#content .icon .back:visible, #content .icon .content:animated').exists()) {
									if(fav4.rightClick == 'flip') {
										// make sure this is your profile to customize
										if(!fav4.foreignProfile) {
											$(this).siblings('.customize').click();
										}
									}
									else if(fav4.rightClick == 'newwindow') {
										var href = $(this).find('.link').attr('href');
										window.open(href, '_blank');
									}
								}
							}
							else {
								if(fav4.rightClick == 'flip') {
									$(this).find('.back .close').click();	
								}
							}							
							return false;	
						}
					})
			;
		}
		
		/* Icon Reflections */
		if(fav4.iconType == 'floatReflect' || fav4.iconType == 'tableReflect') {
			fav4.reflect();
			$(window).resize(fav4.reflect);
		}
		
		// gmail inbox check
		fav4.checkMail();
		// recheck mail every 60 seconds
		setInterval(fav4.checkMail, (1000 * 60));
		// gmail inbox check
		fav4.checkReader();
		// recheck mail every 60 seconds
		setInterval(fav4.checkReader, (1000 * 60));
			   
		/********** Custom Links **********/
		
		$content
			.find('li .front > a')
				.bind('mouseover', function(){
					var $front = $(this).parent();
					$front.addClass('hover');
					// make sure its your profile
					if(!fav4.foreignProfile) {
						var $customizeIcon = $(this).parents('.icon').find('.customize');
						// make sure not editing any icons currently
						if(!$('#content .icon .back:visible').exists() && !$(this).parents('li').hasClass('ui-sortable-helper')) {
							clearTimeout(fav4.timer);
							fav4.timer = setTimeout(function() {
								$customizeIcon.fadeIn(200);
							}, 300);
						}
					}
				})
				.bind('mousedown', function(e) {
						e.preventDefault();
				})
				.end()
			.find('li')
				.bind('mouseleave', function() {
					var $front = $(this).find('.front');
					$front.removeClass('hover');
					clearTimeout(fav4.timer);
					$(this).find('.customize').hide();
				})
				.end()
			.find('li a')
				.bind(downEvent, function() {
					var $icon = $(this).parent();
					$icon.addClass('down');	
					$(this).bind('mouseleave.escape', function() {
						$icon.removeClass('down');	
						$(this).unbind('mouseleave.escape');	   
					});
				})
				.bind(upEvent, function() {
					var $icon = $(this).parent();
					$icon.removeClass('down');
					$(this).unbind('mouseleave.escape');
				})
				.end()
			.find('.icon .front a.link')
				.bind('click.flip', fav4.flipLink)
				.end()
			.find('.customize')
				.bind('click', function() {	
					if(!fav4.foreignProfile) {
						// clear timeout to show
						clearTimeout(fav4.timer);
						// hide customize button
						$(this).hide();
						// disable keyboard
						fav4.noKeyboardMode = true;
						fav4.noScrollMode = true;
						// find content to flip
						var $content = $(this).siblings('.content');
						fav4.iconFlip($content);		
						return false;
					}
				})
				.end()
			.find('li .back .close')
				.hoverClass()
				.bind('click', function() {
					// enable keyboard
					fav4.noKeyboardMode = false;
					fav4.noScrollMode = false;
					// find content to flip
					var $content = $(this).parents('.content');
					fav4.iconFlip($content);		
					return false;								 
				})
				.end()
			.find('li .back input.url')
				.bind('keydown', function(event) {
					if(event.keyCode == 13) {
						$(this).siblings('.save').addClass('down');
					}
				})
				.bind('keyup', function(event) {
					if(event.keyCode == 13) {
						$(this).blur();
						$(this).siblings('.save')
							.removeClass('down')
							.click()
						;
					}				
				})
				.end()
			.find('li .back .save')
				.hoverClass()
				.downClass()
				.bind('click', function() {
					// grab icon
					var $icon = $(this).parents('.icon');
					// enable keyboard
					fav4.noKeyboardMode = false;
					fav4.noScrollMode = false;
					// save no cookie data and reinit
					fav4.settings.saveCustomUrl($icon);
					fav4.settings.saveCustomColor($icon);
					// find content to flip
					var $content = $(this).parents('.content');
					fav4.iconFlip($content);		
				})
		;	
		
		/*******************************
				Keyboard Bindings
		*******************************/
		
		$(document)
			.bind('keydown', function(event) {
				var $list = $('#content > ul > li, #content .page.active ul li');
				var keycode = event.keyCode;
				if(!fav4.noKeyboardMode && fav4.enableKeyboard) {
					if(fav4.shortcutType == 'all' || fav4.shortcutType == 'numbers') {
						switch(keycode) {
							case 49: case 97:
								fav4.track('site', 'keyboard-shortcut', '1', 1);
								$list.eq(0).find('.front').addClass('down');
							break;
						
							case 50: case 98:
								fav4.track('site', 'keyboard-shortcut', '2', 1);
								$list.eq(1).find('.front').addClass('down');
							break;
						
							case 51: case 99:
								fav4.track('site', 'keyboard-shortcut', '3', 1);
								$list.eq(2).find('.front').addClass('down');
							break;
						
							case 52: case 100:
								fav4.track('site', 'keyboard-shortcut', '4', 1);
								$list.eq(3).find('.front').addClass('down');
							break;
						
							case 53: case 101:
								fav4.track('site', 'keyboard-shortcut', '5', 1);
								$list.eq(4).find('.front').addClass('down');
							break;
						
							case 54: case 102:
								fav4.track('site', 'keyboard-shortcut', '6', 1);
								$list.eq(5).find('.front').addClass('down');
							break;
						
							case 55: case 103:
								fav4.track('site', 'keyboard-shortcut', '7', 1);
								$list.eq(6).find('.front').addClass('down');
							break;
						
							case 56: case 104:
								fav4.track('site', 'keyboard-shortcut', '8', 1);
								$list.eq(7).find('.front').addClass('down');
							break;
						
							case 57: case 105:
								fav4.track('site', 'keyboard-shortcut', '9', 1);
								$list.eq(8).find('.front').addClass('down');
							break;
						
							case 187: case 100:
								fav4.track('site', 'keyboard-shortcut', '10', 1);
								$list.eq(9).find('.front').addClass('down');
							break;
						
							case 67: // c for config
								$('#settings').addClass('skey');
							break;
						
							default:
							break;
						}
					}
					if(fav4.shortcutType == 'all' || fav4.shortcutType == 'letters') {
						switch(keycode) {
							case 65:
								fav4.track('site', 'keyboard-shortcut', '1', 1);
								$list.eq(0).find('.front').addClass('down');
							break;
						
							case 83:
								fav4.track('site', 'keyboard-shortcut', '2', 1);
								$list.eq(1).find('.front').addClass('down');
							break;
						
							case 68:
								fav4.track('site', 'keyboard-shortcut', '3', 1);
								$list.eq(2).find('.front').addClass('down');
							break;
						
							case 70:
								fav4.track('site', 'keyboard-shortcut', '4', 1);
								$list.eq(3).find('.front').addClass('down');
							break;
						
							case 71:
								fav4.track('site', 'keyboard-shortcut', '5', 1);
								$list.eq(4).find('.front').addClass('down');
							break;
						
							case 72:
								fav4.track('site', 'keyboard-shortcut', '6', 1);
								$list.eq(5).find('.front').addClass('down');
							break;
						
							case 74:
								fav4.track('site', 'keyboard-shortcut', '7', 1);
								$list.eq(6).find('.front').addClass('down');
							break;
						
							case 75:
								fav4.track('site', 'keyboard-shortcut', '8', 1);
								$list.eq(7).find('.front').addClass('down');
							break;
						
							case 76:
								fav4.track('site', 'keyboard-shortcut', '9', 1);
								$list.eq(8).find('.front').addClass('down');
							break;
						
							case 59:
								fav4.track('site', 'keyboard-shortcut', '10', 1);
								$list.eq(9).find('.front').addClass('down');
							break;
						
							case 67: // c for config
								$('#settings').addClass('skey');
							break;
						
							default:
							break;
						}
					}
				}
			})
			.bind('keyup', function(event) {
				var $list = $('#content > ul > li, #content .page.active ul li');			
				var keycode = event.keyCode;
				var shiftKey = event.shiftKey;
				
				if (fav4.noKeyboardMode || !fav4.enableKeyboard) {
					// ESC
				}
				else {
					if(keycode == 75) {
						if(shiftKey) {
							if($('#home').hasClass('bg1')) {
								$('#home').removeClass('lightson bg1 bg2 bg3').addClass('lightsout searchbottomcenter').addClass('bg2');								
							}
							else if($('#home').hasClass('bg2')) {
								$('#home').removeClass('lightson bg1 bg2 bg3').addClass('lightsout searchbottomcenter').addClass('bg3');								
							}
							else if($('#home').hasClass('bg3')) {
								$('#home').removeClass('lightson bg1 bg2 bg3').addClass('lightsout searchbottomcenter');								
							}
							else {
								$('#home').removeClass('lightson bg1 bg2 bg3').addClass('lightsout searchbottomcenter').addClass('bg1');								
							}
						}
					}
					if(fav4.shortcutType == 'all' || fav4.shortcutType == 'numbers') {
						switch(keycode) {
						case 49: case 97: 
							 $list.eq(0).find('.front').removeClass('down');
							 fav4.openLink(0);
							 break;
						
						  case 50: case 98:
							 $list.eq(1).find('.front').removeClass('down');
							 fav4.openLink(1);
							 break;
						
						  case 51: case 99:
							 $list.eq(2).find('.front').removeClass('down');
							 fav4.openLink(2);
							 break;
						
						  case 52: case 100:
							 $list.eq(3).find('.front').removeClass('down');
							 fav4.openLink(3);
							 break;
							 
						  case 53: case 101:
							 $list.eq(4).find('.front').removeClass('down');
							 fav4.openLink(4);
							 break;
						
						  case 54: case 102:
							 $list.eq(5).find('.front').removeClass('down');
							 fav4.openLink(5);
							 break;
						
						  case 55: case 103:
							 $list.eq(6).find('.front').removeClass('down');
							 fav4.openLink(6);
							 break;
						
						  case 56: case 104:
							 $list.eq(7).find('.front').removeClass('down');
							 fav4.openLink(7);
							 break;
						
						  case 57: case 105:
							 $list.eq(8).find('.front').removeClass('down');
							 fav4.openLink(8);
							 break;
						
						  case 187: case 100:
							 $list.eq(9).find('.front').removeClass('down');
							 fav4.openLink(9);
							 break;
						}
					}
					if(fav4.shortcutType == 'all' || fav4.shortcutType == 'letters') {
						switch(keycode) {
						  case 65:
							 $list.eq(0).find('.front').removeClass('down');
							 fav4.openLink(0);
							 break;
						
						  case 83:
							 $list.eq(1).find('.front').removeClass('down');
							 fav4.openLink(1);
							 break;
						
						  case 68:
							 $list.eq(2).find('.front').removeClass('down');
							 fav4.openLink(2);
							 break;
						
						  case 70:
							 $list.eq(3).find('.front').removeClass('down');
							 fav4.openLink(3);
							 break;
							 
						  case 71:
							 $list.eq(4).find('.front').removeClass('down');
							 fav4.openLink(4);
							 break;
						
						  case 72:
							 $list.eq(5).find('.front').removeClass('down');
							 fav4.openLink(5);
							 break;
						
						  case 74:
							 $list.eq(6).find('.front').removeClass('down');
							 fav4.openLink(6);
							 break;
						
						  case 75:
							 $list.eq(7).find('.front').removeClass('down');
							 fav4.openLink(7);
							 break;
						
						  case 76:
							 $list.eq(8).find('.front').removeClass('down');
							 fav4.openLink(8);
							 break;
						
						  case 59:
							 $list.eq(9).find('.front').removeClass('down');
							 fav4.openLink(9);
							 break;
						}
					}
				}
			})
		;
		
		fav4.nag();
		
	}
	
	/********* Settings Init *********/
	if(section == 'settings') {
		
		// disable keyboard shortcuts
		fav4.noKeyboardMode = true;
				
		$('nav li')
			.smoothHover(200)
			.smoothDown(200, {
				instantOn: true,
				click: function() {
					fav4.clicked = true;
					var $this = $(this);
					$this.find('.down').stop();
					setTimeout(function() {
						var href = $this.find('a').attr('href');
						var base = $('base').attr('href');
						if(href) {
							if(base) {
								window.location = base + href;	
							}
							else {
								window.location = href;	
							}
						}
					}, 200);
				}
			})
			.bind(downEvent, function() {
				$(this).siblings('.active')
					.find('.down')
						.hide()
						.end()
					.find('.active')
						.fadeOut(200)
				;
			})
			.bind(upEvent, function() {
				if(!fav4.clicked) {
					$(this).siblings('.active').find('.active')
						.fadeIn(200)
					;
				}
			})
		;
		$('#settings .search input')
			.hover(function() {
				$(this).addClass('hover');						
			},function() {
				$(this).removeClass('hover');
			})
			.bind('focus', function() {
				var $search = $(this);
				$search.addClass('focus');
				if($search.val() == fav4.searchPromptText) {
					$search.val('');	
				}
			})
			.bind('blur', function() {		
				var $search = $(this);
				$search.removeClass('focus');
				if($search.val() == '') {
					$search.val(fav4.searchPromptText);	
				}	
			})
			.bind('keyup', function(event) {
				var $this = $(this);
				var $tab = $this.parents('.tab');
				var $searchField = $tab.find('.search .field');
				var searchValue = $this.val();
				if(fav4.utils.trueAlphaKey(event)) {
					$searchField.addClass('loading');
					if(typeof(fav4.timer) != 'undefined') {
						clearTimeout(fav4.timer);	
					}
					fav4.timer = setTimeout(function() {
						var $filterGroup = $this.parents('.search').siblings('ul').find('li');
						fav4.settings.iconSearch(searchValue, $filterGroup, $tab);
					}, 200);
				}
				else {
					$searchField.removeClass('loading');	
				}
			})
		;
		
		// logging out
		$('#login .logout').click(function() {
			fav4.settings.logout();
			return false;
		});
		
		// sites tab
		if($('#sites, #admin').exists()) {
			
			$('select, input:checkbox, input:radio, input:file')
				.uniform({resetSelector: 'button[type="reset"]'})
			;
			$('#settings .sort select')
				.change(function() {
					window.location = $(this).val();
				})
			;
			
			$('#featured .add')
				.hoverClass()
				.downClass()
				.bind('click', function() {
					var $iconBlock = $(this).parent();
					var $allIcons = $('#all-sites ul > li');
					var identifier = $iconBlock.find('.meta .identifier').text();
					var url = $iconBlock.find('.meta .url').text();
					var name = $iconBlock.find('.name').text();
					// not currently a fav, add it
					if(!$iconBlock.hasClass('active')) {
						$iconBlock.addClass('loading');
						// add icon cookie
						fav4.settings.addIcon(identifier, url);
						setTimeout(function() {
							fav4.growl();
							$iconBlock
								.removeClass('loading')
								.addClass('active')
							;
							// update ui
							fav4.settings.addFavesUI(name, identifier, url);
							// update other lists
							$allIcons
								.filter('.'+identifier)
								.addClass('active');
						}, 400);
					}
					// remove fav
					else {
						$iconBlock.addClass('loading');
						fav4.settings.removeIcon(identifier, url);
						// update ui
						setTimeout(function() {
							fav4.growl();
							$iconBlock
								.removeClass('loading')
								.removeClass('active')
							;
							fav4.settings.removeFavesUI(identifier, url);
							// update other lists
							$allIcons
								.filter('.'+identifier)
								.removeClass('active');
						}, 400);
					}
				})
			;
			$('#all-sites .left > ul li')
				.hoverClass()
				.downClass()
				.bind('click', function() {
					var $iconBlock = $(this);
					if(!$iconBlock.hasClass('alert')) {
						var $featuredIcons = $('#featured .left li');
						var identifier = $iconBlock.find('.meta .identifier').text();
						var url = $iconBlock.find('.meta .url').text();
						var name = $iconBlock.find('.name').text();
						// not currently a fav, add it
						if(!$iconBlock.hasClass('active')) {
							$iconBlock.addClass('loading');
							fav4.settings.addIcon(identifier, url);
							setTimeout(function() {
								fav4.growl();
								$iconBlock
									.removeClass('loading')
									.addClass('active')
									.addClass('alert')
								;
								// update ui
								fav4.settings.addFavesUI(name, identifier, url);
								$featuredIcons
									.filter('.'+identifier)
									.addClass('active');
								setTimeout(function() {
									$iconBlock.removeClass('alert');
								}, 2000);
							}, 400);
						}
						// remove fav
						else {
							$iconBlock.addClass('loading');
							fav4.settings.removeIcon(identifier, url);
							setTimeout(function() {
								fav4.growl();
								$iconBlock
									.removeClass('loading')
									.removeClass('active')
								;
								fav4.settings.removeFavesUI(identifier, url);
								$featuredIcons
									.filter('.'+identifier)
									.removeClass('active');
							}, 400);
						}
					}
				})
			;
			$('#settings .modal')
				.find('form') 
					.bind('submit', function(){
						$('#settings .modal .save').click();
						return false;
					})
					.end()
				.find('.color')
					.bind('change', function() {
						var $field = $(this);
						var $icon = $field.parents('.modal').find('.icon .bg img');
						var color = $field.val();
						if(color == 'transparent') {
							$icon.removeAttr('src');
							$icon.hide();
						}
						else {
							$icon.show();
							$icon.attr('src', 'images/icons/bg/custombg-'+color+'.png'); 
						}
					})
			;
			
			$('#customize .left > ul li')
				.hoverClass()
				.downClass()
				.bind('click', function() {
					var $iconBlock = $(this);
					if(!$iconBlock.hasClass('alert')) {
						var $featuredIcons = $('#featured .left li');
						var identifier = $iconBlock.find('.meta .identifier').text();
						var url = $iconBlock.find('.meta .url').text();
						var name = $iconBlock.find('.name').text();
						// not currently a fav, add it
						if(!$iconBlock.hasClass('active')) {
							$iconBlock.addClass('loading');
							var $wrapper = $('#wrapper');
							var $dimmer = $('#settings .dimmer');
							var $modal = $('#settings .modal');
							var $icon = $modal.find('.icon .front img');
							$icon.attr('src','images/icons/fullsize/'+identifier+'.png');
							$wrapper.addClass('animating');
							$dimmer.show();
							var animationDuration = 200;
							if(fav4.iPad || fav4.iPhone) {
								animationDuration = 0;	
							}
							$modal
								.find('.save')
									.hoverClass()
									.downClass()
									.one('click', function() {
										var newURL = $modal.find('.url').val();
										var newColor = $modal.find('.color').val();
										$dimmer.hide();
										$modal.hide();
										fav4.settings.addIcon(identifier, url);
										fav4.settings.addFavesUI(name, identifier, newURL, newColor);
										fav4.changeUrl(identifier, newURL);
										fav4.changeColor(identifier, newColor);
										fav4.growl();
										$iconBlock
											.removeClass('loading')
											.addClass('alert')
											.addClass('active')
										;
										setTimeout(function() {
											$iconBlock.removeClass('alert');	
										}, 2000);
										// clear one
										$modal.find('.save, .cancel').unbind();								
									})
									.end()
								.find('.cancel')
									.hoverClass()
									.downClass()
									.one('click', function() {
										$dimmer.hide();
										$modal.hide();	
										$iconBlock.removeClass('loading');
										// clear one
										$modal.find('.save, .cancel').unbind();							
									})
									.end()
								.css({
									opacity: 0,
									width: '385px',
									height: '158px',	
									marginTop: '-120px',
									marginLeft: '-214px'								
								})
								.show()
								.animate({
									opacity: 1,
									width: '538px',
									height: '210px',
									marginTop: '-125px',
									marginLeft: '-285px'	
								}, animationDuration, function(){
									$wrapper.removeClass('animating');
									$(this).find('.color').trigger('change');
								})
							;
						}
						// remove fav
						else {
							$iconBlock.addClass('loading');
							fav4.settings.removeIcon(identifier, url);
							setTimeout(function() {
								fav4.growl();
								$iconBlock
									.removeClass('loading')
									.removeClass('active')
								;
								fav4.settings.removeFavesUI(identifier, url);
								$featuredIcons
									.filter('.'+identifier)
									.removeClass('active');
							}, 400);
						}
					}
				})
			;
			
			var sortableSettings = {
				cursor: '',
				distance: 0,
				revert: 200,
				tolerance: 'pointer',
				scroll: false,
				placeholder: 'placeholder',
				update: function(event, ui) {
					fav4.growl();
					fav4.settings.resortSettingsIcons();
				}
			};
			var $favList = $('#myfaves .list ul');
			$favList
				.sortable(sortableSettings)
				.find('li')
					.hoverClass({
						useLive: true,
						context: $favList	
					})
					.downClass({
						useLive: true,
						context: $favList,
						filter: '.edit'	
					})
			;
			$favList
				.bind('touchmove', function(e){ e.preventDefault(); })
				.addTouch();
			$('#myfaves .list input')
				.bind('focus', function() {
					$(this).parent().addClass('focus');	
				})
				.bind('blur', function() {
					$(this).parent().removeClass('focus');	
				})
			;
			
			// trash
			var droppableSettings = {
				activeClass: 'active',
				hoverClass: 'drop',
				over: function(event, ui) {
					var $draggable = $(ui.draggable);
					var name = $draggable.find('.name').html();
					$draggable
						.data('name', name)
						.addClass('remove')
						.find('.name')
							.html('Remove '+name+'?')
					;
				},
				out: function(event, ui) {
					var $draggable = $(ui.draggable);
					var name = $draggable.data('name');
					$draggable
						.removeClass('delete')
						.find('.name')
							.html(name)	
					;	
				},
				drop: function(event, ui) {
					var $draggable = $(ui.draggable);
					var name = $draggable.data('name');
					var identifier = $draggable.find('.meta .identifier').text();
					$(ui.helper).addClass('hide');
					$('#myfaves .placeholder').hide();
					$draggable
						.removeClass('remove hover down')
						.addClass('hide')
						.find('.name')
							.html(name)
					;
					fav4.growl();
					fav4.settings.poof();
					fav4.settings.updateFavesUI();
					
					// remove active items from other lists
					setTimeout(function() {
						$('#featured .left li, #all-sites .left ul > li, #customize .left ul > li')
							.filter('.'+identifier)
								.removeClass('active')
						;
					}, 300);
									
					// undo message
					$('#myfaves .undo')
						.data('identifier', identifier)
						.html('<b>'+name+'</b> has been removed. <a href="#">Undo?</a>')
						.find('a')
							.bind('click', function() {
								var $undo = $('#content .undo');
								var $list = $('#myfaves .list ul');
								var identifier = $undo.data('identifier');
								$list.find('li.hide.'+identifier).removeClass('hide');
								fav4.settings.resortSettingsIcons();
								$undo.empty();
								fav4.settings.updateFavesUI();	
								// add active items to other lists
								setTimeout(function() {
									$('#featured .left li, #all-sites .left ul > li, #customize .left ul > li')
										.filter('.'+identifier)
											.addClass('active')
									;
								}, 300);
								return false;	
							})
					;
					fav4.settings.resortSettingsIcons();
				}
			};
			
			// edit mode
			$('#myfaves')
				.find('.modify')
					.hoverClass()
					.bind('click', function() {
						var $list = $(this).parents('.list');
						var $fields = $list.find('.color, .custom-url');
						if(!$list.hasClass('edit')) {
							$list.addClass('edit');
							$favList.sortable('disable');
							// store cancel data
							$fields.each(function() {
								var $field = $(this);
								$field.data('cancel', $field.val());
							});
						}
					})
					.end()
				.find('.actions div')
					.hoverClass()
					.downClass()
					.end()
				.find('.actions .save')
					.bind('click', function() {
						var $list = $(this).parents('.list');
						$list.removeClass('edit');	
						$favList.sortable('enable');
						fav4.growl();
						$favList.find('li').each(function() {
							var $icon = $(this);
							var $color = $icon.find('.color');
							var $customURL = $icon.find('.custom-url');
							var identifier = $icon.find('.identifier').html();
							if($color.exists()) {
								var newColor = $color.val();
								if(newColor != $color.data('cancel')) {
									fav4.changeColor(identifier, newColor);
								}
							}
							if($customURL.exists()) {
								var newURL = $customURL.val();
								if(newURL != $customURL.data('cancel')) {
									fav4.changeUrl(identifier, newURL);
								}
							}
						});
					})
					.end()
				.find('.actions .cancel')
					.bind('click', function() {
						var $list = $(this).parents('.list');
						var $fields = $list.find('.color, .custom-url');
						$list.removeClass('edit');
						// retrieve cancel data
						$fields.each(function() {
							var $field = $(this);
							$field.val($field.data('cancel'));
						});
						$.uniform.update($fields);
						$favList.sortable('enable');					
					})
					.end()
				.find('.trash')
					.droppable(droppableSettings)
			;
		}
		
		// options tab
		if($('#options').exists()) {
			$('select, input:checkbox, input:radio, input:file')
				.uniform({resetSelector: 'button[type="reset"]'})
			;
			
			// color picker
			var colorPickerOptions = {
				onShow: function (colorPicker) {
					$(colorPicker).show();
					return false;
				},
				onHide: function (colorPicker) {
					$(colorPicker).fadeOut(200);
					return false;
				},
				onChange: function (hsb, hex, rgb) {
					var hexCode = '#'+ hex;
					$('#backgrounds .solid .color').css('backgroundColor', hexCode);
					$('#backgrounds .solid .theme').html('solid-'+hex);
				},
				onSubmit: function (hsb, hex, rgb) {
					$('.colorpicker').fadeOut(200);
					$('#backgrounds .solid').removeClass('active');
					$('#backgrounds .solid .select').click();					
				}
			};
			// set default color if solid
			var theme = $.cookie('theme');
			if(typeof(theme) == 'string' && theme.search('solid') != -1) {
				colorPickerOptions.color = theme.split('-')[1];
			}
			else {
				colorPickerOptions.color = 'FFFFFF';
			}
			$('#backgrounds .color-picker').ColorPicker(colorPickerOptions);

			
			// init			
			$('#sheen')
				.change(function() {
					var settingValue = $(this).val();
					var settingName = $(this).attr('id');
					fav4.growl();
					$.storage(settingName, settingValue , fav4.cookie.cookieOptions);	
					$('#preview-top')
						.attr('class','')
						.addClass(settingValue)
					;
				})
			;
			$('#iconType')
				.change(function() {
					var settingValue = $(this).val();
					var settingName = $(this).attr('id');
					fav4.growl();
					$.storage(settingName, settingValue , fav4.cookie.cookieOptions);	
					$('#preview-bottom')
						.attr('class','')
						.addClass(settingValue)
					;					
				})
			;
			$('#settings ul.rows .select')
				.hoverClass()
				.downClass()
				.bind('click', function() {
					var $button = $(this);
					var $option = $button.parents('li');
					if(!$option.hasClass('active')) {
						if($.browser.msie && parseInt($.browser.version, 10) == 7) {
							var layout = $option.find('.layout').html();
							if(layout == 'magiscroll') {
								if (confirm("Sorry IE7 does not support magiscroll technology. Would you like to download Google Chrome?")) {
									window.location = 'http://www.google.com/chrome/';
									
								}
								return;						
							}
						}
						$option
							.find('.prefs')
								.children().each(function() {
									var cookieName = $(this).attr('class');
									var cookieValue = $(this).html();
									$.cookie(fav4.cookie[cookieName], cookieValue , fav4.cookie.cookieOptions);
								})
						;					
						$option
							.find('select')
								.each(function() {
									var cookieName = $(this).attr('class');
									var cookieValue = $(this).val();
									$.cookie(fav4.cookie[cookieName], cookieValue , fav4.cookie.cookieOptions);
								})			
						;
						$button.addClass('loading');
						if($.cookie('username')) {
							fav4.settings.syncSettings();	
						}
						setTimeout(function(){ 
							fav4.growl();
							$button.removeClass('loading');
							$option
								.addClass('active')
								.siblings()
									.removeClass('active')
									.end()
							;
							fav4.customize();
						}, 400);
					}
					return false;
				})
			;
			$('#settings ul.rows select')
				.bind('change', function() {
					var $parent = $(this).parents('li');
					var $select = $parent.find('.select');
					if($parent.filter('.active').exists()) {
						var $button = $(this).parents('li').find('.select');
						var cookieName = $(this).attr('class');
						var cookieValue = $(this).val();
						$.storage(fav4.cookie[cookieName], cookieValue , fav4.cookie.cookieOptions);	
						$button.addClass('loading');
						setTimeout(function() {
							$button.removeClass('loading');
							fav4.customize();		
						}, 400);
					}
					else {
						$select.trigger('click');
					}
				})
			;
			
			
			/* Preferences */
			
			$('#preferences input, #preferences select')
				.bind('change', function() {
					$('#preferences .save').removeClass('active');
				})
			;
			$('#preferences .save')
				.hoverClass()
				.downClass()
				.bind('click', function() {
					var $save = $(this);
					if(!$save.filter('.loading, .active').exists()) {							
						$save.addClass('loading');
						setTimeout(function() {
							$save
								.removeClass('loading')
								.addClass('active');
							fav4.settings.savePreferences();
						}, 400);
					}
					return false;
				})
			;
			
			// Hide show search options on select change
			$('#search-option').change(function() {
				fav4.settings.initSearchOptions();
			});
		}
		
		// account setup
		if($('#setup').exists()) {
			// setup uniform
			$('select, input:checkbox, input:radio, input:file')
				.uniform({
					resetSelector: 'button[type="reset"]'
				})
			;
			// setup field hover and click events
			$('.checker')
				.click(function(event) {
					event.stopImmediatePropagation();
				})
			;
			$('#setup .field')
				.bind('mouseenter', function() {
					$(this).addClass('hover');
					var fieldName = $(this).attr('id');
					$('#setup .right').find('.'+fieldName).addClass('hover');
				})
				.bind('mouseleave', function() {
					$(this).removeClass('hover');
					var fieldName = $(this).attr('id');
					$('#setup .right').find('.'+fieldName).removeClass('hover');
				})
				.bind('click', function(event) {
					var $field = $(this);
					$field.find('input[type=text]').focus();
					$checkbox = $field.find('input[type=checkbox]');
					if($checkbox.exists()) {
						if($checkbox.attr('checked')) {
							$checkbox.removeAttr('checked');
						}
						else {
							$checkbox.attr('checked', 'checked');								
						}
						$.uniform.update();
						return false;
					}
				})
			;
			$('#setup input')
				.bind('focus', function() {
					var $field = $(this).parents('.field');
					$field
						.addClass('active')
						.removeClass('hover')
						.siblings()
							.removeClass('hover')
					;			
					var fieldName = $field.attr('id');
					$('#setup .right').find('.'+fieldName)
						.addClass('active')
						.siblings()
							.removeClass('hover');		
				})
				.bind('blur', function() {
					var $field = $(this).parents('.field');
					$field
						.removeClass('active')
					;			
					var fieldName = $field.attr('id');
					$('#setup .right').find('.'+fieldName).removeClass('active');
				})
			;
			$('#username input')
				.blur(function(){
					var $validation = $('#username .validate');
					var $validationMessage = $validation.find('.message');
					// grab tentative username
					var username = $(this).val();
					$validation
						.removeClass('success failure')
					;
					if(username == '') {
						$validation.addClass('failure');
						$validationMessage.html('Choose a username');
					}
					else {
						fav4.settings.checkUsername(username, {
							success: function(response) {
								// if username doesnt exist show sucess
								if(!response.exists) {
									$validation.addClass('success');
									$validationMessage.html(response.message);
								}
								else {
									$validation.addClass('failure');
									$validationMessage.html(response.message);								
								}
							}
						});
					}
				})
			;
			$('#email input')
				.blur(function() {
					var email = $(this).val();
					var $validation = $('#email .validate');
					var $validationMessage = $validation.find('.message');
					$validation.removeClass('success failure');
					if(	fav4.utils.checkEmail(email) ) {
						$validation.addClass('success');
						$validationMessage.html('That looks good');
					}
					else {
						$validation.addClass('failure');
						$validationMessage.html("Hey that doesn't look right");	
					}
				})
			;
			$('#setup .submit')
				.hoverClass()
				.downClass()
				.click(function() {
					var $email =  $('#email input');
					var $username =  $('#username input');
					var email = $email.val();
					var username = $username.val();
					if(!fav4.utils.checkEmail(email) || username == '') {
						$email.trigger('blur');	
						$username.blur();
						return false;
					}
					// make ajax request to create account
					var userData = {
						username: $('#username input').val(),
						email:	$('#email input').val(),
						importSettings: $('#import input:checked').size(),
						updates: $('#updates input:checked').size(),
						isPublic: $('#public input:checked').size()
					};
					fav4.settings.createUser(userData, {
						success: function(response) {
							var $dimmer = $('#setup .dimmer');
							var $modal = $('#setup .modal');
							var $wrapper = $('#wrapper');
							var height;
							if(response.success) {
								var username = response.data.username;
								
								$modal.find('.success').show();
								$modal.find('.failure').hide();
								if(response.sync) {
									$modal.find('.fresh').hide();
									$modal.find('.sync').show();
									height = 253;		
								}
								else {
									$modal.find('.sync').hide();
									$modal.find('.fresh').show();
									height = 228;								
								}
								var baseUserURL = $modal.find('.user-link').html();
								$modal
								.find('.username')
									.html(username)
									.end()
								.find('user-link')
									.html(baseUserURL + username + '/')
								;
							}
							else {
								if(response.exists) {
									$('#username input').trigger('blur');	
									return;
								}
								$modal.find('.failure').show();
								$modal.find('.success').hide();
								height = 125;			
							}
							$dimmer.show();
							$wrapper.addClass('animating');
							$modal
								.css({
									opacity: 0,
									width: '319px',
									height: Math.round(height * 0.75)+'px',	
									marginTop: Math.round(-(height * 0.75) / 2)+'px',
									marginLeft: '-160px'								
								})
								.show()
								.animate({
									opacity: 1,
									width: '425px',
									height: height+'px',	
									marginTop: Math.round(-height / 1.6)+'px',
									marginLeft: '-213px'	
								}, 300, function(){
									$wrapper.removeClass('animating');
								})
							;
						},
						failure: function() {
							var $dimmer = $('#setup .dimmer');
							var $modal = $('#setup .modal');
							var $wrapper = $('#wrapper');
							var height = 125;		
							$dimmer.show();
							$wrapper.addClass('animating');
							$modal.find('.failure').show();
							$modal.find('.success').hide();	
							$modal
								.css({
									opacity: 0,
									width: '319px',
									height: Math.round(height * 0.75)+'px',	
									marginTop: Math.round(-(height * 0.75) / 2)+'px',
									marginLeft: '-160px'								
								})
								.show()
								.animate({
									opacity: 1,
									width: '425px',
									height: height+'px',	
									marginTop: Math.round(-height / 1.6)+'px',
									marginLeft: '-213px'	
								}, 300, function(){
									$wrapper.removeClass('animating');
								})
							;
						}					
					});
				})
			;
			// enter changes radio button
			$(document)
				.bind('keydown', function(event) {
					if(event.keyCode == '13') {
						$checkbox = $('.field.active, .field.hover').find('input[type=checkbox]');
						if($checkbox.exists()) {
							$.uniform.update(); 
						}
						else {
							$('.submit')
								.addClass('down')
							;
						}
					}
				})
				.bind('keyup', function(event) {
					if(event.keyCode == '13') {
						$checkbox = $('.field.active, .field.hover').find('input[type=checkbox]');
						if($checkbox.exists()) {
							if($checkbox.attr('checked')) {
								$checkbox.removeAttr('checked');
							}
							else {
								$checkbox.attr('checked', 'checked');								
							}
							$.uniform.update();
						}
						else {
							$('.submit')
								.removeClass('down')
								.click()
							;	
						}
					}
				})
			;
		}
	
		
		/***********  Tabs **********/
		if($('#settings .tabs').exists()) {
			
			// handle history event
			$.address.change(function(event) {
				$('#content .tab-loading').hide();
				if(typeof(event.pathNames[0]) != 'undefined') {
					var section = event.pathNames[0];
					$('#'+section)
						.addClass('open')
						.siblings()
							.removeClass('open')
					;
					$('.tabs .'+section)
						.addClass('active')
						.siblings()
							.removeClass('active')
					;
				}
				else {
					$('.tab')
						.eq(0)
						.addClass('open')
						.siblings()
							.removeClass('open')
					;
					$('.tabs li')
						.eq(0)
						.addClass('active')
						.siblings()
							.removeClass('active')
					;						
				}
			});
		
			// attach events
			$('#settings .tabs').each(function() {
				var $tabs = $(this).find('li');
				var $tabContent = $(this).siblings('.tab');
				$tabs
					.hoverClass()
					.downClass()
					.bind('click', function() {
						var $tab = $(this);
						if(!$tab.hasClass('active')) {
							$tab.removeClass('hover');
							var section = $tab.attr('class');
							// fix tabs
							$tabs.removeClass('active');
							$tab.addClass('active');
							$tabContent
								.removeClass('open')
								.filter('#'+section)
									.addClass('open')
							;
							// record history
							$.address.value(section+'/'); 				
						}
					})
				;
			});
		}
		
		if( $('#content #manage').exists() ) {
			
			var $save = $('#manage .save')
			var $gmailCheckbox = $('#manage .gmail input:checkbox');
			
			$('select, input:checkbox, input')
				.bind('change keydown', function() {
					$save.removeClass('active');	
				})
				.uniform({resetSelector: 'button[type="reset"]'})
			;
			
			var checkGmail = function() {
				var isChecked = $gmailCheckbox.filter(':checked').size();
				var $fields = $('#manage .gmail .fields');
				if(isChecked) {
					$fields.addClass('visible');
				}
				else {
					$fields.removeClass('visible');						
				}	
			}
			checkGmail();
				$gmailCheckbox.bind('change', checkGmail)
			;
			
			$save
				.hoverClass()
				.downClass()
				.bind('click', function() {
					var $save = $(this);
					if(!$save.filter('.loading, .active').exists()) {
						// form data	
						var invalid = false;
						var email = $('#email input').val();
						var updates = $('#updates input').filter(':checked').size();
						var isPublic = $('#public input').filter(':checked').size();
						var username = $('#gmail-username input').val();
						var password = $('#gmail-password input').val();
						var useGmail = $gmailCheckbox.filter(':checked').size();
						
						var userData = {
							email: email,
							isPublic: isPublic,
							updates: updates	
						};
					
						// check email
						var $validation = $('#email .validate');
						var $validationMessage = $validation.find('.message');
						$validation.removeClass('success failure');
						if(!fav4.utils.checkEmail(email) ) {
							invalid = true;							
							$validation.addClass('failure');
							$validationMessage.html("Hey that doesn't look right");	
						}	
						else {
							$validation.removeClass('failure');
						}
						
						$save.addClass('loading');
						// delete gmail settings if unchecked
						if(!useGmail) {
							$.cookie('gAuthP', null, fav4.cookie.cookieOptions);
							$.cookie('gAuthPLK', null, fav4.cookie.cookieOptions);
						}
						
						// check gmail account
						if(!invalid && useGmail && username && password) {
							
							username.replace('@gmail.com', '');
							
							fav4.settings.encryptMail(username, password, function() {
								var ajaxSettings = {
									type: 'POST',			
									url: 'api/sync-mail/',
									dataType: 'json',
									error: function(data) {
										var $validation = $('#content .gmail .validate');
										var $validationMessage = $validation.find('.message');
										$validationMessage.html('<p class="red">Unable to query google for that account</p><p><b>Important Note:</b> if you enter information incorrectly several times you will get a notification in Gmail saying that your account is trying to be accessed from 74.207.232.245. <a href="settings/help/#advanced-unread-privacy>Please read this help article</a> on how this works and why your information is 100% safe.</p>');	
										$validation.addClass('failure');
										$('#gmail-password input').val('');
										fav4.settings.clearMailAccount();
										$save.removeClass('loading');										
									},
									success: function(data) {
										if(typeof(data.valid) != 'undefined' && data.valid) {
											var $validation = $('#content .gmail .validate');
											if(data.failed) {
												var invalid = true;
												// display warning
												var $validationMessage = $validation.find('.message');
												$validationMessage.html('<p class="red">Incorrect username or password</p><p><b>Important Note:</b> if you enter information incorrectly several times you will get a notification in Gmail saying that your account is trying to be accessed from 74.207.232.245. <a href="settings/help/#advanced-unread-privacy>Please read this help article</a> on how this works and why your information is 100% safe.</p>');	
												$validation.addClass('failure');
												fav4.settings.clearMailAccount();
												$('#gmail-password input').val('');
												$save.removeClass('loading');
											}
											else {
												$validation.removeClass('failure');
												fav4.settings.saveAccountSettings(userData, function() {
													$save.removeClass('loading').addClass('active');
												});
											}
										}
									}
								};
								$.ajax(ajaxSettings); 	
							});							
						}
						else {
							if(!invalid) {
								setTimeout(function() {
									fav4.settings.saveAccountSettings(userData, function() {
										$save.removeClass('loading').addClass('active');
									});
								}, 400);
							}
							else {
								$save.removeClass('loading');	
							}
						}
					}
					return false;
				})
			;
			
		}
		
		
	}
};

$(document).ready(fav4.onReady);


/*******************************
		  FAV4 Methods
*******************************/

$.extend(fav4, {
	
	isiPad: function() {
		return navigator.userAgent.match(/iPad/i) != null;
	},
	isiPhone: function() {
		return navigator.userAgent.match(/iPhone/i) != null;
	},
	protect: function() {
		// Protect other domains from running this script
		//eval("var name = document.domain;if(name != 'myfav.es' && name != 'beta.myfav.es' && name != 'www.myfav.es'){ window.location.href = 'http://myfav.es' }");
		eval(unescape('%76%61%72%20%6E%61%6D%65%20%3D%20%64%6F%63%75%6D%65%6E%74%2E%64%6F%6D%61%69%6E%3B%69%66%28%6E%61%6D%65%20%21%3D%20%27%6D%79%66%61%76%2E%65%73%27%20%26%26%20%6E%61%6D%65%20%21%3D%20%27%62%65%74%61%2E%6D%79%66%61%76%2E%65%73%27%20%26%26%20%6E%61%6D%65%20%21%3D%20%27%77%77%77%2E%6D%79%66%61%76%2E%65%73%27%29%7B%20%77%69%6E%64%6F%77%2E%6C%6F%63%61%74%69%6F%6E%2E%68%72%65%66%20%3D%20%27%68%74%74%70%3A%2F%2F%6D%79%66%61%76%2E%65%73%27%20%7D'));
	},
	initCookies: function() {
		var settings = ['layout', 'iconsPerPage'];
		$.each(settings, function(i, setting) {
			var cookieValue = $.storage(fav4.cookie[setting]);
			if(cookieValue) {
				fav4[setting] = cookieValue;
			}
		});
	},
	reflect: function() {
		if(fav4.iconType == 'floatReflect' || fav4.iconType == 'tableReflect') {
			var $icons = $('#content .icon');
			var $reflections = $('#content .reflection');
			var numIcons = fav4.numIcons();
			var numReflect = numIcons
			var numRemainder = numIcons % fav4.iconsPerRow;
			// reflect only last row for grid
			var numReflect = (fav4.layout == 'magiscroll')
				? (numRemainder == 0)
					? (fav4.iconsPerRow)
					: (fav4.iconsPerRow - (fav4.iconsPerRow - numRemainder))
				: numIcons
			;
			var startSpot = numIcons - numReflect;
			$reflections.remove();
			$icons
				.slice(startSpot, numIcons)
					.find('a.link, a.bg')
						.reflect()
			;
		}
	},
	growl: function() {
		var $growl = $('#growl');
		if(!$growl.visible()) {
			//$growl.slideDown(400, 'easeOutQuad');
		}
	},
	rows: {
		wizard: function() {
			var numIcons = $('#content > ul > li').size();
			var maxRows = fav4.rows.maxRows();
			var numRows;
			if(numIcons < 8) {
				numRows = 1;	
			}
			if(numIcons == 8 || numIcons == 10 || numIcons == 11 || numIcons == 14) {
				numRows = 2;	
			}
			if(numIcons == 9 || numIcons == 12 || numIcons == 13 || numIcons == 15) {
				numRows = 3;	
			}
			if(numIcons > 15) {
				numRows = 4;	
			}
			if(numRows > maxRows) {
				numRows = maxRows;
			}
			if(numRows == 0) {
				numRows = 1;	
			}
			// Lower to max rows available
			return numRows;
		},
		maxRows: function() {
			var height = $(window).height();
			var padding = 100;
			if($('body').hasClass('searchbottomcenter')) {
				padding = 180;	
			}
			return parseInt((height - padding) / 190, 10);	
		},
		fit: function() {
			$('#content')
				.removeClass('static')
				.removeAttr('style')
			;
			fav4.numRows = fav4.rows.wizard();
			fav4.rows.create();
			fav4.initSortable();
		},
		create: function(rows) {
			var numRows = fav4.numRows;
			if(fav4.layout == 'magiscroll') {
				var $icons = $('#content > ul > li').not('.ui-sortable-helper'),
					numIcons = $icons.size(),
					iconsLeft = numIcons % numRows,
					iconsPerRow = (numIcons / numRows)
				;
				// handle remainder
				if(iconsLeft > 0) {
					iconsPerRow = ((numIcons - iconsLeft) / numRows) + 1;
				}
				// record to namespace
				fav4.iconsPerRow = iconsPerRow;
				if(typeof(rows) == 'number') {
					fav4.track('grid', 'rows', '', numRows);	
				}
				else {
					fav4.track('grid', 'rows', 'auto', numRows);
				}
				fav4.track('grid', 'total-icons', '', numIcons);
				fav4.track('grid', 'icons-per-row', '', iconsPerRow);
				
				$icons.removeClass('row');
				for(var i=1; i<numRows; i++) {
					$icons.eq(i*iconsPerRow).addClass('row');
				}
				$('body').removeClass('row1 row2 row3 row4 row5').addClass('row'+fav4.numRows);
			}			
			/* For debugging
			$icons.each(function() {
				var row = ''
				if($(this).hasClass('row')) {
					row = '                                       row';	
				}
				console.log($(this).find('a.link').attr('id') + ' ' + row);	
			});
			*/
		}
		
	},
	initSortable: function() {
		if(fav4.section == 'home' && fav4.isSortable && fav4.layout != 'polygon' && !fav4.iPhone) {
			var $icons = $("#content ul");
			var distance = 8;
			if($.browser.msie) {
				distance = 2;	
			}
			var sortableSettings = {
				distance: distance,
				revert: 200,
				axis: 'x',
				tolerance: 'pointer',
				scroll: false,
				start: function(e, ui) {
					var $item = $(ui.item);
					var $customize = $item.find('.customize');
					clearTimeout(fav4.timer);
					if($customize.visible()) {
						$customize.fadeOut(200);	
						fav4.customSwap = true;
					}
					$item
						.find('a.link')
							.unbind('click.flip')
					;		
				},
				stop: function(e, ui) {
					var $item = $(ui.item);
					var $customize = $item.find('.customize');
					var customSwap = fav4.customSwap;
					if(typeof(customSwap) != 'undefined' && customSwap) {
						$customize.fadeIn(200);
						fav4.customSwap = false;	
					}
					$item
						.find('a.link')
							.bind('click.flip',fav4.flipLink)
					;	
					fav4.reflect();	
				},
				update: function() {
					fav4.settings.resortIcons();
				}
			};
			if(fav4.numRows > 1 && fav4.layout == 'magiscroll') {
				sortableSettings.revert = 300;
				sortableSettings.axis = false;	
				sortableSettings.change = function() {
					fav4.rows.create();
					fav4.reflect();	
				};
				sortableSettings.update = function() {
					fav4.rows.create();
					fav4.settings.resortIcons();
				};
			}
			if(fav4.layout == 'pages' ) {
				sortableSettings.axis = 'x';
				sortableSettings.start= function(e, ui) {
					var $item = $(ui.item);
					var $customize = $item.find('.customize');
					clearTimeout(fav4.timer);
					if($customize.visible()) {
						$customize.fadeOut(200);	
						fav4.customSwap = true;
					}
					$item
						.find('a.link')
							.bind('click.flip',fav4.flipLink)
					;
					$item
						.parents('.page')
							.addClass('hidden')
					;		
				};
				sortableSettings.stop = function(e, ui) {
					var $item = $(ui.item);
					var $customize = $item.find('.customize');
					var customSwap = fav4.customSwap;
					if(typeof(customSwap) != 'undefined' && customSwap) {
						$customize.fadeIn(200);
						fav4.customSwap = false;	
					}
					$item
						.find('a.link')
							.bind('click.flip',fav4.flipLink)
					;	
					$item
						.parents('.page')
							.removeClass('hidden')
					;
				};
			}
			// no sortable for iphone flick view.
			if((fav4.iPhone && fav4.layout == 'pages') || (fav4.iPad && fav4.layout == 'pages')) {
				return
			}
			
			$icons
				.sortable(sortableSettings)
				.addTouch()
			;
		}
	},
	
	
	polygon: {
		
		init: function() {
			var numIcons = fav4.numIcons();
			var css = '';
			var numDegrees = fav4.degrees = 360/ numIcons;
			var zRatio = ((numIcons / 25) * 400) + 290;
			var scaleRatio = 0.75 - ((numIcons / 25) * 0.1);
			var $icons = $('#content ul li');
			for(i=0;i<=numIcons;++i) {
				$icons.eq(i).data('degrees', (numDegrees*i));
				css += '	#content li:nth-child('+i+') { -webkit-transform: scale3d('+scaleRatio+', '+scaleRatio+', '+scaleRatio+') rotateY('+(numDegrees*i)+'deg) translateZ('+zRatio+'px); } \n';
			}
			css += '	#content ul { -webkit-transform: rotateY('+(-(numDegrees))+'deg) }';
			$("head").append('<style type="text/css"/>').find("style:last").append(css);	
			$('#content').append('<div id="arrows"><div class="arrow" id="arrow-left" style="display: block;"></div><div class="arrow" id="arrow-right"></div></div>');
			fav4.polygon.initKeyboard();
			fav4.polygon.selectIcon(0);
		},
		initKeyboard: function() {
			var swipeLeft = function() {
				var $icons = $('#content ul');
				var $icon = $('#content ul li');
				if(!$icons.animated()) {
					$icon.filter('.selected').removeClass('selected');
					var current = parseInt($icons.rotate(), 10) - fav4.degrees;
					var closestDegrees = Math.round(current / fav4.degrees) * fav4.degrees;
					// degrees for checking active icon
					var checkDegrees = fav4.polygon.checkDegrees(closestDegrees);
					var next = { spot: 0 };
					$icon.each(function() {
						var proximity = $(this).data('degrees') - checkDegrees;
						if(proximity <= 2 && proximity >= -2) {
							next.spot = $icon.index($(this));					
						}
					});
					$icons.animate({
						rotate: '-='+fav4.degrees+'deg'
					}, 350, 'easeInOutSine', function() {
						fav4.polygon.selectIcon(next.spot);		
					});
				}				
			};	
			var swipeRight = function() { 
				var $icons = $('#content ul');
				var $icon = $('#content ul li');
				if(!$icons.animated()) {
					$icon.filter('.selected').removeClass('selected');
					var current = parseInt($icons.rotate(), 10) + fav4.degrees;
					var closestDegrees = Math.round(current / fav4.degrees) * fav4.degrees;
					// degrees for checking active icon
					var checkDegrees = fav4.polygon.checkDegrees(closestDegrees);
					var next = { spot: 0 };

					$icon.each(function() {
						var proximity = $(this).data('degrees') - checkDegrees;
						if(proximity <= 2 && proximity >= -2) {
							next.spot = $icon.index($(this));					
						}
					});
					$icons.animate({
						rotate: '+='+fav4.degrees+'deg'
					}, 350, 'easeInOutSine', function() {
						fav4.polygon.selectIcon(next.spot);		
					});						
				}
			};
			var spinStart = function(e) {
				e.preventDefault();
				$('#home > h2').html(' ');
				var name = $(this).attr('id');
				var $icons = $('#content ul');
				var $icon = $('#content ul li');
				var key = e.keyCode;
				if(name == 'arrow-left' || name == 'arrow-right') {
					$(this).addClass('down');	
				}
				if(key == 37 && fav4.lastKey != 37 || name == 'arrow-left') {
					$icon.filter('.selected').removeClass('selected');
					$icons.stop().animate({
						rotate: '+=360deg'
					}, 3000, 'easeOutSine', function() {
						fav4.lastKey = '';	
					});		
				}
				// right arrow
				if(key == 39 && fav4.lastKey != 39 || name == 'arrow-right') {
					$icon.filter('.selected').removeClass('selected');
					$icons.stop().animate({
						rotate: '-=360deg'
					}, 4000, 'easeOutSine', function() {
						fav4.lastKey = '';	
					});				
				}
				if(key == 13) {
					$icon.filter('.selected').addClass('down');
				}
				fav4.lastKey = key;
			};		
			var spinStop = function(e) {
				var name = $(this).attr('id');
				var $icons = $('#content ul');
				var $icon = $icons.find('li');
				var key = e.keyCode;
				if(name == 'arrow-left' || name == 'arrow-right') {
					$(this).removeClass('down');	
				}
				if(key == 37 && fav4.lastKey == 37 || name == 'arrow-left') {
					var current = parseInt($('#content ul').rotate(), 10);
					var closestDegrees = Math.ceil(current / fav4.degrees) * fav4.degrees;
					// degrees for checking active icon
					var checkDegrees = fav4.polygon.checkDegrees(closestDegrees);
					$icon.each(function() {
						var proximity = $(this).data('degrees') - checkDegrees;
						if(proximity <= 1 && proximity >= -1) {
							var spot = $icon.index($(this));
							fav4.polygon.selectIcon(spot);							}
					});
					$icons.stop().animate({
						rotate: closestDegrees+'deg'
					}, 300, 'easeOutSine');
				}
				// right arrow
				if(key == 39 && fav4.lastKey == 39 || name == 'arrow-right') {
					var name = $(this).attr('id');
					var current = parseInt($('#content ul').rotate(), 10);
					var closestDegrees = Math.floor(current / fav4.degrees) * fav4.degrees;
					// degrees for checking active icon
					var checkDegrees = fav4.polygon.checkDegrees(closestDegrees);
					$icon.each(function() {
						var proximity = $(this).data('degrees') - checkDegrees;
						if(proximity <= 1 && proximity >= -1) {
							var spot = $icon.index($(this));
							fav4.polygon.selectIcon(spot);
						}
					});
					$icons.stop().animate({
						rotate: closestDegrees+'deg'
					}, 300, 'easeOutSine');
				}
				if(key == 13) {
					var spot = $icon.index($icon.filter('.selected'));
					$icon.filter('.selected').removeClass('down');
					fav4.openLink(spot);	
				}
				fav4.lastKey = '';
			};
			// ipad/iphone gestures
			$('#content').swipe({
				swipeLeft: swipeLeft,
				swipeRight: swipeRight
			});
			if(fav4.iPad || fav4.iPhone) {
				$('#arrow-left, #arrow-right')
					.bind('touchstart', spinStart)
					.bind('touchend', spinStop)
				;	
			}
			else {
				$('#arrow-left, #arrow-right')
					.bind('mousedown', spinStart)
					.bind('mouseup', spinStop)
				;					
			}
			$(document)
				.bind('keydown', spinStart)
				.bind('keyup', spinStop)
			;
						
		},
		checkDegrees: function(closestDegrees) {
			var checkDegrees = 360 - closestDegrees;
			if(closestDegrees >= 360 || closestDegrees <= 0) {
				checkDegrees = 360 - Math.abs(closestDegrees - (Math.floor(closestDegrees / 360)) * 360);	
			}
			if(checkDegrees == 360) {
				checkDegrees = 0;	
			}
			return checkDegrees;
		},
		selectIcon: function(spot) {
			var $icon = $('#content ul li');
			var $selectedIcon = $icon.eq(spot);
			var iconName = $selectedIcon.find('.link').html().replace('-',' ');
			if(iconName.match(/custom/i)) {
				iconName = 'custom';
				var src = $selectedIcon.find('.link').attr('href');
				if(src) {
					var regex = /[^.]+\.[^.]+$/;
					var result = src.match(regex);
					var iconName = result[0];
				}
			}	
			var $content = $('#content');
			$selectedIcon.addClass('selected');
			if($('#home > h2').size() > 0) {
				$('#home > h2').hide().html(iconName).fadeIn(300);
			}
			else {
				$('<h2 />')
					.insertAfter($content)
					.html(iconName)
				;
			}
		}
	},
	
	pages: {
		bundleIcons: function() {
			// store browser width and height
			fav4.browser = {
				width: $(window).width(),
				height: $(window).height()
			};			
			// used to search for pagebreak values
			var inArray = function(needle, haystack) {
				var key = '';
				for (key in haystack) {
					if (haystack[key] == needle) {
						return true;
					}
				}
				return false;
			};
			var $content = $('#content');
			// read pagebreak cookie
			var pageBreaks = $.storage(fav4.cookie.pageBreaks);
			// if cookie available use it
			if (pageBreaks){
				pageBreaks = pageBreaks.split('::');
				var numPages = pageBreaks.length;
			}
			// otherwise generate pagebreaks
			else {
				pageBreaks = [];
				// initialize number of icons from cookie
				var iconsPerPage = fav4.iconsPerPage;
				if(iconsPerPage == 'auto') {
					iconsPerPage = fav4.pages.maxIcons();
					fav4.track('pages', 'icons-per-page', 'auto', iconsPerPage);	
				}
				else {
					fav4.track('pages', 'icons-per-page', '', iconsPerPage);
					if(fav4.iPad || fav4.iPhone) {
						if(iconsPerPage > fav4.pages.maxIcons()) {
							var iconsPerPage = fav4.pages.maxIcons()	
						}
					}
				}
				var numIcons = fav4.numIcons();
				var numPages = Math.ceil(numIcons / iconsPerPage);
				fav4.track('pages', 'total-icons', '', numIcons);
				fav4.track('pages', 'total-pages', '', numPages);	
				for(var i=1; i<=numPages; i++) {
					// dont make new page on last icon
					if(iconsPerPage * i != numIcons) {
						// zero index icon 
						pageBreaks.push((iconsPerPage * i) -1);
					}
				}
			}
			// record numpages as property
			fav4.pages.numPages = numPages;
			
			// create document fragment
			var $fragment = $('<div />')
				.attr('id','pages');
			// add pages
			for(var i=0; i<numPages; i++) {
				$('<div />')
					.addClass('page')
					.html('<ul class="connected"></ul>')
					.appendTo($fragment)
				;
			}
			// add icons to each page
			var page = 0;
			var iconHTML = '';
			var numIcons = fav4.numIcons();
			fav4.eachIcon(function(icon, index) {
				iconHTML += fav4.icon.create(icon.shorthand, icon.url, index, true);
				fav4.track('pages', 'icon', icon.shorthand, 1);
				if(inArray(index, pageBreaks) || (index+1 == numIcons)) {
					var $page = $fragment.find('.page:eq('+page+') ul');
					$page.append(iconHTML);
					iconHTML = '';
					page++;
				}
			});
			// add width to ul
			$fragment
				.find('.page ul')
					.each(function() {
						var $list = $(this);
						$list.addClass('col'+ $list.children().size());
					})
			;
			// create arrow prototype
			var $arrow = $('<div />')
				.addClass('arrow')
				.bind('mouseenter', function() {
					var name = $(this).attr('id');
					// if you dragged an icon trigger special
					/*if($('.ui-sortable-helper').exists()) {
						$(this).addClass('special');	
						if(name == 'arrow-left') {
							//fav4.pages.setPage(fav4.pages.page-1);							
						}
						if(name == 'arrow-right') {
							//fav4.pages.setPage(fav4.pages.page+1);						
						}
					}	
					else {
						$(this).addClass('hover');	
					} */
					$(this).addClass('hover');
				})
				.bind('mouseleave', function() {
					$(this).removeClass('special hover');
				})
				.bind('mousedown', function() {
					$(this).addClass('down');
				})
				.bind('mouseup', function() {
					$(this).removeClass('down');
					var name = $(this).attr('id');
					if(name == 'arrow-left') {
						fav4.pages.setPage(fav4.pages.page-1);							
					}
					if(name == 'arrow-right') {
						fav4.pages.setPage(fav4.pages.page+1);						
					}
				})
			;
			// uses clone to avoid editing prototype
			var $arrows = $('<div />')
				.attr('id', 'arrows')
				.append($arrow.clone(true).attr('id', 'arrow-left'))
				.append($arrow.clone(true).attr('id', 'arrow-right'))
			;
			// add inline stylesheet for fitted content
			fav4.pages.fit();
			// refit on resize
			$(window).resize(function() {
				fav4.pages.fit();
				fav4.pages.setPage();
			});
			// add fragment
			var $pageAppend = $arrows.add($fragment);
			$content
				.html($pageAppend)
			;
			// add ipad style
			if(fav4.iPad || fav4.iPhone) {
				
				$('#arrows').hide();
				var pages = $('#pages')[0];
				pages.addEventListener('touchmove', function(e){ e.preventDefault(); });
				var myScroll = new iScroll(pages, { hScrollbar: false, vScrollbar: false, snap: true });
				// old ipad code
				/*
				$arrow
					.bind('touchstart', function() {
						$(this).addClass('down');						
						var name = $(this).attr('id');
						if(name == 'arrow-left') {
							fav4.pages.setPage(fav4.pages.page-1);							
						}
						if(name == 'arrow-right') {
							fav4.pages.setPage(fav4.pages.page+1);						
						}
					})
					.bind('touchend', function() {
						$(this).removeClass('down');
					})
					.unbind('mousedown')
					.unbind('mouseup')
				;
				if(fav4.iPad) {
					$content.swipe({
						swipeLeft: function() {
							fav4.pages.setPage(fav4.pages.page+1);							
						},
						swipeRight: function() {
							fav4.pages.setPage(fav4.pages.page-1);							
						}
					});
				}
				*/
				
				
				
			}
			// standard browsing experience
			else {
				// init keyboard
				fav4.pages.initKeyboard();
				// set page
				if(typeof(fav4.pages.page) == 'undefined') {
					fav4.pages.page = 1;
				}
				fav4.pages.setPage(fav4.pages.page);
			}

		},
		
		// fit design using inline styles
		fit: function() {
			fav4.browser = {
				width: $(window).width(),
				height: $(window).height()
			};
			$('style[title=resize]').remove();
			if(fav4.iPad || fav4.iPhone) {
				var pagesWidth = fav4.browser.width * fav4.pages.numPages;
				$('head').append('<style type="text/css" title="resize"> body#home #content #pages { width: '+pagesWidth+'px; height: '+fav4.browser.height+'px; }  body#home #content .page { width: '+(fav4.browser.width-30)+'px; padding-left: 30px; height: '+fav4.browser.height+'px; } </style>');
			}
			else {
				$('head').append('<style type="text/css" title="resize"> body#home #content #pages { height: '+fav4.browser.height+'px; }  body#home #content .page { width: '+(fav4.browser.width-30)+'px; padding-left: 30px; height: '+fav4.browser.height+'px; } </style>');
			}
		},
		maxIcons: function(width) {
			if(typeof(width) == 'undefined') {
				if(typeof(fav4.browser.width) == 'undefined') {
					width = $(window).width();
				}
				else {
					width = fav4.browser.width;
				}
			}
			var icons = Math.floor((width * 0.85) / fav4.iconWidth) ;
			if(icons == 0) {
				icons = 1;
			}
			return icons;
		},
		
		// animate page change, or refresh page if nothing passed into method
		setPage: function(page) {
			var $pageContainer = $('#pages');
			var $pages = $pageContainer.find('.page');
			var numPages = $pages.size();
			if(typeof(page) == 'undefined') {
				var page = fav4.pages.page;
			}
			// zero index of page
			zeroPage = page - 1;
			if( (page >= 1) && (page <= numPages) ) {
				
				fav4.track('pages', 'page-load', 'page-'+page, 1);
				
				var offsetX = -($pages.eq(zeroPage).position().left);
				if(page == fav4.pages.page) {
					$pageContainer.css('left', offsetX+'px');	
					$pages
						.removeClass('active')
						.eq(zeroPage)
							.addClass('active')
					;
					fav4.pages.setArrows(page, numPages);
				}
				else {
						var pageSpeed = 750;
						if(fav4.iPad || fav4.iPhone) {
							pageSpeed = 0;	
						}
						$pageContainer.stop().animate({ left: offsetX}, pageSpeed, 'easeOutQuint');
						$pages
							.removeClass('active')
							.eq(zeroPage)
								.addClass('active')
						;
						fav4.pages.page = page;
						fav4.pages.setArrows(page, numPages);
				}
			}
		},
		// function can take current page and number of pages to avoid recalculating
		setArrows: function(page, numPages) {
			var $pageContainer = $('#pages');
			var $pages = $('#pages .page');
			var $leftArrow = $('#arrow-left');
			var $rightArrow = $('#arrow-right');
			if(typeof(page) == 'undefined') {
				page = fav4.pages.page;
			}
			if(typeof(numPages) == 'undefined') {
				numPages = $pages.size();	
			}
			if(page == 1 && page == numPages) {
				$leftArrow.hide();	
				$rightArrow.hide();
			}
			else if(page == numPages) {
				$leftArrow.show();
				$rightArrow.hide();	
			}
			else if(page == 1) {
				$leftArrow.hide();
				$rightArrow.show();
			}
			else {
				$leftArrow.show();
				$rightArrow.show();	
			}
		},
		initKeyboard: function() {
			$(document)
				.bind('keydown', function(e) {
					if(!fav4.noKeyboardMode && fav4.enableKeyboard) {
						var $leftArrow = $('#arrow-left');
						var $rightArrow = $('#arrow-right');
						var key = e.keyCode;
						var page = fav4.pages.page;
						// left arrow
						if(key == 37) {
							$leftArrow.addClass('down');
							fav4.pages.setPage(page-1);
						}
						// right arrow
						if(key == 39) {
							$rightArrow.addClass('down');
							fav4.pages.setPage(page+1);						
						}
					}
				})
				.bind('keyup', function(e) {
					if(!fav4.noKeyboardMode && fav4.enableKeyboard) {
						var $leftArrow = $('#arrow-left');
						var $rightArrow = $('#arrow-right');
						var key = e.keyCode;
						// left arrow
						if(key == 37) {
							$leftArrow.removeClass('down');
						}
						// right arrow
						if(key == 39) {
							$rightArrow.removeClass('down');				
						}
					}
				})
			;
		}
	},
	
	scroll: {
		// calculats width of all icons
		calculateWidth: function(outerWidth) {
			// default to outer width (includes margins)
			var outerWidth,
				lastWidth,
				rowWidth,
				ulWidth,
				$lastLi = $('#content > ul > li:last-child')
			;
			if(typeof(outerWidth) == 'undefined') {
				outerWidth = true;
			}
			if($lastLi.exists()) {
				lastWidth = $lastLi[0].offsetLeft + $lastLi.outerWidth();
			}
			// check each row for candidates for width
			if(typeof(fav4.iconsPerRow) != 'undefined') {
				var $lastIcons = $('#content > ul > li:nth-child('+fav4.iconsPerRow+'n)');
				$lastIcons.each(function() {
					rowWidth = $(this)[0].offsetLeft + $(this).outerWidth();
					ulWidth = (rowWidth > lastWidth)
						? rowWidth
						: lastWidth
					;	
				});
			}
			if(outerWidth) {
				var ulPadding = fav4.scroller.padding * 2;
				return ulWidth + ulPadding;
			}
			return ulWidth;
		},
		positionMenu: function() {	
			var $menu = $('#content');
			var width = $(window).width();
			var ulWidth = fav4.scroll.calculateWidth();
			var iconWidth = fav4.iconWidth;
			// position menu in center if smaller than window width
			if(ulWidth < width) {
				$menu
					.removeClass('dynamic')
					.addClass('static')
					.css({ 
						width: ulWidth+'px',
						left: '50%',
						marginLeft: '-'+(ulWidth / 2)+'px'
					})
				;	
			}
			// remove styles if not
			else {
				$menu
					.removeClass('static')
					.addClass('dynamic')
					.removeAttr('style');
			}
			// position icons in center
			$menu.scrollLeft((ulWidth-width) / 2);
			// position search to not overlap grid
			fav4.scroll.positionSearch();
		},
		positionSearch: function() {
			if(typeof(fav4.numRows) != 'undefined' && fav4.numRows >= 1) {
				var $lastLi = $('#content > ul > li:last-child');
				var $ul = $('#content > ul');
				if($lastLi.exists() && $('body.searchbottomcenter').exists()) {
					var $search = $('#search');
					var topOffset = $lastLi.offset().top + $lastLi.height();
					$search.css({ top: (topOffset+35)+'px'});
				}
			}
		},
		getRatios: function() {
			var $menu = $('#content');
			//Get menu width
			var menuWidth = $menu.width();
			var ulWidth = fav4.scroll.calculateWidth();
			var menuOffset = $menu.offset().left;
			var ratio = ((ulWidth - menuWidth) / menuWidth);
			var menuRatio = menuOffset * ratio;	
			return { ratio: ratio, menuRatio: menuRatio };
		},
		bindEvents: function() {
			var $menu = $('#content');
			if(fav4.iPad) {
				var ulWidth = fav4.scroll.calculateWidth();
				var $menuList = $menu.find('ul').css('width',ulWidth);
				$menu.css('overflow','scroll');
			}
			else {
				var ratios = fav4.scroll.getRatios();
				var content = document.getElementById('content');
				// handles position of menu on mousemove dom event
				$(window)
					.bind('resize.scroll', function() {
						$('#content').css('overflow', 'hidden');
						var ratios = fav4.scroll.getRatios();
						fav4.scroll.positionMenu();
						$menu
							.unbind('mousemove.scroll')
							.bind('mousemove.scroll', function(e){
								var x = e.pageX;
								if(!fav4.noScrollMode && x!= 0) {
									content.scrollLeft = (x * ratios.ratio) - ratios.menuRatio;
								}
							})
						;
						$('#content').css('overflow', '');
					})
				;
				$menu.bind('mousemove.scroll', function(e){
					var x = e.pageX;
					if(!fav4.noScrollMode && x!= 0) {
						content.scrollLeft = (x * ratios.ratio) - ratios.menuRatio;
					}
				});
			}
		},
		unbindEvents: function() {
			var $menu = $('#content');
			$menu.unbind('mousemove.scroll');
			$(window).unbind('resize.scroll');
		}
	},
	
	// Add custom settings
	customize: function() {
		// jq
		var $search = $('#search input[type=text]');
		var $searchForm = $('#search form');
		var $newWindow = $('#newwindow-option');
		var $searchLocation = $('#searchlocation-option');
		var $searchEngineOption = $('#searchengine-option');
		var $sortable = $('#sortable-option');
		var $searchFocus = $('#focus-option');
		var $showSearch = $('#search-option');
		
		var $enableKeyboard = $('#enablekeyboard-option');
		var $rightClick = $('#rightclick-option');
		
		var $iconLinks = $('#content ul li .front a');
		var $icons = $("#content ul");
		
		var $numRows = $('#settings select.numRows');
		var $iconsPerPage = $('#settings select.iconsPerPage');
		
		var $themes = $('#backgrounds .left ul.rows li');
		var $layouts = $('#layout .left ul.rows li');
		
		// read cookies
		var newWindow = $.storage(fav4.cookie.newWindow);
		var searchLocation = $.storage(fav4.cookie.searchLocation);
		var searchFocus = $.storage(fav4.cookie.searchFocus);
		var searchEngine = $.storage(fav4.cookie.searchEngine);
		var theme = $.storage(fav4.cookie.theme);
		var sortable = $.storage(fav4.cookie.sortable);
		
		// new settings - may
		var numRows = $.storage(fav4.cookie.numRows);
		var iconsPerPage = $.storage(fav4.cookie.iconsPerPage);
		var layout = $.storage(fav4.cookie.layout);
		
		// new settings - june
		var rightClick = $.storage(fav4.cookie.rightClick);
		var enableKeyboard = $.storage(fav4.cookie.enableKeyboard);
		// new settings - july
		var shortcutType = $.storage(fav4.cookie.shortcutType);
		var iconType = $.storage(fav4.cookie.iconType);
		var sheen = $.storage(fav4.cookie.sheen);
		
		// track
		fav4.track('load', 'new-window', newWindow, 1);
		fav4.track('load', 'search-location', searchLocation, 1);
		fav4.track('load', 'search-focus', searchFocus, 1);
		fav4.track('load', 'search-engine', searchEngine, 1);
		fav4.track('load', 'theme', theme, 1);
		fav4.track('load', 'sortable', sortable, 1);
		fav4.track('load', 'num-rows', numRows, 1);
		fav4.track('load', 'icons-per-page', iconsPerPage, 1);
		fav4.track('load', 'layout', layout, 1);
		fav4.track('load', 'right-click', rightClick, 1);
		fav4.track('load', 'enable-keyboard-shortcuts', enableKeyboard, 1);
		
		fav4.enableKeyboard = true;
		if(enableKeyboard != null && enableKeyboard == 0) {
			fav4.enableKeyboard = false;	
		}
		
		// new july 2010
		if(!shortcutType) {
			shortcutType = fav4.shortcutType;	
		}
		if(shortcutType == 'numbers' || shortcutType == 'letters' || shortcutType == 'all' || shortcutType == 'none') {
			fav4.shortcutType = shortcutType;
			$enableKeyboard.find('option[value='+shortcutType+']').attr('selected', 'selected'); 
		}
		
		
		if(rightClick) {
			fav4.rightClick = rightClick;
			$rightClick.find('option[value='+rightClick+']').attr('selected', 'selected'); 	
		}
		
		
		// initialize settings & set option defaults
		if(layout == 'pages') {
			$layouts.eq(0).addClass('active').siblings().removeClass('active');
		}
		if(layout == 'magiscroll' && numRows == 1) {
			$layouts.eq(1).addClass('active').siblings().removeClass('active');
		}
		if(layout == 'magiscroll' && (numRows == 'auto' || numRows > 1) ) {
			$layouts.eq(2).addClass('active').siblings().removeClass('active');
		}
		
		// init numrows from cookie if available
		if(iconsPerPage) {
			$iconsPerPage.find('option[value='+iconsPerPage+']').attr('selected', 'selected');
		}
		if(numRows) {
			fav4.numRows = numRows;	
			$numRows.find('option[value='+numRows+']').attr('selected', 'selected');
		}
		// init columns
		if(fav4.numRows > 0 || fav4.numRows == 'auto') {
			if(fav4.numRows == 'auto') {
				fav4.numRows = fav4.rows.wizard();	
				fav4.rows.fit();
				$(window).bind('resize', function(){
					fav4.rows.fit();	
				});
			}
			else {
				fav4.rows.create();
			}
		}
		
		// new window
		if(newWindow && newWindow != 0) {
			fav4.useNewWindow = true;
			$iconLinks.attr('target', '_blank');
			$searchForm.attr('target', '_blank');
			$newWindow.attr('checked', 'checked');
		}
		else {
			$iconLinks.removeAttr('target');
			$searchForm.removeAttr('target');
			$newWindow.removeAttr('checked');
		}
		// search bar location
		if(searchLocation && searchLocation == 'none') {
			fav4.search.off();	
			$showSearch.find('option[value=none]').attr('selected', 'selected');
		}
		if(searchLocation && searchLocation == 'center') {
			fav4.search.center();
			$showSearch.find('option[value=center]').attr('selected', 'selected');
		}
		if(searchLocation && searchLocation == 'top') {
			fav4.search.top();	
			$showSearch.find('option[value=top]').attr('selected', 'selected');
		}
		// search focus
		if(searchLocation != 'none' && searchFocus && searchFocus != 0) {
			fav4.searchFocus = true;
		}
		// themes
		if(theme) {
			fav4.setTheme(theme);
			var $activeSelect = $themes.find('select.theme option[value='+theme+']');
			var $activeTheme = $activeSelect.parents('li');
			/* update color metadata */
			if(typeof(theme) == 'string' && theme.search('solid') != -1) {
				$activeTheme = $('#backgrounds .solid');
				var hexColor = theme.split('-')[1];
				$activeTheme.find('.color').css('background-color', '#'+hexColor);
			}
			/* update preview image */
			else { 
				var themeType = $activeTheme.removeClass('active hover down').attr('class');
				$activeTheme
					.find('.preview img')
						.attr('src', 'images/themes/thumb/'+themeType+'/'+theme+'.jpg')
				;
			}
			$activeSelect.attr('selected', 'selected')
			$activeTheme
				.addClass('active')
				.siblings()
					.removeClass('active')
			;
		}
		// themes
		if(iconType) {
			fav4.iconType = iconType;
			$('#iconType option[value='+iconType+']')
				.attr('selected', 'selected')
			;
			$('#preview-bottom').addClass(iconType); 	
		}
		if(sheen) {
			fav4.sheen = sheen;
			$('#sheen option[value='+sheen+']')
				.attr('selected', 'selected')
			;
			$('#preview-top').addClass(sheen);
		}
		// sortable
		if(sortable != 0) {
			$sortable.attr('checked','checked');
			fav4.isSortable = true;
		}
		else {
			$sortable.removeAttr('checked');
			fav4.isSortable = false;
		}
		// search engines
		if(typeof(fav4.searchEngines[searchEngine]) != 'undefined') {
			var engine = fav4.searchEngines[searchEngine];
			$searchForm
				.attr('action', engine.url)
				.attr('method', engine.method)
			;	
			$searchEngineOption.find('option[value='+searchEngine+']').attr('selected','selected');
			if(searchEngine == 'google') {
				$('<div/>')
					.attr('id', 'autocomplete')
					.insertAfter($search)
				;
				$('#autocomplete .complete')
					.live('click', function() {
						$('#autocomplete').hide();
						var searchTerm = $(this).find('b').html();
						$search.val(searchTerm);
						$('#search form').submit();		
					})
				;
				$search
					.attr('autocomplete', 'off')
					.bind('focus', function() {
						$(window)
							.bind('keydown.search', function(event) {
								var $autocomplete = $('#autocomplete');
								var key = event.keyCode;
								var up = 38;
								var down = 40;
								var enter = 13;
								if(key == up) {
									var $activeTerm = $autocomplete.find('.complete.active');
									var $terms = $autocomplete.find('.complete');
									if($terms.index($activeTerm) > 0) {
										event.preventDefault();
										$activeTerm
											.removeClass('active')
											.prev()
												.addClass('active');
										;
										var searchTerm = $autocomplete.find('.complete.active b').html();
										$search.val(searchTerm);
									}
									else {
										$activeTerm.removeClass('active');										
										$search.val(fav4.searchTerm);	
									}
								}
								if(key == down) {
									var $activeTerm = $autocomplete.find('.complete.active');
									if($activeTerm.exists()) {
										if($activeTerm.next().exists()) {
											$activeTerm
												.removeClass('active')
												.next()
													.addClass('active')
											;
											var searchTerm = $autocomplete.find('.complete.active b').html();
											$search.val(searchTerm);
										}
									}
									else {
										fav4.searchTerm = $search.val();
										$autocomplete
											.find('.complete').eq(0)
											.addClass('active')
										;	
										var searchTerm = $autocomplete.find('.complete.active b').html();
										$search.val(searchTerm);
									}
								}
								if(key == enter) {
									var searchTerm = $autocomplete.find('.complete.active b').html();
									// if nothing selected dont modify
									if(searchTerm) {
										$search.val(searchTerm);
									}
								}
							})
						;
					})
					.bind('focus', function() {
						clearTimeout(fav4.timer);
						$('#autocomplete').show();
					})
					.bind('blur', function() {
						fav4.timer = setTimeout(function() {
							$('#autocomplete').fadeOut();
						}, 750);
						$(window)
							.unbind('keydown.search')
						;
					})
					.bind('keyup', function(event) {
						var input = $(this).val();
						if(input.length > 1) {
							if(typeof(fav4.timer != 'undefined')) {
								clearTimeout(fav4.timer);
							}
							// calculate number of results (5px padding)
							var resultCount = parseInt(($(window).height() - ($search.offset().top + fav4.searchHeight + 15)) / fav4.autoCompleteHeight);
							$(window).resize(function() {
								var resultCount = parseInt(($(window).height() - ($search.offset().top + fav4.searchHeight + 15)) / fav4.autoCompleteHeight);
								var resultIndex = resultCount - 1;
								$('#autocomplete .complete')
									.show()
									.filter(':gt('+resultIndex+')')
									.hide()
								;
							});
							// start query request timeout
							fav4.timer = setTimeout(function() {
								if(fav4.utils.alphaKey(event)) {
									fav4.autoComplete($search, input, resultCount);	
								}
							}, 100);
						}
						else {
							$('#autocomplete').hide();
						}
					})
				;
					
			}
				
			// search focus
			if(fav4.searchFocus) {
				fav4.noKeyboardMode = true;
				$search.focus();			
				$searchFocus.attr('checked', 'checked');
			}
		}
		
		
		fav4.initSortable();
		fav4.settings.initSearchOptions();
		
	},
	
	autoComplete: function($input, value, resultNumber) {
		// default ajax options
		var ajaxSettings = {
			type: 'GET',			
			beforeSend: function(xhr) {
				xhr.setRequestHeader('Host', 'clients1.google.com');
				xhr.setRequestHeader('Referer', 'http://clients1.google.com');
				xhr.setRequestHeader('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.8 Safari/534.7');
			},
			url: 'http://clients1.google.com/complete/search',
			dataType: 'jsonp',
			data: {
				q: value
			},
			error: function(error) {
				// error handling goes here	
			},
			success: function(results) {
				var $autocomplete = $('#autocomplete');
				var completes = results[1];
				var html = '';
				var length = completes.length;
				var results = (length < resultNumber) ? length: resultNumber;
				for(var i=0; i<results; i++) {
					var complete = completes[i];
					html += ''	+
						'<div class="complete">\n'	+
						'	<b>'+complete[0]+'</b>'	+
						'	<em>'+complete[1]+'</em>'	+
						'</div>'
					;
				}
				if(length > 0) {
					$autocomplete.fadeIn(200).html(html);
				}
				else {
					$autocomplete.fadeOut(200);	
				}
			}
		};
		$.ajax(ajaxSettings); 
	},
	
	checkUpgrades: function() {
		/* no upgrade prompt yet
		var version = $.storage(fav4.cookie.version);
		if(fav4.showUpdate && (!version || version < fav4.currentVersion) ) {
			$('#newstuff').fadeIn(500);
		}
		*/
	},
	
	upgradeVersion: function() {
		var currentVersion = $.storage(fav4.cookie.version);
		if(!currentVersion || currentVersion < fav4.currentVersion) {
			$.storage(fav4.cookie.version, fav4.currentVersion , fav4.cookie.cookieOptions);
			$('#newstuff').hide();
		}
	},
	
	// utility for iterating over cookie object
	eachIcon: function(callback) {
		// get the cookie
		var cookie = $.storage(fav4.cookie.icons);
		if(typeof(cookie) == 'string') {
			var icons = cookie.split("::");
			// last array element is blank
			var numIcons = icons.length -1;		
			var icon, url, iconID;
			for(var i=0; i<numIcons; i++){
				icon = icons[i].split(",");
				var icon = {
					shorthand: icon[0],
					iconID: 'icon-'+ icon[0],
					url: icon[1]
				};
				var returns = callback(icon, i);
				if(returns === 'FALSE') {
					break;	
				}
			}
		}
	},
	
	numIcons: function() {
		var cookie = $.storage(fav4.cookie.icons);
		var length = 0;
		if(typeof(cookie) == 'string') {	
			var icons = cookie.split("::");
			length = icons.length - 1;
		}
		return length;
	},
	
	findColor: function(shorthand) {
		var cookie = $.storage(fav4.cookie.colors);
		if(typeof(cookie) == 'string') {
			var customIcons = cookie.split("::");
			// last array element is blank
			var numCustomIcons = customIcons.length;		
			var customIcon, color;
			for(var i=0; i<numCustomIcons; i++){
				customIcon = customIcons[i].split(",");
				color = customIcon[1];
				if(customIcon[0] == shorthand) {
					return color;	
				}
			}
		}
		fav4.changeColor(shorthand, fav4.defaultColor);
		return fav4.defaultColor;
	},
	
	changeColor: function(shorthand, color) {
		var cookie = $.storage(fav4.cookie.colors);
		if(typeof(cookie) == 'string') {
			var customIcons = cookie.split("::");
			// last array element is blank
			var numCustomIcons = customIcons.length-1;		
			var customIcon, color, found = false;
			// no cookie yet
			var cookieChunk = '';
			for(var i=0; i<numCustomIcons; i++){
				customIcon = customIcons[i].split(",");
				// record new value
				if(customIcon[0] == shorthand) {
					found = true;
					cookieChunk += shorthand+','+color+'::';	
				}
				// record old value
				else {
					cookieChunk += customIcons[i]+'::';	
				}
			}
			if(!found) {
				cookieChunk += shorthand+','+color+'::';
			}	
		}
		else {
			var cookieChunk = shorthand+','+color+'::';	
		}
		$.storage(fav4.cookie.colors, cookieChunk , fav4.cookie.cookieOptions);
	},
	findUrl: function(shorthand) {
		var cookie = $.storage(fav4.cookie.urls);
		if(typeof(cookie) == 'string') {
			var customIcons = cookie.split("::");
			// last array element is blank
			var numCustomIcons = customIcons.length;		
			var customIcon, url;
			for(var i=0; i<numCustomIcons; i++){
				customIcon = customIcons[i].split(",");
				url = customIcon[1];
				if(customIcon[0] == shorthand) {
					return url;	
				}
			}
		}
		return false;
	},
	
	nag: function() {
		var dismissNag = $.cookie(fav4.cookie.dismissNag);
		var iconCookie = $.storage(fav4.cookie.icons);
		var message = "<b>We've just added 50 new backgrounds to choose from.</b> Check them out by clicking the icon below to visit your myfav.es settings";
		var nagVersion = 2;
		if(typeof(iconCookie) == 'string' || !fav4.foreignProfile) {
			if(typeof(dismissNag) == 'undefined' || !dismissNag || dismissNag < nagVersion) { 
				
				var $nag = $('<div/>')
					.attr('id', 'nag')
						.html(message)
					.appendTo('body')
					.hoverClass()
					.click(function(){
						$.cookie(fav4.cookie.dismissNag, nagVersion, fav4.cookie.cookieOptions);
						// find base 
						var base = $('base').attr('href');
						window.location.href = base + 'settings/';
						return false;
					})
				;
				var $close = $('<div/>')
					.addClass('close')
					.html('<div class="hover"></div>')
					.click(function(event) {
						$.cookie(fav4.cookie.dismissNag, nagVersion, fav4.cookie.cookieOptions);
						$nag.hide();
						event.stopImmediatePropagation();	
						return false;
					})
					.smoothHover(200)
					.appendTo($nag);
				;
				$('#settings').click(function() {
					$nag.hide();
					$.cookie(fav4.cookie.dismissNag, nagVersion, fav4.cookie.cookieOptions);					
				});
				fav4.utils.precache(['images/nag.png'], function() {
					setTimeout(function(){
						$nag.fadeIn(500);
					}, 500);
				});
				
			}
		}
	},
	
	changeUrl: function(shorthand, url) {
		var cookie = $.storage(fav4.cookie.urls);
		if(typeof(cookie) == 'string') {
			var customIcons = cookie.split("::");
			// last array element is blank
			var numCustomIcons = customIcons.length-1;		
			var customIcon, url, found = false;
			// no cookie yet
			var cookieChunk = '';
			for(var i=0; i<numCustomIcons; i++){
				customIcon = customIcons[i].split(",");
				// record new value
				if(customIcon[0] == shorthand) {
					found = true;
					cookieChunk += shorthand+','+url+'::';	
				}
				// record old value
				else {
					cookieChunk += customIcons[i]+'::';	
				}
			}
			if(!found) {
				cookieChunk += shorthand+','+url+'::';
			}	
		}
		else {
			var cookieChunk = shorthand+','+url+'::';	
		}
		$.storage(fav4.cookie.urls, cookieChunk , fav4.cookie.cookieOptions);
	},
		
	footer: {
		hide: function() {
			$("#footer, #search").hide();
		}
	},
	
	flipLink: function() {
		var url = $(this).attr('href');
		if(typeof(url) == 'undefined' || url == '' || url == 'flip') {
			if(!$('#content .icon .back:visible, #content .icon .content:animated').exists()) {
				$(this).parents('.content').siblings('.customize').click();
			}
			return false;
		}
	},
	checkReader: function() {
		if(!fav4.foreignProfile) {
			var $readerIcon = $('#icon-google-reader, #content .link[href*="google.com/reader"]');
			var gAuthP = $.cookie('gAuthP');
			if($readerIcon.exists() && typeof gAuthP != undefined && gAuthP != null) {	
				var ajaxSettings = {
					type: 'POST',			
					url: 'include/api/google-reader.php',
					dataType: 'json',
					success: function(data) {
						if(typeof(data.valid) != 'undefined' && data.valid) {
							var $icon = $readerIcon.parents('.icon');
							var $unread = $icon.find('.unread');
							var unreadCount = data.unreadCount;
							if(unreadCount > 0) {
								// edit inbox count
								if($unread.exists()) {
									$unread.html(data.count)	
								}
								// add inbox count
								else {
									var $unread = $('<div />')
										.addClass('unread')
										.hide()
										.html(unreadCount)
										.appendTo($icon)
										.fadeIn(500, function() {
											$(this).removeAttr('style');	
										})
									;
								}
								// add special classes
								$unread.removeClass('hundred thousand');
								if(unreadCount >= 100 && unreadCount < 1000) {
									$unread.addClass('hundred');
								}
								// add special classes
								else if(unreadCount >= 1000 && unreadCount < 10000) {
									$unread.addClass('thousand');
								}
							}
						}
					}
				};
				$.ajax(ajaxSettings); 
			}
		}
	},
	checkMail: function() {
		if(!fav4.foreignProfile) {
			var $gmail = $('#icon-gmail, #icon-gmail-alt, #content .link[href*="gmail.com"]');
			var gAuthP = $.cookie('gAuthP');
			if($gmail.exists() && typeof gAuthP != undefined && gAuthP != null) {	
				var ajaxSettings = {
					type: 'POST',			
					url: 'api/sync-mail/',
					dataType: 'json',
					success: function(data) {
						if(typeof(data.valid) != 'undefined' && data.valid) {
							var $icon = $gmail.parents('.icon');
							var $unread = $icon.find('.unread');
							var count = data.count;
							if(count > 0) {
								// edit inbox count
								if($unread.exists()) {
									$unread.html(data.count)	
								}
								// add inbox count
								else {
									var $unread = $('<div />')
										.addClass('unread')
										.hide()
										.html(count);
									$icon
										.append($unread)
									;
									setTimeout(function() {
										$icon.find('.unread').fadeIn(500, function() {
												$(this).removeAttr('style');	
											})
										;
									}, 500);
								}
								// add special classes
								$unread.removeClass('hundred thousand');
								if(count >= 100 && count < 1000) {
									$unread.addClass('hundred');
								}
								// add special classes
								else if(count >= 1000 && count < 10000) {
									$unread.addClass('thousand');
								}
							}
						}
					}
				};
				$.ajax(ajaxSettings); 
			}
		}
	},	
	icon: {
		create: function(shorthand, url, index, returnHTML) {
			if(returnHTML == 'undefined') {
				returnHTML = false;	
			}
			var title = shorthand.replace('icon-', '').replace('-',' ');
			var backTitle = title;
			var customColor = '';
			var customSelect = '';			
			// custom url
			var customUrl = fav4.findUrl(shorthand);
			if(customUrl) {
				url = customUrl;	
			}		
			// flip icon on blank url or flip command
			var linkText = 'href="'+url+'"';
			var inputVal = url;
			if(typeof(url) == 'undefined' || url == 'undefined' || url == 'flip' || url == '') {
				inputVal = fav4.urlPrompt;
				linkText = '';
			}	
			// custom icon setup
			if(shorthand.search('custom-') != -1) {
				backTitle = '';
				var curColor = fav4.findColor(shorthand);
				fav4.track('load', 'custom-color', curColor, 1);
				customColor += '\n 				<a id="custombg-'+curColor+'" class="bg"></a>';
				customSelect += '\n					<p>Select icon color:</p>';
				customSelect += '\n					<select class="color">';
				jQuery.each(fav4.colors, function(i, color) {
					if(color != curColor) {
						customSelect += '\n						<option value="'+color+'">'+color+'</option>';
					}
					// active option
					else {
						customSelect += '\n						<option value="'+color+'" selected>'+color+'</option>';						
					}
				});
				customSelect += '\n					</select>';
			}
			var className = '';
			var html = '<li'+className+'>\n'	+
			'	<div class="icon">\n'	+
			'		<div class="content">\n'	+
			'			<div class="front">\n'	+ 
			'				<div class="hover"></div>\n'	+customColor +
			'				<a class="sheen" '+linkText+'></a>'	+
			'				<a id="'+shorthand+'" '+linkText+'class="link">'+shorthand+'</a>\n'	+
			'			</div>\n'	+
			'			<div class="back">\n'	+
			'				<div class="form">\n'	+
			'					<div class="close"></div>\n'	+
			'					<h2>'+backTitle+'</h2>\n'	+
			'					<p>change url</p>\n'	+
			'					<input class="url" type="text" value="'+inputVal+'" />\n'	+ customSelect +
			'					<div class="save">'+shorthand+'</div>\n'	+
			'				</div>\n'	+
			'			</div>\n'	+
			'		</div>\n'	+
			'		<div class="customize"><a href="#"></a></div>\n'	+
			'	</div>\n'	+
			'</li>';
			if(returnHTML) {
				return html;	
			}
			else {
				$('#content ul').append(html);
			}
		}	
	},
	
	setTheme: function(theme) { 
		// check for existing solid color classes
		var classList = $('body').attr('class').split(' ');
		var solidClass = '';
		$.each(classList, function(index, className) {
			if(className.search('solid') != -1) {
				solidClass += ' ' + className;	
			}
		});
		// read from class list of light and dark themes
		var classList = fav4.lightThemes.join(' ') + ' ' + fav4.darkThemes.join(' ') + solidClass;
		$('body')
			.removeAttr('style')
			.removeClass(classList);			
		if(fav4.utils.inArray(theme, fav4.darkThemes) ) {
			fav4.lights.off();	
		}
		else {
			fav4.lights.on();	
		}
		if(typeof(theme) == 'string' && theme.search('solid') != -1) {
			// grab hex color
			var hexColor = theme.split('-')[1];
			// add css
			//$('style[title=solid]').remove();
			//$('head').append('<style type="text/css" title="solid"> body#home.solid { background-image: none !important; background-color: #'+hexColor+' !important; } </style>');
			//$('style[title=solid]')[0].disabled = false;
			$('body').css({
				backgroundColor: '#'+hexColor,
				backgroundImage: 'none'
			});
			// stylesheet disabled hax
			// check lightness value of color chosen and adapt
			var lightness = fav4.utils.rgbLightness(hexColor);
			if(lightness > 128) {
				$('body').removeClass('lightsout').addClass('lightson');	
			}
			else {
				$('body').removeClass('lightson').addClass('lightsout');		
			}
			$('body').addClass('solid');
			
		}
		else {
			$('body').addClass(theme);
		}
	},
	lights: {
		on: function() {
			$('body').removeClass("lightsout");			
		},
		off: function() {
			$('body').addClass("lightsout");			
		}
	},
	search: {
		off: function() {
			$('body')
				.removeClass("searchtopright searchbottomcenter")
			;
		},
		center: function() {
			$('body')
				.removeClass("searchtopright")
				.addClass("searchbottomcenter")
			;
		},
		top: function() {
			$('body')
				.removeClass("searchbottomcenter")
				.addClass("searchtopright")
			;
		}
	},
	
	openLink: function(index) {
		clearTimeout(fav4.timer);	
		var $icon =  $('#content > ul > li, #content .active.page li').eq(index);
		var href = $icon.find('.link').attr('href');
		if(typeof(href) != 'undefined' && href != 'undefined' && href != '' && href != 'flip') {
			if(fav4.useNewWindow) {
				window.open(href);	
			}
			else {
				window.location = href;	
			}
		}
		else {
			if(!$('#content .icon .back:visible, #content .icon .content:animated').exists()) {
				$icon.find('.content').siblings('.customize').click();
			}
			return false;
		}
	},
	
	
	track: function (category, action, label, value) {
		if(label != '' && +(label) === 0) {
			label = 'off';
		}
		if(+(label) === 1) {
			label = 'on';	
		}
		try {
			// async google analytics (delay for onload)
			/*
			setTimeout(function(){ 
				//console.log(category + " : " + action + " : " + label + " : " + value);
				_gaq.push(['_trackEvent', category, action, label, value]);
			}, 60);
			*/
			//pageTracker._trackEvent(category, action, label, value);	
		}
		catch(e) {
			// log error
		}
	},
	
	
	loginPanel: function() {
		// check whether already inserted into page
		var $wrapper = $('#wrapper');
		var $loginPanel = $('#login-panel');
		var $dimmer = $('#login-dimmer');
		
		// if not already written to page generate html
		if(!$loginPanel.exists()) {
			var html = 	''	+
				'<div id="login-close"></div>' + "\n" 	+
				'<div class="providers">' + "\n" 	+
				'	<h3>Sign in using your account with:</h3>' + "\n" 	+
				'	<ul>' + "\n" 	+
				'		<li class="facebook"><div class="hover"></div><div class="down"></div><a href="login/facebook/"></a></li>' + "\n" +
				'		<li class="twitter"><div class="hover"></div><div class="down"></div><a href="login/twitter/""></a></li>' + "\n" +
				'		<li class="google"><div class="hover"></div><div class="down"></div><a href="login/google/""></a></li>' + "\n" +
				'		<li class="openid"><div class="hover"></div><div class="down"></div><a href="login/openid/"></a></li>' + "\n" +
				'	</ul>' + "\n" +
				'	<div class="divider"></div>' + "\n" +
				'	<a class="help" href="settings/help/#sleep">I dont use any of these services</a>' + "\n" +
				'</div>' + "\n" +
				'<div class="loading">' + "\n" +
				'	<div class="message"></div>' + "\n" +
				'</div>' + "\n" +
				'<div class="open-login">' + "\n" +
				'	<div class="logo"></div>' + "\n" +
				'	<p class="create"><a href="https://www.myopenid.com/signup" target="_blank">Create a new openID account</a></p>' + "\n" +
				'	<label for="open-id">Enter your OpenID URL:</label>' + "\n" +
				'	<form method="post" action="login/openid/">'+ "\n" +
				'		<input type="text" name="open-id" class="text">' + "\n" +
				'	</form>' + "\n" +
				'	<div class="sign-in">' + "\n" +
				'		<div class="hover"></div>' + "\n" +
				'		<div class="down"></div>' + "\n" +
				'	</div>' + "\n" +
				'	<div class="divider"></div>' + "\n" +
				'	<a class="return" href="#">Use Facebook, Google, or Twitter instead</a>' + "\n" +
				'</div>'
			;
			var $dimmer = $('<div />')
				.attr('id', 'login-dimmer')
				.bind('click', fav4.hideLoginPanel)
				.appendTo('body')
			;
			var $loginPanel  = $('<div />')
				.attr('id', 'login-panel')
				.html(html)
				.appendTo('body')
			;
			$loginPanel
				.find('#login-close')
					.hoverClass()
					.bind('click', fav4.hideLoginPanel)
					.end()
				.find('ul li')
					.smoothHover(200, {
						ieFix: true	
					})
					.smoothDown(200, {
						instantOn: true,
						click: function() {
							var $this = $(this);
							var providerName = $this.attr('class');
							if(providerName == 'openid') {
								$loginPanel.addClass('openid');
							}
							else {
								// loading
								$loginPanel.addClass('loading');
								$loginPanel.find('.loading .message').html('Authenticating with '+fav4.utils.ucwords(providerName)+'...');
								var href = $this.find('a').attr('href');
								if(href) {
									// find base 
									var base = $('base').attr('href');
									window.location = base + href;	
								}	
							}
						}
					})
					.end()
				.find('.open-login .return')
					.click(function() {
						$loginPanel.removeClass('openid');
						return false;
					})
					.end()
				.find('.open-login .sign-in')
					.smoothHover(200, {
						ieFix: true	
					})
					.smoothDown(200, {
						instantOn: true,
						click: function() {
							var openID = $loginPanel.find('.open-login input').val();
							if(openID) {
								$loginPanel.find('.open-login form').submit();
							}
						}
					})
			;
		}
		fav4.utils.precache(['images/login-sprite.png'], function() {
			$wrapper.addClass('animating');
			$dimmer.show();
			setTimeout(function() {
				if($.browser.msie) {
					$loginPanel.show();
					$wrapper.removeClass('animating');
				}
				else {
					$loginPanel.fadeIn(750, function() {
						$wrapper.removeClass('animating');	
					});
				}
			}, 100);
		});
		
		return false;
		
	},
	
	hideLoginPanel: function() {
		var $loginPanel = $('#login-panel');
		var $dimmer = $('#login-dimmer');
		
		$loginPanel.hide();
		$dimmer.fadeOut(300);
		
	},
	
	settings: {
		
		createUser: function(userData, params) {	
			var settings = {
				success: function(){},
				failure: function(){}	
			};
			$.extend(settings, params);
			var ajaxSettings = {
				type: 'POST',			
				url: 'api/create-account/',
				dataType: 'json',
				data: userData,
				error: function(error) {
					settings.failure(error);
				},
				success: function(data) {
					settings.success(data);
				}
			};
			$.ajax(ajaxSettings); 
		},
		
		checkUsername: function(username, params) {	
			var settings = {
				success: function(){},
				failure: function(){}	
			};
			$.extend(settings, params);
			var ajaxSettings = {
				type: 'GET',			
				url: 'api/username-taken/'+username+'/',
				dataType: 'json',
				error: function(error) {
					settings.failure(error);
				},
				success: function(data) {
					settings.success(data);
				}
			};
			$.ajax(ajaxSettings); 			
		},
		
		syncSettings: function(params) {
			var settings = {
				success: function(){},
				failure: function(){}	
			};
			$.extend(settings, params);
			var ajaxSettings = {
				type: 'GET',			
				url: 'api/sync-settings/',
				dataType: 'json',
				error: function(error) {
					settings.failure(error);
				},
				success: function(data) {
					settings.success(data);
				}
			};
			$.ajax(ajaxSettings); 	
		},
		
		navContinuity: function() {
			setTimeout(function() {
				$('nav li.active .active').fadeIn(300);
			}, 500);	
		},
		
		iconSearch: function(term, $filterGroup, $tab) {
			if(term != '') {
				// default ajax options
				var ajaxSettings = {
					type: 'GET',
					url: 'api/search/'+term+'/json/',
					dataType: 'json',
					complete: function() {
						$tab.find('.search .field').removeClass('loading');
					},
					error: function(error) {
						// error handling goes here	
					},
					success: function(response) {
						if(response.status == 'success') {
							var selector = '';
							var length = response.results.length;
							jQuery.each(response.results, function(index, result) {
								selector += '.'+result.identifier;
								if((index+1) != length) {
									selector += ', ';
								}
							});
							$tab
								.addClass('search')
								.find('h3.search')
									.html('Search Results:')
							;
							$filterGroup
								.removeClass('result')
								.filter(selector)
									.addClass('result');
							;
						}
						else {
							$tab
								.addClass('search')
								.find('h3.search')
									.html('Sorry no results were found.')
							;
							$filterGroup
								.removeClass('result')
							;
						}
					}
				};
				$.ajax(ajaxSettings); 
			}
			else {
				$tab.removeClass('search');
				$tab.find('.search .field').removeClass('loading');
				$filterGroup.removeClass('result');	
			}
		},
		
		logout: function() {
			// clear user cookies
			$.storage(fav4.cookie.username, null, fav4.cookie.cookieOptions);
			$.storage(fav4.cookie.oid, null, fav4.cookie.cookieOptions);
			$.storage('setupID', null, fav4.cookie.cookieOptions);
			$.storage('setupOID', null, fav4.cookie.cookieOptions);
			// clear icons, colors and urls
			$.storage(fav4.cookie.icons, null, fav4.cookie.cookieOptions);
			$.storage(fav4.cookie.urls, null, fav4.cookie.cookieOptions);
			$.storage(fav4.cookie.colors, null, fav4.cookie.cookieOptions);
			$('#login')
				.removeClass('logged-in')
				.addClass('logged-out')
			;
			setTimeout(function() {
				var url = window.location.href;
				window.location = url;
			}, 100);
		},
		
		initSearchOptions: function(){
			var selection = $('#search-option').val();
			if(selection == 'none') {
				$('#searchonly')
					.addClass('disabled')
				;
			}
			else {
				$('#searchonly')
					.removeClass('disabled')
				;			
			}
		},
		
		saveCustomColor: function($icon) {
			var newColor = $icon.find('select.color').val();
			var shorthand = $icon.find('a.link').attr('id');
			// change cookie
			fav4.changeColor(shorthand, newColor);
			fav4.track('save', 'custom-color', newColor, 1);
			// change live 
			$icon.find('.bg').attr('id','custombg-'+newColor);
		},
		// Updates cookie to include new url
		saveCustomUrl: function($icon) {
			var shorthand = $icon.find('.save').html();
			var $url = $icon.find('input.url');
			var url = $url.val();
			// if prompt text, clear text
			if(url == 'http://') {
				$url.val('');
				url = '';	
			}
			var $link = $icon.find('a.link');
			// replace link on front side
			if(typeof(url) == 'undefined' || url == '') {
				$link.removeAttr('href');
			}
			else {
				$link.attr('href', url);
			}
			fav4.changeUrl(shorthand, url);
		},
		addIcon: function(identifier, url, unique) {
			if(identifier == null || typeof(identifier) == 'undefined') {
				return false;	
			}
			if(typeof(unique) == 'undefined') {
				var unique = true;	
			}
			// check if already set
			if(unique) {
				var isUnique = true;
				fav4.eachIcon(function(icon, index) {
					if(icon.shorthand == identifier || icon.iconID == identifier) {
						isUnique = false;	
					}
				});
				if(!isUnique) {
					return false;	
				}
			}
			var currentIcons = $.cookie(fav4.cookie.icons);
			currentIcons = (currentIcons == null) 
				? ''
				: currentIcons
			;
			var icons = currentIcons + identifier+','+url+'::';
			$.storage(fav4.cookie.icons, icons, fav4.cookie.cookieOptions);		
			
		},
		removeIcon: function(identifier, url) {
			if(identifier == null || typeof(identifier) == 'undefined') {
				return false;	
			}
			var iconCookie = '';
			fav4.eachIcon(function(icon, index) {
				if(icon.shorthand != identifier && icon.iconID != identifier) {
					iconCookie += icon.shorthand+','+icon.url+'::';
				}
			});
			$.storage(fav4.cookie.icons, iconCookie, fav4.cookie.cookieOptions);	
		},		
		// add to faves count and sortable list
		addFavesUI: function(name, identifier, url, color) {
			if(identifier == null || typeof(identifier) == 'undefined') {
				return false;	
			}
			if(typeof(color) != 'undefined') {
				var colorHTML = '';
				colorHTML += '\n					<select class="color">';
				jQuery.each(fav4.colors, function(i, colorChoice) {
					if(color != colorChoice) {
						colorHTML += '\n <option value="'+colorChoice+'">'+colorChoice+'</option>';
					}
					// active option
					else {
						colorHTML += '\n <option value="'+colorChoice+'" selected>'+colorChoice+'</option>';						
					}
				});
				colorHTML += '\n	</select>';	
			}
			else {
				var colorHTML = '<div class="empty-field"></div>';	
			}
			var $favesCount = $('#sites .faves-count b');
			var $favesList = $('#myfaves .list > ul');
			var oldCount = +($favesCount.html());
			if(oldCount == 0) {
				$('#myfaves .empty').addClass('not');
				$('#myfaves .list').removeClass('hide');	
			}
			$favesCount.html(oldCount+1);
			// do html insert for speed
			var newHTML = $favesList.html() +
				'<li class="'+identifier+'">'	+
				'	<div class="meta">'	+
				'		<div class="url">'+url+'</div>'	+
				'		<div class="identifier">'+identifier+'</div>'	+
				'	</div>'	+
				'	<div class="icon"></div>'	+
				'	<p class="name">'+name+'</p>'	+
				'	<div class="handle"></div>'	+ colorHTML +
				'	<input type="text" class="custom-url" value="'+url+'"'	+
				'</li>'
			;
			// do html insert for speed
			$favesList.html(newHTML);	
			$favesList.sortable('refresh');	
			if(typeof(color) != 'undefined') {
				$favesList.find('li:last-child select').uniform();
			}	
		},
		// remove from faves count and sortable
		removeFavesUI: function(identifier, url) {
			if(identifier == null || typeof(identifier) == 'undefined') {
				return false;	
			}
			var $favesCount = $('#sites .faves-count b');
			var $favesList = $('#myfaves .list > ul');
			var oldCount = +($favesCount.html());
			$favesCount.html(oldCount-1);
			if(oldCount == 1) {
				$('#myfaves .empty').removeClass('not');
				$('#myfaves .list').addClass('hide');	
			}
			// dom remove
			$('#myfaves .list > ul').find('.'+identifier).remove();		
			$favesList.sortable('refresh');		
		},
		updateFavesUI: function(identifier) {
			var $favesCount = $('#sites .faves-count b');
			var $faves = $('#myfaves .list li');
			var numIcons = $faves
				.not('.placeholder, .hide')
				.size()
			;
			$favesCount.html(numIcons);
			if(numIcons == 0) {
				$('#myfaves .empty').removeClass('not');
				$('#myfaves .list').addClass('hide');			
			}
			else {
				$('#myfaves .empty').addClass('not');
				$('#myfaves .list').removeClass('hide');					
			}
		},
		// update of myfaves tab in settings
		resortSettingsIcons: function() {
			var iconCookie = '';
			$('#myfaves .list li').each(function() {
				var $icon = $(this);
				if(!$icon.hasClass('hide')) {
					var url = $icon.find('.meta .url').text();
					var identifier = $icon.find('.meta .identifier').text();
					// shorthand,url::shorthand,url::shorthand,url::shorthand,url
					if(identifier != '' && identifier != null) {
						iconCookie += identifier+','+url+'::';
					}	
				}
			});
			$.storage(fav4.cookie.icons, iconCookie , fav4.cookie.cookieOptions);	
		},
		poof: function(event) {
			var $poof = $('#myfaves .poof'),
				frames = 5, 
				frameSize = 32, 
				frameRate = 40
			; 
			$poof.show();
			for(var index = 1; index < frames; index++) { 
				$poof
					.delay(frameRate)
					.animate({ 
						backgroundPosition: '0px ' +  -(index*frameSize) + 'px' 
					}, 0);
			} 
			setTimeout(function() {
				$poof.hide();
			}, frames * frameRate); 
		},
		// Create cookie from resort
		resortIcons: function(event, ui) {
			// resort code
			var iconCookie = '';
			var $link, identifier, url;
			$('#content ul > li').each(function() {
				$link = $(this).find('.link');
				url = $link.attr('href');	
				identifier = $link.attr('id');
				// shorthand,url::shorthand,url::shorthand,url::shorthand,url
				if(identifier != '' && identifier != null) {
					iconCookie += identifier+','+url+'::';
				}
			});
			$.storage(fav4.cookie.icons, iconCookie , fav4.cookie.cookieOptions);
		},
		clearMailAccount: function() {			
			$.cookie('gAuthP', null, fav4.cookie.cookieOptions);
			$.cookie('gAuthPLK', null, fav4.cookie.cookieOptions);
			$.cookie('gAuthO', null, fav4.cookie.cookieOptions);
			$.cookie('gAuthOLK', null, fav4.cookie.cookieOptions);
		},
		encryptMail: function(username, password, callback) {
			
			var authData = {
				gAuthO: escape(window.btoa(username)),
				gAuthP: escape(window.btoa(password))			
			};
			
			var ajaxSettings = {
				type: 'POST',			
				url: 'api/encrypt/',
				dataType: 'text',
				data: authData,
				error: function(error) {
				},
				success: function(data) {
					if(typeof(callback) == 'function') {
						callback();	
					}
				}
			};
			$.ajax(ajaxSettings); 
			
		},
		
		saveAccountSettings: function(settings, callback) {
			
			var ajaxSettings = {
				type: 'POST',			
				url: 'include/api/update-account.php',
				dataType: 'json',
				data: settings,
				complete: function(data) {
					if(typeof(callback) == 'function') {
						callback();	
					}
				}
			};
			$.ajax(ajaxSettings); 
		},
		
		savePreferences: function() {
			// grab settings
			var sortable = $('#sortable-option:checked').size();
			var newWindow = $('#newwindow-option:checked').size();
			var searchLocation = $('#search-option').val();
			var searchFocus = $('#focus-option:checked').size();
			var searchEngine = $('#searchengine-option').val();
			
			var rightClick = $('#rightclick-option').val();
			var enableKeyboard = $('#enablekeyboard-option').val();
			
			// july 2010
			if(enableKeyboard == 'all') {
				$.cookie(fav4.cookie.enableKeyboard, 1, fav4.cookie.cookieOptions);
				$.cookie(fav4.cookie.shortcutType, 'all', fav4.cookie.cookieOptions);				
			}
			else if(enableKeyboard == 'none') {
				$.cookie(fav4.cookie.enableKeyboard, 0, fav4.cookie.cookieOptions);
				$.cookie(fav4.cookie.shortcutType, 'none', fav4.cookie.cookieOptions);					
			}
			else if(enableKeyboard == 'numbers') {
				$.cookie(fav4.cookie.enableKeyboard, 1, fav4.cookie.cookieOptions);
				$.cookie(fav4.cookie.shortcutType, 'numbers', fav4.cookie.cookieOptions);					
			}
			else if(enableKeyboard == 'letters') {
				$.cookie(fav4.cookie.enableKeyboard, 1, fav4.cookie.cookieOptions);
				$.cookie(fav4.cookie.shortcutType, 'letters', fav4.cookie.cookieOptions);					
			}
			
			$.cookie(fav4.cookie.sortable, sortable, fav4.cookie.cookieOptions);
			$.cookie(fav4.cookie.newWindow, newWindow, fav4.cookie.cookieOptions);
			$.cookie(fav4.cookie.searchLocation, searchLocation, fav4.cookie.cookieOptions);
			$.cookie(fav4.cookie.searchFocus, searchFocus, fav4.cookie.cookieOptions);
			$.cookie(fav4.cookie.searchEngine, searchEngine, fav4.cookie.cookieOptions);
			
			$.storage(fav4.cookie.rightClick, rightClick, fav4.cookie.cookieOptions);
		}
	},
	
	// Utility methods
	utils: {
		alphaKey: function(e) {
			if(e.keyCode != 16 && e.keyCode != 13 && e.keyCode != 20 && e.keyCode != 20 && e.keyCode != 13 && e.keyCode != 38 && e.keyCode != 40 && e.keyCode != '') {
				return true;
			}
			else {
				return false;
			}
		},
		// precache images
		precache: function(images, callback) {
			jQuery.each(images, function(index, src) {
				var image = new Image();
				if(typeof(callback) == 'function') {
					// bind callback to load error and abort, so it always fires
					jQuery(image)
						.bind('load', callback)
						.bind('error', callback)
						.bind('abort', callback)
					;
				}
				image.src = src;
			});	
		},
		rgbLightness: function(hexColor) {
			var rHex = hexColor.substr(0,2);
			var gHex = hexColor.substr(2,2);
			var bHex = hexColor.substr(4,2);
			
			var r = parseInt(rHex, 16);
			var g = parseInt(gHex, 16);
			var b = parseInt(bHex, 16);
			var max = Math.max(r, g, b), min = Math.min(r, g, b);
			var h, s, l = (max + min) / 2;
		
			if(max == min){
				h = s = 0; // achromatic
			}
			else {
				var d = max - min;
				s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
				switch(max){
					case r: h = (g - b) / d + (g < b ? 6 : 0); break;
					case g: h = (b - r) / d + 2; break;
					case b: h = (r - g) / d + 4; break;
				}
				h /= 6;
			}
		
			return l;
		},
		// doesnt allow any special chars
		trueAlphaKey: function(e) {
			if((e.keyCode >= 48 && e.keyCode <= 90) || (e.keyCode >= 96 && e.keyCode <=111) || (e.keyCode >= 188 && e.keyCode <= 222) || e.keyCode == 8) {
				return true;
			}
			else {
				return false;
			}
		},
		// Validates email
		checkEmail: function(addy) {
			if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$/.test(addy)){
				return true;
			} 
			else {
				return false;
			}	
		},
		inArray: function(needle, haystack, argStrict) {
			var key = '', strict = !!argStrict;
			if (strict) {
				for (key in haystack) {
					if (haystack[key] === needle) {
						return true;
					}
				}
			} 
			else {
				for (key in haystack) {
					if (haystack[key] == needle) {
						return true;
					}
				}
			}
		
			return false;
		},
		// Returns uppercase words
		ucwords: function(str) {
			return (str + '').replace(/^(.)|\s(.)/g, function ($1) {
				return $1.toUpperCase();	
			});
		}
	}
});

/* icon Flip Addendum */
fav4.iconFlip = function($this) {
	// use simple flip for IE
	if($.browser.msie) {
		fav4.simpleFlip($this);
		return;
	}
	// cache jq objects
	var $iconLI = $this.parents('li');
	var $icon = $this.parents('.icon');
	var $otherIcon = $('.icon').not($icon).parents('li');
	var $sides = $this.find('.front, .back');
	var $visibleSide = $sides.filter(':visible');
	var $hiddenSide = $sides.not(':visible');
	
	var $this = $iconLI;
	
	// dont scale with more than 6 too much cpu
	var other = {
		animateIn: {
			scale: 0.8
		},
		animateOut: {
			scale: 1
		}
	};
	if($otherIcon.size() >= 6 && $.browser.mozilla) {
		other = {
			animateIn: {
				opacity: 0.3	
			},
			animateOut: {
				opacity: 1
			}
		};
	}
	
	// settings
	var flip = function(degrees) {
		var animationTime = fav4.flip.duration;
		var flipTime = animationTime / 2;	
		var width = $this.width();
		var height = $this.height();
		// golden ratio for 2d scaling items	
		var scaleRatio = 1 - (1 / (height / width * fav4.flip.ratio));
		if(!$this.animated()) {
			/*$sides
				.css('opacity',0.5);*/
			$this
				.addClass('animating');
			$icon
				.stop()
				.animate({ scale: scaleRatio}, {
					easing: fav4.flip.easing.scale,
					duration: flipTime, 
					queue: false
				}
			);
			setTimeout(function() {
				$this
					.rotate3Di(degrees, animationTime, {
						direction: 'clockwise', 
						easing: fav4.flip.easing.rotate,
						sideChange: function(dontFlip) {
							// no clue jq1.4.3 bug based on starting data of plugin
							if(!dontFlip) {
								$visibleSide.hide();
								$hiddenSide.show();
								$icon
									.animate({ 
										scale: 1
									},{
										easing: fav4.flip.easingfadeIn,
										duration: flipTime, 
										queue: false
									})
								;
								$icon.toggleClass('flip');
							}
						},
						complete: function() {
							$this
								.removeClass('animating')
								.css('transform','')
							;
							$hiddenSide
								.stop()
								.show()
								/*.animate({opacity: 1},{
									easing: fav4.flip.easing.fadeIn,
									duration: flipTime, 
									queue: false
								})*/
							;
							// FLIPPING OVER
							if($hiddenSide.hasClass('back')) {
								$this.addClass('flip');	
								$icon
									.animate({
										height: '310px',
										left: '-86px',
										top: '-75px',
										width: '290px'		  
									}, {
										easing: fav4.flip.easing.scale,
										duration: flipTime, 
										queue: false,
										complete: function() {
											$hiddenSide.find('.form').fadeIn(100);	
											$icon.addClass('shadow');
											var $url = $hiddenSide.find('input.url');
											if($url.exists() && $url.val() == '') {
												$url.val('http://').focus();
											}
										}
									})
								;
								$otherIcon
									.animate(other.animateIn, {
										easing: fav4.flip.easingfadeIn,
										duration: flipTime, 
										queue: false
									})
								;
							}
						}
					})
				;
			}, flipTime);
		}
	};
	if($visibleSide.hasClass('back')) {
		var flipTime = fav4.flip.duration/2;
		// reset skew on start to avoid antialiasing issues
		//$this.css('transform','skew(360deg, 180deg) scale(1, 1)');
		$icon.removeClass('shadow');
		$visibleSide.find('.form').fadeOut(100, function() {
			$icon
				.animate({
					top: '0px',
					left: '0px',
					width: '156px',
					height: '156px'
				}, flipTime, function(){
					$icon.attr('style','');
					$this
						.removeClass('flip')
						.addClass('animating')
						.css('transform','skew(360deg, 180deg) scale(1, 1)')
					;
					flip('-=180');
				})
			;												  
		});
		$otherIcon
			.animate(other.animateOut, {
				easing: fav4.flip.easingfadeIn,
				duration: flipTime, 
				queue: false
			})
		;	  
	}
	else {
		flip('+=180');	
	}
	
};


fav4.initOfflineCache = function() {
	// Convenience array of status values
	var cacheStatusValues = [];
	cacheStatusValues[0] = 'uncached';
	cacheStatusValues[1] = 'idle';
	cacheStatusValues[2] = 'checking';
	cacheStatusValues[3] = 'downloading';
	cacheStatusValues[4] = 'updateready';
	cacheStatusValues[5] = 'obsolete';
	
	// Listeners for all possible events
	var cache = window.applicationCache;
	
	if(typeof(cache) == 'object') {
		
		// Log every event to the console
		var logEvent = function(e) {
			var online, status, type, message;
			//online = (isOnline()) ? 'yes' : 'no';
			status = cacheStatusValues[cache.status];
			type = e.type;
			//message = 'online: ' + online;
			message= 'event: ' + type;
			message+= ', status: ' + status;
			if (type == 'error' && navigator.onLine) {
				message+= ' There was an unknown error, check your Cache Manifest.';
			}
			console.log(message+"\n");
		}
		
		cache.addEventListener('cached', logEvent, false);
		cache.addEventListener('checking', logEvent, false);
		cache.addEventListener('downloading', logEvent, false);
		cache.addEventListener('error', logEvent, false);
		cache.addEventListener('noupdate', logEvent, false);
		cache.addEventListener('obsolete', logEvent, false);
		cache.addEventListener('progress', logEvent, false);
		cache.addEventListener('updateready', logEvent, false);
		
		
		// Swap in newly download files when update is ready
		cache.addEventListener('updateready', function(e){
			// Don't perform "swap" if this is the first cache
			if (cacheStatusValues[cache.status] != 'idle') {
				cache.swapCache();
				window.location.reload();
				console.log('Swapped/updated the Cache Manifest.');
			}
		}, false);
	}
};

fav4.simpleFlip = function($this) {
	// cache
	var $icon = $this.parents('.icon');
	var $sides = $this.find('.front, .back');
	var $visibleSide = $sides.filter(':visible');
	var $hiddenSide = $sides.not(':visible');
	if($hiddenSide.hasClass('back')) { 
		$icon.addClass('bg');
		$visibleSide.hide();
		$icon
			.animate({
				height: '290px',
				left: '-86px',
				top: '-75px',
				width: '290px'		  
			}, {
				easing: fav4.flip.easing.scale,
				duration: 300, 
				queue: false,
				complete: function() {
					$hiddenSide.show();
					$hiddenSide.find('.form').fadeIn(100);	
					$icon.addClass('shadow');
					var $url = $hiddenSide.find('input.url');
					if($url.exists() && $url.val() == '') {
						$url.val('http://').focus();
					}	
				}
			})
		;
	}
	else {
		$icon.removeClass('shadow');
		$visibleSide.find('.form').fadeOut(100, function() {
			$visibleSide.hide();									 
			$icon
				.animate({
					top: '0px',
					left: '0px',
					width: '156px',
					height: '156px'
				}, 300, function(){
					$icon.removeClass('bg');
					$hiddenSide.show();
				})
			;												  
		});
	}
	// flip
	$icon.toggleClass('flip');
};



/*******************************
		jQuery Plugins 
*******************************/

jQuery.fn.extend({
	// test if el is animated
	animated: function() {
		if(this.filter(':animated').size() > 0) {
			return true;
		}
		else {
			return false;	
		}
	},
	// test if el is visible
	visible: function() {
		if(this.filter(':visible').size() > 0) {
			return true;
		}
		else {
			return false;	
		}
	},
	// test if el exists
	exists: function() {
		if(this.size() > 0) {
			return true;
		}
		else {
			return false;	
		}
	}
});


/*	******************************
		PLUGIN - 
		Hover / Focus Class - Add class for css hover and focus 
		Force Hover - check mouse position to trigger hover
		
		Author: Jack Lukic - KNI
		Last revision: November 2009
	******************************	*/
	
jQuery.fn.extend({
	hoverClass: function(className, params) {
		if(typeof(className) == 'undefined') {
			var className = 'hover';
		}
		if(typeof(className) == 'object') {
			params = className;
			className = 'hover';
		}
		var settings = {
			useLive: false,
			context: 'body',
			filter: ''
		}
		$.extend(settings, params);
		
		var userAgent = navigator.userAgent;
		var iPad = userAgent.match(/iPad/i) != null;
		var iPhone = userAgent.match(/iPhone/i) != null;
		
		if(!iPad && !iPhone) {
			if(settings.useLive) {	
				$(this, settings.context).live('mouseover',function(){
					if(settings.filter == '' || $(this).filter(settings.filter).size() == 0) { 
						$(this).addClass(className);
					}
				});
				$(this, settings.context).live('mouseout', function() {
					if(settings.filter == '' || $(this).filter(settings.filter).size() == 0) {
						$(this).removeClass(className);							  
					}
				});	
			}
			else {
				$(this).each(function() {
						$(this).hover(function(){
							if(settings.filter == '' || $(this).filter(settings.filter).size() == 0) {
								$(this).addClass(className);							  
							}				   
						},
						function() {
							if(settings.filter == '' || $(this).filter(settings.filter).size() == 0) {
								$(this).removeClass(className);							  
							}
						});
				});
			}
		}
		return this;
	},
	touchClass: function(className, params) {
		if(typeof(className) == 'undefined') {
			var className = 'hover';
		}
		if(typeof(className) == 'object') {
			params = className;
			className = 'hover';
		}
		var settings = {
			filter: ''
		}
		$.extend(settings, params);
		
		var userAgent = navigator.userAgent;
		var iPad = userAgent.match(/iPad/i) != null;
		var iPhone = userAgent.match(/iPhone/i) != null;
		
		if(iPad || !iPhone) {
			$(this).each(function() {
				$(this)
					.bind('touchstart', function(){
						if(settings.filter == '' || $(this).filter(settings.filter).size() == 0) {
							$(this).addClass(className);							  
						}				   
					})
					.bind('touchend', function() {
						if(settings.filter == '' || $(this).filter(settings.filter).size() == 0) {
							$(this).removeClass(className);							  
						}
					})
				;
			});
		}
		return this;
	},
	downClass: function(className, params) {
		if(typeof(className) == 'undefined') {
			var className = 'down';
		}
		if(typeof(className) == 'object') {
			params = className;
			className = 'down';
		}
		var settings = {
			useLive: false,
			context: 'body',
			filter: ''
		}
		$.extend(settings, params);
		
		var userAgent = navigator.userAgent,
			iPad = userAgent.match(/iPad/i) != null,
			iPhone = userAgent.match(/iPhone/i) != null,
			downEvent = 'mousedown',
			upEvent = 'mouseup'
		;			
		if(iPad || iPhone) {
			downEvent = 'touchstart';
			upEvent = 'touchend';	
		}
		
		if(settings.useLive) {	
			$(this, settings.context).live(downEvent,function(){
				if(settings.filter == '' || $(this).filter(settings.filter).size() == 0) { 
					$(this).addClass(className);
					if(!(iPad || iPhone)) {
						$(this).one('mouseleave', function() {
							$(this).removeClass(className);	
						});
					}	
				}
			});
			$(this, settings.context).live(upEvent, function() {
				if(settings.filter == '' || $(this).filter(settings.filter).size() == 0) {
					$(this).removeClass(className);							  
				}
			});	
		}
		else {
			$(this).each(function() {
				$(this)
					.bind(downEvent, function(){
						if(settings.filter == '' || $(this).filter(settings.filter).size() == 0) {
							$(this).addClass(className);
							if(!(iPad || iPhone)) {
								$(this).one('mouseleave', function() {
									$(this).removeClass(className);	
								});
							}						  
						}				   
					})
					.bind(upEvent, function() {
						if(settings.filter == '' || $(this).filter(settings.filter).size() == 0) {
							$(this).removeClass(className);							  
						}
					})
				;
			});
		}
		return this;
	},
	focusClass: function(className, params) {
		if(typeof(className) == 'undefined') {
			var className = 'active';
		}
		if(typeof(className) == 'object') {
			params = className;
			className = 'active';
		}
		var settings = {
			filter: ''
		}
		$.extend(settings, params);
		
		$(this).each(function() {
			$(this)
				.focus(function(){
					if(settings.filter == '' || $(this).filter(settings.filter).size() == 0) {
						$(this).addClass(className);							  
					}				   
				})
				.blur(function() {
					if(settings.filter == '' || $(this).filter(settings.filter).size() == 0) {
						$(this).removeClass(className);							  
					}
				})
			;
		});
		return this;
	},
	forceHover: function() {
		$(this).each(function() {
			var $this = $(this);
			var offset = $this.offset();
			var width = $this.width();
			var height = $this.height();
			// look for first mousemove event
			$(document).bind('mousemove.poll', function(e) {
				var offsetX = e.pageX - offset.left;
				var offsetY = e.pageY - offset.top;
				if( (offsetX >= 0) && (offsetX <= width) && (offsetY <= height) && (offsetY >= 0) ) {
					$this.trigger('mouseover');
				}
				$(document).unbind('mousemove.poll');
			});
		});
		return this;
	}
});



/*	******************************
		PLUGIN - Smooth Hover, Down
		Author: Jack Lukic - KNI
		Last revision: July 2010
	******************************	*/

jQuery.fn.extend({
	smoothHover: function(duration, params) {
		var settings = {
			filterClass: '.active, .disabled',
			instantOn: false,
			ieFix: false
		};
		var settings = $.extend(settings, params);
		if(settings.ieFix && $.browser.msie) {
			duration = 0;	
		}
		$(this).each(function() {
			var $this = $(this),
				$hover = $this.find('.hover')
			;
			$this
				.bind('mouseenter', function() {
					if(!$this.filter(settings.filterClass).exists()) {
						if(settings.instantOn) {
							$hover.show();
						}
						else {
							$hover
								.protectAnimation()
								.fadeIn(duration)
							;
						}
					  }
				})
				.bind('mouseleave', function() {
					if(!$this.filter(settings.filterClass).exists()) {
						$hover
							.fadeOut(duration)
						;
					}
				})
			;
		});
		return this;
	},
	smoothDown: function(duration, params) {
		var settings = {
			click: function() {},
			filterClass: '.active, .disabled',
			instantOn: false,
			ieFix: false
		};
		var settings = $.extend(settings, params);
		if(settings.ieFix && $.browser.msie) {
			duration = 0;	
		}
		var userAgent = navigator.userAgent;
		var iPad = userAgent.match(/iPad/i) != null;
		var iPhone = userAgent.match(/iPhone/i) != null;
		
		$(this).each(function() {
			var $this = $(this),
				$hover = $this.find('.hover'),
				$down = $this.find('.down'),
				mousedownEvent = 'mousedown',
				mouseupEvent = 'mouseup'
			;
			if(iPad || iPhone) {
				var mousedownEvent = 'touchstart';
				var mouseupEvent = 'touchend';
			}
			$this
				.bind(mousedownEvent, function() {
					if(!$this.filter(settings.filterClass).exists()) {
						if(settings.instantOn) {
							$down.show();
						}
						else {
							$hover.hide();
							$down.fadeIn(duration);
						}
						if(!(iPad || iPhone)) {
							$this.bind('mouseleave.escape', function() {
								$down.fadeOut(duration);
								$this.unbind('mouseleave.escape');
							});
						}
					}
				})
				.bind(mouseupEvent, function() {
					if(!$this.filter(settings.filterClass).exists()) {
						$down.fadeOut(duration);
					}
				})
				.bind(mouseupEvent, settings.click)
			;
		});
		return this;
	},
	forceHover: function() {
		$(this).each(function() {
			var $this = $(this);
			var offset = $this.offset();
			var width = $this.width();
			var height = $this.height();
			// look for first mousemove event
			$(document).bind('mousemove.poll', function(e) {
				var offsetX = e.pageX - offset.left;
				var offsetY = e.pageY - offset.top;
				if( (offsetX >= 0) && (offsetX <= width) && (offsetY <= height) && (offsetY >= 0) ) {
					$this.trigger('mouseenter');
				}
				$(document).unbind('mousemove.poll');
			});
		});
		return this;
	},
	protectAnimation: function() {
		$(this).each(function() {
			// stop current animation
			if($(this).filter(':animated').size() > 0) {
				$(this).stop();	
			}
			// prevent stuck style tag
			$(this).attr('style','');
		});
		return this;
	}
});


/*!
	// modified to work with myfaves
	reflection.js for jQuery v1.03
	(c) 2006-2009 Christophe Beyls <http://www.digitalia.be>
	MIT-style license.
*/


$.fn.extend({
	reflect: function(options) {
		options = $.extend({
			height: (4/20),
			opacity: 0.7
		}, options);
		this.each(function() {
			if (/^img$/i.test(this.tagName)) {
				var img = this;
				var location = this;	
			}
			else {
				var location = this;	
				var background = $(this).css('background-image')
					.replace('url("', '')
					.replace('url(', '')
					.replace('")', '')
					.replace(')', '')
				;
				var img = $('<img />').attr('src', background)[0];
			}
			function doReflect() {
				var imageWidth = img.width, 
					imageHeight = img.height, 
					reflection, 
					reflectionHeight,
					context, 
					gradient
				;
				reflectionHeight = Math.floor((options.height > 1) 
					? Math.min(imageHeight, options.height) 
					: imageHeight * options.height)
				;
				if ($.browser.msie) {
					reflection = $('<img />').attr('src', img.src)
						.css({
							width: imageWidth,
							height: imageHeight,
							marginBottom: reflectionHeight - imageHeight,
							filter: 'flipv progid:DXImageTransform.Microsoft.Alpha(opacity=' + (options.opacity * 100) + 
							', style=1, finishOpacity=0, startx=0, starty=0, finishx=0, finishy=' + (reflectionHeight / imageHeight * 100) + ')'
						})[0]
					;
				} else {
					reflection = $('<canvas />')[0];
					if (!reflection.getContext) { 
						return;
					}
					context = reflection.getContext('2d');
					try {
						$(reflection).attr({width: imageWidth, height: reflectionHeight});
						context.save();
						context.translate(0, imageHeight-1);
						context.scale(1, -1);
						context.drawImage(img, 0, 0, imageWidth, imageHeight);
						context.restore();
						context.globalCompositeOperation = 'destination-out';

						gradient = context.createLinearGradient(0, 0, 0, reflectionHeight);
						gradient.addColorStop(0, 'rgba(255, 255, 255, ' + (1 - options.opacity) + ')');
						gradient.addColorStop(1, 'rgba(255, 255, 255, 1.0)');
						context.fillStyle = gradient;
						context.rect(0, 0, imageWidth, reflectionHeight);
						context.fill();
					} 
					catch(e) {
						return;
					}
				}
				var $icon = $(location).parents('.icon');
				$(reflection)
					.addClass('reflection')
					.insertAfter($icon)
				;
			}
			if (img.complete) {
				doReflect();
			}
			else {
				$(img).load(doReflect);
			}
		});
		return this;
	}
});


/*	******************************
		PLUGIN - Follow Link 
		Author: Jack Lukic - KNI
		Last revision: July 2010
	******************************	*/
jQuery.fn.extend({
	followLink: function(filter) {
		return $(this).each(function() {
			$(this).bind('click', function() {
				if(typeof filter == 'undefined') {
					var href = $(this).find('a').eq(0).attr('href');
				}
				else {
					var href = $(this).find(filter).eq(0).attr('href');
				}
				if(href) {
					// find base 
					var base = $('base').attr('href');
					window.location.href = base + href;	
				}
				return false;
			});
		});
	}
});

/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

/**
 * Create a cookie with the given name and value and other optional parameters.
 *
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Set the value of a cookie.
 * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
 * @desc Create a cookie with all available options.
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Create a session cookie.
 * @example $.cookie('the_cookie', null);
 * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
 *       used when the cookie was set.
 *
 * @param String name The name of the cookie.
 * @param String value The value of the cookie.
 * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
 * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
 *                             when the the browser exits.
 * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
 * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 *                        require a secure protocol (like HTTPS).
 * @type undefined
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */

/**
 * Get the value of a cookie with the given name.
 *
 * @example $.cookie('the_cookie');
 * @desc Get the value of a cookie.
 *
 * @param String name The name of the cookie.
 * @return The value of the cookie.
 * @type String
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */
jQuery.storage = function(name, value, options) {
    if (typeof value != 'undefined') {
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
		if(encodeURIComponent(value) == null) {
			return false;	
		}
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
		if($.cookie('username')) {
			fav4.settings.syncSettings();	
		}		
    } 
	else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
		if(fav4.user && fav4.user.settings && typeof(fav4.user.settings[name]) != 'undefined') {
			return fav4.user.settings[name];	
		}
        return cookieValue;
    }
};

jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') {
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');	
    } 
	else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};

