/*******************************
       Namespaced Functions
 *******************************/

// Creates modal for chrome frame install prompt for unsupported browsers 
chester.chromeFrameInstall = function() {
	// cache some jq objects for anonfunctions
	var $content = $('#content, #footer, #post-count, #page-fade');
	var $gradients = $('#leftgradient, #rightgradient, #wrapper');
	var $modal = $('#chrome');	
	var $download = $modal.find('.download');
	
	// use chromeframe library code to check for install
	CFInstall.check({
		// prevent iframe prompt
		preventPrompt: true,
		
		onmissing: function() {
			// remove pngs
			$gradients.css('background-image','none');
			// hide content
			$content.hide();
			// bind events for button
			$download
				.hoverClass()
				.downClass()
			;
			// show modal
			$modal.show();
		},
		oninstall: function() {
			// hide modal
			$modal.hide();
			// show content
			$content.show();
		}
	});
};


// Bind events for photo sharing on fancybox
chester.bindPhotoShare = function() {
	var photo = chester.activePhoto;
	// add dynamic share links
	$('#fancy_shareoverlay .wall a').attr('href', photo.wall);
	$('#fancy_shareoverlay .tweet a').attr('href', photo.tweet);
	$('#fancy_shareoverlay .stumble a').attr('href', photo.stumble);
	// bind share close button
	$('#fancy_shareoverlay .close')
		.click(function() {
			$('#fancy_shareoverlay').hide();	
			return false;
		})
	;		
	// bind share links
	$('#fancy_shareoverlay ul li')
		.click(chester.activateShareLinks)
	;	
	// bind special share links 
	$('#fancy_shareoverlay .link, #fancy_shareoverlay .embed')
		.click(function() {
			$.fn.fancybox.close();
		})
	;
	$('#fancy_share')
		.click(function() {
			$('#fancy_shareoverlay').show();
			return false;
		})
	;
}

chester.setActivePhoto = function($card) {
	// generate photo config object
	chester.activePhoto = {
		// basic info
		category: 'photo',
		title: $card.find('input.title').val(),
		// embed copy text
		embedCopyText: $card.find('input.embed').val(),
		linkCopyText: $card.find('input.link').val(),
		// urls for wall/tweet/stumble links
		wall: $card.find('input.wall').val(),
		tweet: $card.find('input.tweet').val(),
		stumble: $card.find('input.stumble').val()
	}	
}

