function set_fancybox() {
	$("a.fancybox").fancybox({
		'transitionIn'  :	'fade',
		'transitionOut' :	'fade',
		'speedIn'       :	600,
		'speedOut'      :	200,
		'type'          :	'image',
		'titlePosition' :	'inside'
	});
}

function set_hyphenator() {
	//sh_highlightDocument();
	Hyphenator.config({
		displaytogglebox: true,
		intermediatestate: 'visible',
		selectorfunction: function() {
			return $(".content p").get();
		},
		safecopy: true,
		togglebox: function(s) {
			var myBox, bdy, myIdAttribute, myTextNode, myClassAttribute;
			if (!!(myBox = document.getElementById('HyphenatorToggleBox'))) {
				if(s) {
					myBox.firstChild.data = 'Hy-phe-na-ti-on';
				} else {
					myBox.firstChild.data = 'Hyphenation';
				}
			} else {
				createElem = function(tagname) {
					if (document.createElementNS) {
						return document.createElementNS('http://www.w3.org/1999/xhtml', tagname);
					} else if(document.createElement) {
						return document.createElement(tagname);
					}
				};
				bdy = document.getElementsByTagName('body')[0];
				myBox = createElem('div');
				myIdAttribute = document.createAttribute('id');
				myIdAttribute.nodeValue = 'HyphenatorToggleBox';
				myTextNode = document.createTextNode('Hy-phe-na-ti-on');
				myBox.appendChild(myTextNode);
				myBox.setAttributeNode(myIdAttribute);
				myBox.onclick =  Hyphenator.toggleHyphenation;
				$(bdy).append(myBox);
			}
		}
	});
}

function path() {
	var args = arguments,
	    result = []
	;

	for(var i = 0; i < args.length; i++) {
		result.push(args[i].replace('@', 'http://alexgorbatchev.com/pub/sh/current/scripts/'));
	}
	return result
};

function set_syntaxhighlighter() {
	SyntaxHighlighter.autoloader.apply(null, path(
		'cpp c                  @shBrushCpp.js',
		'c# c-sharp csharp      @shBrushCSharp.js',
		'css                    @shBrushCss.js',
		'js jscript javascript  @shBrushJScript.js',
		'xml xhtml xslt html    @shBrushXml.js'
	));
	SyntaxHighlighter.defaults['pad-line-numbers'] = true;
	SyntaxHighlighter.all();
}

function fix_photosets() {
	$(".html_photoset").each(function() {
		var maxHeight = 0;
		var container = $(this);
		if(container.find(".photoset_photo").length > 0) {
			container.find(".photoset_photo").each(function() {
				if(this.height > maxHeight) {
					maxHeight = this.height;
					container.height(this.height);
				}
			});
		} else {
			//var embed = $(container.find("embed").get(0));
			//var flashvars = embed.attr("flashvars");
			var embed = container.find("embed").get(0);
			var flashvars = embed.getAttribute("flashvars");
			var params = {};
			flashvars.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, key, value) {
				params[key] = value;
			});
			$.get(params.dataFile, function(xml) {
				$(xml).find("image").each(function() {
					var img = $(new Image());
					img.load(function() {
						if(this.height > maxHeight) {
							maxHeight = this.height;
							container.height(this.height);
							$(embed).height(this.height);
						}
					}).attr("src", $(this).attr("source"));
				});
			});
		}
	});
}

function fix_videos() {
	$(".post.video").each(function() {
		var container = $(this);
		var targetWidth = $(container.find(".post-data").get(0)).width();
		$("object").each(function () {
			if($(this).find("embed[src^='http://www.youtube.com']").length > 0) {
				// Identify and hide embed(s)
				var parent = $(this).parent();
				parent.css("visibility","hidden");
				var youtubeCode = parent.html();
				if(youtubeCode.toLowerCase().indexOf("<param") == -1) {
					var params = "";
					// IE doesn't return params with html(), so...
					$("param", this).each(function () {
						params += $(this).get(0).outerHTML;
					});
					youtubeCode = youtubeCode.replace(/<embed/i, params + "<embed");
				}
				var theEmbed = $(this).find("embed");
				var theParam = $(this).find("param[name='movie']");
				// Set colours in control bar to match page background
				var oldOpts = /rel=0/g;
				var newColor = getHexColor(getRGB($(parent).css("background-color"))).substring(1);
				var newOpts = "rel=0&amp;color1=0x" + newColor + "&amp;color2=0x" + newColor + "&amp;hd=1&amp;border=0&amp;loop=1&amp;enablejsapi=1";
	
				theEmbed.get(0).src = theEmbed.get(0).src.replace(oldOpts, newOpts);
				if(theParam.length > 0) {
					theParam.get(0).value = theParam.get(0).value.replace(oldOpts, newOpts);
				}
	
				youtubeCode = youtubeCode.replace(oldOpts, newOpts);
				// Extract YouTube ID and calculate ideal height
				var youtubeIDParam = $(this).find("embed").attr("src");
				var youtubeIDPattern = /\/v\/([0-9A-Za-z-_]*)/;
				var youtubeID = youtubeIDParam.match(youtubeIDPattern);
				// Test for widescreen aspect ratio
				$.getJSON("http://gdata.youtube.com/feeds/api/videos/" + youtubeID[1] + "?v=2&alt=jsonc&callback=?", function(data) {
					if(data.error === undefined)
					{
						data = data.data;
						var heightRatio = 1;
						if (data.aspectRatio != null) {
							heightRatio = 0.5625;
						} else {
							heightRatio = 0.75;
						}
						// Replace YouTube embed with new code
						parent.html(youtubeCode);
						parent.find("object").width(targetWidth);
						parent.find("object").height(targetWidth * heightRatio);
						parent.find("object").find("embed").width(targetWidth);
						parent.find("object").find("embed").height(targetWidth * heightRatio);
						parent.css("visibility","visible");
						
						container.find(".magnifier .fancybox").each(function() {
							$(this).fancybox({
								"type": "swf",
								"swf": {
									"allowfullscreen": "true"
								},
								"height": 720,
								"width": 720 / heightRatio,
								"href": $(container.find("embed").get(0)).attr("src"),
								"titlePosition": "inside"
							});
						});
					}
				});
			}
		});
	});
}

function set_search() {
	$("input[type=search]").focus(function() {
		if($(this).val() == "Search") {
			$(this).val("")
		}
	})
	$("input[type=search]").blur(function() {
		if($(this).val() == "") {
			$(this).val("Search")
		}
	})
}

function fix_images() {
	$("img").each(function() {
		$(this).removeAttr("hspace");
		$(this).removeAttr("vspace");
	});
	$(".post-body p > a[href^='http']").filter(":has(img)").each(function() {
		$(this).css('background', 'inherit');
		$(this).css('padding-right', 'inherit');
	});
	$(".post.link").each(function() {
		var container = $(this);
		var targetWidth = 500;
		container.find(".description img").each(function() {
			if($(this).width() > targetWidth)
			{
				var ratio = targetWidth / $(this).width();
				var newHeight = $(this).height() * ratio;
				var newWidth  = targetWidth;
				$(this).width (newWidth );
				$(this).height(newHeight);
			}
		});
	});
	$(".post.text").each(function() {
		var container = $(this);
		var targetWidth = 500;
		container.find(".post-body img").each(function() {
			if($(this).width() > targetWidth)
			{
				var ratio = targetWidth / $(this).width();
				var newHeight = $(this).height() * ratio;
				var newWidth  = targetWidth;
				$(this).width (newWidth );
				$(this).height(newHeight);
			}
		});
	});
}

function previousNode(n)
{
	do
	{
		n = n.previousSibling;
	}
	while(n.nodeType != 1);
	return n;
}

var monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];

function rightNowString(dt)
{
	return dt.getFullYear() + (dt.getMonth() < 9 ? "0" : "") + (dt.getMonth() + 1) + (dt.getDate() < 10 ? "0" : "") + dt.getDate() + (dt.getHours() < 10 ? "0" : "") + dt.getHours() + (dt.getMinutes() < 10 ? "0" : "") + dt.getMinutes() + (dt.getSeconds() < 10 ? "0" : "") + dt.getSeconds();
}

function wholeDayString(dt)
{
	return dt.getFullYear() + (dt.getMonth() < 9 ? "0" : "") + (dt.getMonth() + 1) + (dt.getDate() < 10 ? "0" : "") + dt.getDate() + "235959";
}