// Event binding for share links (featured, modal, back)
chester.activateShareLinks = function() {
	// cache
	var $this = $(this);
	var type = $this.attr('class');
	// grab tracking info, take out semicolon
	var category = $this.parents('.card').find('h3').html()
	if(typeof(category) == 'string') {
		category.replace(':','');
	}
	var title = $this.parents('.card').find('.title').html();
	// special category and title retrieval for photo modal share
	if($this.parents('#fancy_shareoverlay').exists()) {
		if(typeof(chester.activePhoto) != 'undefined') {
			var photo = chester.activePhoto;
			var category = photo.category;
			var title = photo.title;
		}
		chester.track.share(category, title, type);
		// follow normal links
		if( !$this.hasClass('link') && !$this.hasClass('embed')) {
			return true;
		}
	}
	// special category and title retrieval for featured content
	if($this.parents('.feature').exists()) {
		category = $this.parents('.card').find('.info .active h3').html();
		title = $this.parents('.card').find('.info .active a').html();
		if( !$this.hasClass('link') && !$this.hasClass('embed')) {
			chester.track.share(category, title, type);
			// find url
			var url = $this.parents('.card').find('.info .active .'+type).val();
			// follow normal links
			if(typeof(url) != 'undefined') {
				window.open(url);
			}
			return false;
		}
	}
	chester.track.share(category, title, type);
	
	// Special Case for Copy Links
	if( $this.hasClass('link') || $this.hasClass('embed') ) {
		var $info = $(this).parents('.card').find('.info');
		var $shareContent = $('#share');
		// find relevant info
		var category = $this.parents('.card').find('h3').html();
		var copyText = $this.find('code').html();
		// special category and title retrieval for featured content
		if($this.parents('#fancy_shareoverlay').exists()) {
			var copyText = photo[type+'CopyText'];
		}
		// special category and title retrieval for photo content 
		if($this.parents('.feature').exists()) {
			category = $this.parents('.card').find('.info .active h3').html();
			copyText = $this.parents('.card').find('.info .active .'+type).val();
		}
		// push to page
		$shareContent.find('h3').eq(0).html(category);
		$shareContent.find('p').eq(0).html(title);
		
		if($this.hasClass('embed')) {
			copyText = copyText.replaceAll('%26lt;','<').replaceAll('%26gt;','>');
		}
		$shareContent.find('textarea').eq(0).val(copyText);					
	
		$.dimScreen(chester.crossfadeDuration, chester.dimmerOpacity, function() {
			// recreate placement location
			$('#copy').html('<div id="copy-seo"></div>');
			// Add movie
			var config = {
				embed: "copy-seo",
				minimumFlashVersion: '9',
				src: "swf/copy-popup.swf",			
				width: "277",
				height: "41",
				expressInstall: 'swf/express-install.swf',
				
				vars: { copyText: copyText },
				params: { scale: "noscale", bgcolor: "", menu: "false", wmode: "transparent", allowScriptAccess: "always" },
				attributes: { id: 'copy-swf',	name: 'copy-swf' }
			};		
			swfobject.embedSWF(config.src, config.embed, config.width, config.height, config.minimumFlashVersion, config.expressInstall, config.vars, config.params, config.attributes);  
		
			var $close = $shareContent.find('.close');				
			$close
				.hoverClass()
				.downClass()
				.click(function() {
					$shareContent.fadeOut(chester.crossfadeDuration,function() {
						$.unDimScreen();									
					});
					return false;
				})
			;
			$shareContent.fadeIn(chester.crossfadeDuration);
		});
		return false;
	}	
}

// Precache images
chester.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;
	});	
}

chester.addDashes = function(value) {
	 value = value.replace(/ /gi,'-');
	 value = escape(value.replace(/[^0-9a-zA-Z-]/gi,""));
	 return value.toLowerCase();	
}

// Flip card
chester.cardFlip = function($this) {
	// use simple flip for IE
	if($.browser.msie) {
		chester.simpleFlip($this);
		return;
	}
	// cache jq objects
	var $card = $this.parents('.card');
	var $sides = $this.find('.front, .back');
	var $visibleSide = $sides.filter(':visible');
	var $hiddenSide = $sides.not(':visible');
	// figure out degrees for flip
	var degrees = '+=180';
	if($visibleSide.filter('.back').exists()) {
		var degrees =  '-=180';
		// reset skew on start to avoid antialiasing issues
		$this.css('transform','skew(360deg, 180deg) scale(1, 1)');			   
	}
	// settings
	var animationTime = chester.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 * chester.flip.ratio));	
	if(!$this.animated()) {
		$sides
			.css('opacity',0);
		$this
			.addClass('animating');
		$card
			.stop()
			.animate({ scale: scaleRatio}, {
				easing: chester.flip.easing.scale,
				duration: flipTime, 
				queue: false
			}
		);
		setTimeout(function() {
			$this
				.rotate3Di(degrees, animationTime, {
				direction: 'clockwise', 
				easing: chester.flip.easing.rotate,
				sideChange: function() {
					$card
						.animate({ 
							scale: 1 
						},{
							easing: chester.flip.easingfadeIn,
							duration: flipTime, 
							queue: false
						})
					;
					$this.toggleClass('flip');
				},
				complete: function() {
					$this
						.removeClass('animating')
						.css('transform','')
						.forceHover()
					;
					$hiddenSide
						.stop()
						.show()
						.animate({opacity: 1},{
							easing: chester.flip.easing.fadeIn,
							duration: flipTime, 
							queue: false
						})
					;
				}
			});
		}, flipTime);
	}
};