function tidy_tweets(data)
{
	data = data.results;
	data = $.grep(data, function(elt) { return elt.to_user_id == null; });
//	data = $.grep(data, function(elt) { return elt.text.substring(0, 4) != "RT @"; });
	data.sort(function(lhs, rhs) { return (Number(Date.parse(rhs.created_at)) - Number(Date.parse(lhs.created_at))); });
	$.each(data, function(idx, val) { data[idx].created_at = new Date(Date.parse(val.created_at)); });
	$.each(data, function(idx, val) { data[idx].text = val.text.replace(/(http[s]?:\/\/\S+)/g, "<a href=\"$1\">$1</a>"); });
	$.each(data, function(idx, val) { data[idx].text = val.text.replace(/\#(\w+)/g, "<a href=\"http://twitter.com/search?q=%23$1\">#$1</a>"); });
	$.each(data, function(idx, val) { data[idx].text = val.text.replace(/\@(\w+)/g, "<a href=\"http://twitter.com/$1\">@$1</a>"); });
	return data;
}

function populate_tweets_new(data)
{
	data = tidy_tweets(data);
	for(i = 0; i < data.length; ++i)
	{
		var dt = data[i].created_at;
		var right_now = rightNowString(dt);
		var whole_day = wholeDayString(dt);
		
		var twit_node = document.getElementById("canonical_twitter").cloneNode(true);
		twit_node.id = "t_" + data[i].id;
		$(twit_node).removeClass("hide");
		$(twit_node).find("#twitter_status")[0].innerHTML = data[i].text;
		$(twit_node).find(".timestamp a")[0].innerHTML = (dt.getHours() < 10 ? "0" : "") + dt.getHours() + ":" + (dt.getMinutes() < 10 ? "0" : "") + dt.getMinutes();
		$(twit_node).find(".timestamp a")[0].href = "http://twitter.com/" + data[i].from_user + "/status/" + data[i].id_str;
		$(twit_node).find(".permalink a")[0].href = "http://twitter.com/" + data[i].from_user + "/status/" + data[i].id_str;

		//$("#tweets")[0].appendChild(twit_node);
	}
}

function populate_tweets(data)
{
	data = tidy_tweets(data);
	
	var date_finders = $(".date_finder");
	
	var date_picker = [];
	for(j = 0; j < date_finders.length; ++j)
	{
		date_picker.push({
			"date" : date_finders[j].id.substring(2),
			"element" : date_finders[j]
		});
	}
	
	if(current_page > 1 && wholeDayString(data[data.length - 1].created_at) > date_picker[0].date)
	{
		return;
	}

	for(i = 0; i < data.length; ++i)
	{
		var dt = data[i].created_at;
		var right_now = rightNowString(dt);
		var whole_day = wholeDayString(dt);

		var chosen_position = null;
		var chosen_index = -1;
		for(j = 0; j < date_picker.length; ++j)
		{
			if(right_now > date_picker[j].date)
			{
				chosen_position = date_picker[j].element;
				chosen_index = j;
				break;
			}
		}

		if(chosen_position)
		{
			var twit_node = document.getElementById("canonical_twitter").cloneNode(true);
			twit_node.id = "t_" + data[i].id;
			$(twit_node).removeClass("hide");
			$(twit_node).find("#twitter_status")[0].innerHTML = data[i].text;
			$(twit_node).find(".timestamp a")[0].innerHTML = (dt.getHours() < 10 ? "0" : "") + dt.getHours() + ":" + (dt.getMinutes() < 10 ? "0" : "") + dt.getMinutes();
			$(twit_node).find(".timestamp a")[0].href = "http://twitter.com/" + data[i].from_user + "/status/" + data[i].id_str;
			$(twit_node).find(".permalink a")[0].href = "http://twitter.com/" + data[i].from_user + "/status/" + data[i].id_str;
			
			var date_id = "d_" + whole_day;
			
			var date_node = $("#" + date_id);
			if(date_node.length == 0)
			{
				date_node = document.getElementById("canonical_date_entry").cloneNode(true);
				date_node.id = date_id;
				$(date_node).removeClass("hide");
				$(date_node).find("a")[0].href = "/archive/" + dt.getFullYear() + "/" + (dt.getMonth() < 9 ? "0" : "") + (dt.getMonth() + 1);
				$(date_node).find("a")[1].href = "/archive/" + dt.getFullYear() + "/" + (dt.getMonth() < 9 ? "0" : "") + (dt.getMonth() + 1);
				$(date_node).find("a")[1].innerHTML = dt.getDate() + " " + monthNames[dt.getMonth()] + " " + dt.getFullYear();
				chosen_position.parentNode.insertBefore(date_node, chosen_position);
				
				date_picker.splice(chosen_index, 0, {
					"date" : whole_day,
					"element" : date_node
				});
				++chosen_index;
			}
			var finder_node = document.getElementById("canonical_date_finder").cloneNode(true);
			finder_node.id = "d_" + right_now;
			
			date_picker.splice(chosen_index, 0, {
				"date" : right_now,
				"element" : finder_node
			});
			
			chosen_position.parentNode.insertBefore(finder_node, chosen_position);
			chosen_position.parentNode.insertBefore(twit_node, chosen_position);
		}
	}
}

function retrieve_tweets() {
	if(Object.isDefined(window.twitter_username)) {
		$.getJSON("http://search.twitter.com/" + "search.json?callback=?", { "q": "from:" + twitter_username, "result_type": "recent", "rpp": 100 }, populate_tweets);
	}
}

// based on https://github.com/tuupola/jquery_lazyload
function set_lazyload() {
	$.fn.lazyload = function(options) {
		var settings = {
			threshold : 0,
			failurelimit : 0,
			event : "scroll",
			container : window,
			prime: function(self, settings) {
			},
			reveal: function(self, settings) {
			}
		};

		if(options) {
			$.extend(settings, options);
		}

		// Fire one scroll event per scroll. Not one scroll event per image.
		var elements = this;
		if("scroll" == settings.event) {
			$(settings.container).bind("scroll", function(event) {
				var counter = 0;
				elements.each(function() {
					if($.abovethetop(this, settings) || $.leftofbegin(this, settings)) {
						/* Nothing. */
					} else if(!$.belowthefold(this, settings) && !$.rightoffold(this, settings)) {
						$(this).trigger("appear");
					} else if(counter++ > settings.failurelimit) {
						return false;
					}
				});
				// Remove element from array so it is not looped next time.
				var temp = $.grep(elements, function(element) {
					return !element.loaded;
				});
				elements = $(temp);
			});
		}
		
		this.each(function() {
			var self = this;
			self.loaded = false;
			
			settings.prime(self, settings);

			$(self).one("appear", function() {
				if(!this.loaded) {
					self.loaded = true;
					settings.reveal(self, settings);
				};
			});

			if("scroll" != settings.event) {
				$(self).bind(settings.event, function(event) {
					if(!self.loaded) {
						$(self).trigger("appear");
					}
				});
			}
		});
		
		// Force initial check if images should appear.
		$(settings.container).trigger(settings.event);
		
		return this;
	};

	// Convenience methods in jQuery namespace.
	// Use as $.belowthefold(element, {threshold : 100, container : window})

	$.belowthefold = function(element, settings) {
		var fold = null;
		if(settings.container === undefined || settings.container === window) {
			fold = $(window).height() + $(window).scrollTop();
		} else {
			fold = $(settings.container).offset().top + $(settings.container).height();
		}
		return fold <= $(element).offset().top - settings.threshold;
	};
	
	$.rightoffold = function(element, settings) {
		var fold = null;
		if(settings.container === undefined || settings.container === window) {
			fold = $(window).width() + $(window).scrollLeft();
		} else {
			fold = $(settings.container).offset().left + $(settings.container).width();
		}
		return fold <= $(element).offset().left - settings.threshold;
	};
		
	$.abovethetop = function(element, settings) {
		var fold = null;
		if(settings.container === undefined || settings.container === window) {
			fold = $(window).scrollTop();
		} else {
			fold = $(settings.container).offset().top;
		}
		return fold >= $(element).offset().top + settings.threshold  + $(element).height();
	};
	
	$.leftofbegin = function(element, settings) {
		var fold = null;
		if(settings.container === undefined || settings.container === window) {
			fold = $(window).scrollLeft();
		} else {
			fold = $(settings.container).offset().left;
		}
		return fold >= $(element).offset().left + settings.threshold + $(element).width();
	};
	
	// Custom selectors for your convenience.
	// Use as $("img:below-the-fold").something()
	$.extend($.expr[':'], {
		"below-the-fold" : "$.belowthefold(a, {threshold : 0, container: window})",
		"above-the-fold" : "!$.belowthefold(a, {threshold : 0, container: window})",
		"right-of-fold"  : "$.rightoffold(a, {threshold : 0, container: window})",
		"left-of-fold"   : "!$.rightoffold(a, {threshold : 0, container: window})"
	});
	
}

function set_page() {
	$.getScript('http://dl.dropbox.com/u/4619191/tumblr/time.js', function() {
		var profile = window.time || {
			start: function() {},
			stop: function() {},
			setLineReportMethod: function() {}
		};

		var console = window.console || {
			log: function() {}
		};

		profile.setLineReportMethod(function(l) {
			console.log(l);
		});
		
		if(!Object.isDefined(window.suppress_twitter) || !window.suppress_twitter) {
			retrieve_tweets();
		}

		set_fancybox();
		set_hyphenator();
		set_syntaxhighlighter();
		set_search();
		set_lazyload();
		
		profile.start('fix images');
		fix_images();
		profile.stop('fix images');
		profile.start('fix videos');
		fix_videos();
		profile.stop('fix videos');
		profile.start('fix photosets');
		fix_photosets();
		profile.stop('fix photosets');
		
		$('.post-body p').lazyload({
			threshold: 1000,
			reveal: function(self, settings) {
				profile.start('hyphenate_and_justify');
				hyphenate_and_justify({
					selection: $(self)
				});
				profile.stop('hyphenate_and_justify');
			}
		});
		
//		profile.start('hyphenate_and_justify');
//		hyphenate_and_justify({
//			selection: $('.post-body p')
//		});
//		profile.stop('hyphenate_and_justify');
	});
}