chester.simpleFlip = function($this) {
	// cache
	var $card = $this.parents('.card');
	var $sides = $this.find('.front, .back');
	var $visibleSide = $sides.filter(':visible');
	var $hiddenSide = $sides.not(':visible');
	// flip
	$this.toggleClass('flip');
	$visibleSide.hide();
	$hiddenSide.show();
}

chester.isURL = function(url) {
	var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
	return regexp.test(url);
}

// User submission request
chester.submitContent = function() {
	
	var $submitContent = $('#submit');
	var $submitCategory = $('#submit-category');
	var $submitButton = $submitContent.find('.submit');
	
	// find category
	var category = $('#category').val();
	var pageLink = $('#submit-site').val();
	
	if(category == '') {
		$submitContent.find('.form')
			.fadeOut(chester.crossfadeDuration, function(){
				$submitContent
					.find('.error')
						.find('p').eq(0)
						.html(chester.errors.form.category)
						.end()
					.end()
					.fadeIn(chester.crossfadeDuration)
				;
			})
		;	
	}
	else if(!chester.isURL(pageLink)) {
		$submitContent.find('.form')
			.fadeOut(chester.crossfadeDuration, function(){
				$submitContent
					.find('.error')
						.find('p').eq(0)
						.html(chester.errors.form.pageLink)
						.end()
					.end()
					.fadeIn(chester.crossfadeDuration)
				;
			})
		;	
	}
	// No errors, lets submit content
	else {
		// analytics tracking
		chester.track.submission(category);
		// generate api link
		var url = chester.submit.service
			.replace('$cat', category)
			.replace('$link', pageLink)
		;
		// give request
		$.ajax({
			type: "GET",
			url: url,
			dataType: "json",
			error: function() {
				// show error content
				$submitContent.find('.form')
					.fadeOut(chester.crossfadeDuration, function(){
						$submitContent
							.find('.error')
								.find('p').eq(0)
								.html(chester.errors.technical.generic)
								.end()
							.end()
							.fadeIn(chester.crossfadeDuration)
						;
					})
				;
			},
			success: function(response) {
				if(!response.errors && typeof(response.data) != 'undefined') {
					// Show success content
					$submitContent.find('.form')
						.fadeOut(chester.crossfadeDuration, function(){
							$submitContent.find('.success').fadeIn(chester.crossfadeDuration);
						})
					;
				}
				else {
					// show error content
					$submitContent.find('.form')
						.fadeOut(chester.crossfadeDuration, function(){
							$submitContent
								.find('.error')
									.find('p').eq(0)
									.html(chester.errors.technical.service)
									.end()
								.end()
								.fadeIn(chester.crossfadeDuration)
							;
						})
					;
				}
			}
		});	
	}
}

// Report like statistics to backend and record cookie
chester.addLike = function($post, callback) {
	var $uid = $post.find('.uid');
	// find id
	var uid = $uid.html();

	if(typeof(uid) != 'undefined') {
		// find service url from config
		var url = chester.like.service.addLike.replace('$id',uid);
		var $text = $post.find('p');
		// add to like total
		$.ajax({
			type: "GET",
			url: url,
			dataType: "json",
			error: function() {
				var response = {
					data: 339,
					errors: false
				};
				if(!response.errors) {
					// grab number of likes
					var number = response.data;
					// if not a small post be verbose
					if(!$post.parents('.small').exists()) {
						// \num = # posts
						number = chester.like.verbose.replace('$num', number);							   
					};
					$text.html(number) 
					callback();
				}
			},
			success: function(response) {
				if(!response.errors && typeof(response.data) != 'undefined') {
					// grab number of likes
					var number = response.data;
					// if feature post, update hidden inputs to keep track
					if($post.parents('.feature').exists()) {
						var $card = $post.parents('.card');
						var $activeInfo = $card.find('input.uid[value='+uid+']').parent();
						// set new liked and # likes value (string literal boolean)
						$activeInfo.find('.likes').val(number);
						$activeInfo.find('.liked').val('true');
					}					
					// if not a small post be verbose
					if(!$post.parents('.small').exists()) {
						// \num = # posts
						number = chester.like.verbose.replace('$num', number);							   
					}
					$text.html(number)
					callback();
				}
			}
		});
	}	
}

// Report like statistics to backend and record cookie
chester.removeLike = function($post, callback) {
	var $uid = $post.find('.uid');
	// find id
	var uid = $uid.html();

	if(typeof(uid) != 'undefined') {
		// find service url from config
		var url = chester.like.service.addUnlike.replace('$id',uid);
		var $text = $post.find('p');
		// add to like total
		$.ajax({
			type: "GET",
			url: url,
			dataType: "json",
			error: function() {
				var response = {
					data: 339,
					errors: false
				};
				if(!response.errors) {
					// grab number of likes
					var number = response.data;
					// if not a small post be verbose
					if(!$post.parents('.small').exists()) {
						// \num = # posts
						number = chester.like.verbose.replace('$num', number);							   
					}
					$text.html(number);
					callback();
				}
			},
			success: function(response) {
				if(!response.errors && typeof(response.data) != 'undefined') {
					// grab number of likes
					if(response.data == 'None') {
						response.data = 0;	
					}
					var number = response.data;
					// if feature post, update hidden inputs to keep track
					if($post.parents('.feature').exists()) {
						var $card = $post.parents('.card');
						var $activeInfo = $card.find('input.uid[value='+uid+']').parent();
						// set new liked and # likes value (string literal boolean)
						$activeInfo.find('.likes').val(number);
						$activeInfo.find('.liked').val('false');
					}	
					// if not a small post be verbose
					if(!$post.parents('.small').exists()) {
						// \num = # posts
						number = chester.like.verbose.replace('$num', number);							   
					}
					$text.html(number);
					callback();
				}
			}
		});
	}	
}

// Add featured badge on page load
chester.addBadge = function() {
	var config = {
		embed: "chester-badge",
		minimumFlashVersion: '8',
		src: "swf/badge.swf",			
		width: "200",
		height: "425",
		expressInstall: 'swf/express-install.swf',
		
		vars: {  },
		params: { scale: "noscale", bgcolor: "#000000", menu: "false", wmode: "transparent", allowScriptAccess: "always" },
		attributes: { id: 'chester-badge-swf',	name: 'chester-badge-swf' }
	};				
	swfobject.embedSWF(config.src, config.embed, config.width, config.height, config.minimumFlashVersion, config.expressInstall, config.vars, config.params, config.attributes); 	
}

chester.addStaticBadge = function() {
	$('#chester-badge-hold').addClass('init');
	chester.precache(chester.staticBadge, function() {
		$('#chester-badge-static').show();
		$('#chester-badge-hold').hide();
	});
}



chester.trackView = function(uid) {
	var url = chester.postCount.service.replace('$id', uid);
	$.ajax({
		type: "GET",
		url: url,
		dataType: "json"
	});	
}

// Add cheetos dust to a clicked link
chester.addDust = function($this) {
	var dustRand = 1 + Math.floor(Math.random() * chester.dustQuantity);
	// pick a random template
	if($this.parents('.card').hasClass('small')) {
		var dustRand = chester.dustSmall;	
	}
	// create dust
	var $dust = $('<div/>').addClass('dust smudge'+dustRand).appendTo($this);
	// find offset of point
	var offset = $this.offset();
	// check if there's an image border
	var $grey = $this.find('.unit');
	// grab dimensions
	var dustWidth = $dust.width();
	var dustHeight = $dust.height();
	var cardXBound = $this.width();
	var cardYBound = $this.height();
	
	// if an image border exists, make dust align with bottom edge of image
	if($grey.exists()) {
		var greyYOffset = ($grey.offset().top - $this.offset().top) + $grey.height();
	}
	else {
		var greyYOffset = cardYBound * 0.85;
	}
	var minY = greyYOffset - (dustWidth * 0.75);
	var maxY = greyYOffset;
	var minX = 0;
	var maxX = cardXBound - dustWidth;
	
	var randX = maxX;
	var randY = maxY;
	var x = 0;
	while( randX > maxX - 60 && randY > cardYBound - dustHeight - 25) {
		var randX = Math.floor(Math.random() * (maxX - minX + 1) + minX);  
		var randY = Math.floor(Math.random() * (maxY - minY + 1) + minY);
		if(x > 20) {
			chester.addDust($this);
			break;
		}
		x++;
	}
	
	/*
	var width = $this.width();
	var height = $this.height();
	var rangeX = 0;
	var rangeY = 0;
	var randX = 1 + Math.floor(Math.random() * rangeX);
	var randY = 1 + Math.floor(Math.random() * rangeY);
	*/	
	
	$dust
		.css({ left: randX, top: randY })
		.fadeIn()
	;	
};


// Calculate number of columns available in layout
chester.numColumns = function() {
	// use standard equation at 1024 or under
	var width = $(window).width();
	if(width < 1050) {
		var numCols = parseInt( (parseInt(width) ) / chester.columnWidth);		
	}
	// otherwise use equation with padding	
	else {
		var numCols = parseInt( (parseInt(width) - chester.resizePadding ) / chester.columnWidth);
	}
	return (numCols == 0) ? 1 : numCols;
};

// Add class to content defining number of columns available
chester.resizeColumns = function() {
	/* Pure JS Solution
	var numCols = parseInt(parseInt(window.innerWidth) / 250);
	numCols = (numCols == 0) ? 1 : numCols;
	document.getElementById('content').className = " col"+numCols;
	*/
	$('#content, #footer').attr('class','col'+chester.numColumns());
	chester.addPlaceholders();
};

// Create a self clearing timer to prevent overfiring
chester.delayedTimer = function(timer, functionName, delay) {
	if(typeof(timer) != 'undefined') {
		clearTimeout(timer);	
	}
	timer = setTimeout(function(){
		functionName();
	}, delay);
};

chester.addPlaceholders = function() {
	// cache vars
	var $content = $('#content');
	var numCards = $content.find('.card').size();
	var numColumns = chester.numColumns();
	var isHomePage = !$('body.subpage').exists();
	var cardClass = '';
	
	// figure out unit based on pagetype
	if(isHomePage) {
		// features take up 2 columns
		var numFeatures = $content.find('.feature').size() * 2;
		var numCards = $content.find('.block').not('.empty').size() + numFeatures;
		// remove current placeholders
		$content.find('.empty').remove();
	}
	else {
		var $availableCards = $content.find('.card').not('.placeholder');
		var numCards = $availableCards.size();
		// add special class for news subsection
		if($availableCards.hasClass('tall')) {
			var cardClass = ' tall';
		}
		// remove current placeholders
		$content.find('.placeholder').remove();
	}
	
	// figure out how many placeholders
	var numPlaceholders = numColumns - (numCards % numColumns);
		
	
	// make sure we are multicolumn
	if(numColumns > 1 && numPlaceholders != numColumns) {
		// append placeholders
		for(var i = 0; i < numPlaceholders; i++) {				// main feed uses blocks
			if(isHomePage) {
				var $placeholder = $('<div/>').addClass('empty').addClass('block');
				// block is made up of two cards
				$('<div/>')
					.addClass('placeholder card')
					.appendTo($placeholder)
				;
				$('<div/>')
					.addClass('placeholder card')
					.appendTo($placeholder)
				;
			}
			// subpage uses cards not blocks
			else {
				var $placeholder = $('<div/>').addClass('placeholder card' + cardClass);
			}
			$content.append($placeholder);
		}
	}
}

String.prototype.replaceAll = function(strTarget, strSubString) {
	var strText = this;
	var intIndexOfMatch = strText.indexOf( strTarget );
	while (intIndexOfMatch != -1){
		strText = strText.replace( strTarget, strSubString )
		intIndexOfMatch = strText.indexOf( strTarget );
	}
	return( strText );
}

