(function( $ ){

	$.fn.klepper = function( options ) {

		var $this				= $(this);
		var first				= true;
		var container			= $this;
		var useAnimating		= false;

		var tweets				= [];
		var shownTweets			= [];
		var unsuccessfulCalls	= 0;
		var newestTweet			= 0;

		var settings = {
			// App settings
			numStartTweets:	1,
			sorting:		'asc',
			refreshSpeed:	5000,
			uniqueOnly:		false,

			animating:			true,
			animation:			"easeOutBounce",
			animationSpeed:		500,

			fetchNum:			20
		};

		var feeds = {
			news: {
				show:			true,
				inactiveAfter:	5,
				scripts:		'/_jsFunctions/klepper/scripts/fetchNews.php',
				callback:		fetchNews
			},
			home: {
				show:			false,
				inactiveAfter:	5,
				script:			'/js/klepper/scripts/fetchHome.php',
				callback:		fetchHome
			},
			mentions: {
				show:			false,
				inactiveAfter:	5,
				script:			'/js/klepper/scripts/fetchMentions.php',
				callback:		fetchMentions
			}
		};

		return this.each(function() {

			if ( options ) {
				$.extend( settings, options );
			}

			$this.html("");
			if (jQuery().tinyscrollbar) {
				makeTinyScrollbar();
				container = $this.find(".viewport .overview");
				$this.tinyscrollbar();
			}
			if (jQuery.easing) {
				if (settings.animating) {
					useAnimating = true;
				}
			}

			$.each(feeds, function(i, feed) {
				if (feed.show) {
					feed.callback();
				}
			});

			if (settings.numStartTweets < 1) {first = false;}

			// Start the update method
			refresh();

		});

		function refresh() {
			// Sorts the tweets
			tweets.sort(dateSorter);
			// Parses the tweet
			parseTweet(tweets.shift());
			// Runs the update again
			setTimeout(refresh, ((shownTweets.length >= ((settings.fetchNum > settings.numStartTweets) ? (settings.numStartTweets) : (settings.fetchNum))) ? (settings.refreshSpeed) : (0)));
		}

		function dateSorter( tweet1, tweet2 ) {
			if (settings.sorting == 'asc') {
				return Date.parse(tweet1.created_at).getTime() - Date.parse(tweet2.created_at).getTime();
			} else if (settings.sorting == 'desc') {
				return Date.parse(tweet2.created_at).getTime() - Date.parse(tweet1.created_at).getTime();
			}

			return 0;
		}

		function parseTweet(tweet) {
			if (typeof tweet !== "undefined") {
				if (!settings.uniqueOnly || typeof shownTweets[tweet.id] === "undefined") {
					// Sets this tweet as shown
					shownTweets.splice(tweet.id, 1, true);
					shownTweets[tweet.id] = true;
					if (newestTweet < tweet.timestamp) {
						newestTweet = tweet.timestamp
					}


					// Replace links
					tweet.text = tweet.text.replace(/(https{0,1}:\/\/[\w\-\.\/#?&=]*)/g, "<a href='$1' target='blank'>$1</a>");
					// Replace at tags
					tweet.text = tweet.text.replace(/@(\w+)/g, "@<a href='http://twitter.com/$1' target='blank' class='at'>$1</a>");
					// Replace hashtag tags
					tweet.text = tweet.text.replace(/\s#(\w+)/g, "<a href='http://twitter.com/#!/search?q=%23$1' target='blank' class='hashtag'>#$1</a>");

					// Makes the tweet box
					var tweetBox = $(document.createElement("div")).addClass("tweet").append(
						$(document.createElement("div")).addClass("body").append(
							//$(document.createElement("div")).addClass("avatar").append(
//								$(document.createElement("img")).attr("src", tweet.user.profile_image_url)
//							)
						).append(
							$(document.createElement("div")).addClass("content").append(
								$(document.createElement("a")).addClass("user-link").attr("target", "blank").attr("href", "http://www.twitter.com/" + tweet.user.screen_name + "/").html(tweet.user.screen_name)
							).append(tweet.text)
						).append(
							$(document.createElement("div")).addClass("clear")
						)
					).append(
						//$(document.createElement("div")).addClass("footer").append(
//							$(document.createElement("span")).addClass("timestamp").attr("title", tweet.created_at).html(tweet.created_at).timeago()
//						).append(
//							" - "
//						).append(
//							$(document.createElement("a")).addClass("reply-link").attr("target", "blank").attr("href", "http://www.twitter.com/?status=@" + tweet.user.screen_name + "&in_reply_to_status_id=" + tweet.id + "&in_reply_to=" + tweet.user.screen_name).html("reply")
//						)
					);
					container.prepend(tweetBox);
					var heightBox = 0;
					heightBox += tweetBox.find(".body").height();
					heightBox += tweetBox.find(".footer").height();

					if (useAnimating && !first) {
						tweetBox.css({display: "none"}).animate(
							{height: "toggle"},
							settings.animationSpeed,
							settings.animation,
							function(){
								if ( container !== $this ) {
									$this.update();
								}
							}
						);
					} else {
						$this.update();
						if (shownTweets.length >= ((settings.fetchNum > settings.numStartTweets) ? (settings.numStartTweets) : (settings.fetchNum))) {first = false;}
					}
				}
			}
		}

        function fetchNews() {
			if (tweets.length < 1) {
				$.ajax({
					type: 'GET',
					url: feeds.home.script,
					data: {
						count:			settings.fetchNum,
						timestamp:		newestTweet,
						include_rts:	false
					},
					dataType: 'json',
					success: function(tweetData) {
						if (tweetData != null) {
							if(tweetData.length > 0) {
								// Reset counter
								unsuccessfulCalls = 0;
								// Insert tweets
								$(tweetData).each(function(i, tweet) {
									tweets.push(tweet);
								});
							} else {
								unsuccessfulCalls++;
							}
						}
					}
				});
			}

			//setTimeout(feeds.home.callback, ((unsuccessfulCalls < feeds.home.inactiveAfter || !settings.uniqueOnly) ? (settings.refreshSpeed) : (600000)));
		}

		function fetchHome() {
			if (tweets.length < 1) {
				$.ajax({
					type: 'GET',
					url: feeds.home.script,
					data: {
						count:			settings.fetchNum,
						timestamp:		newestTweet,
						include_rts:	false
					},
					dataType: 'json',
					success: function(tweetData) {
						if (tweetData.length > 0) {
							// Reset counter
							unsuccessfulCalls = 0;
							// Insert tweets
							$(tweetData).each(function(i, tweet) {
								tweets.push(tweet);
							});
						} else {
							unsuccessfulCalls++;
						}
					}
				});
			}

			setTimeout(feeds.home.callback, ((unsuccessfulCalls < feeds.home.inactiveAfter || !settings.uniqueOnly) ? (settings.refreshSpeed) : (600000)));
		}

		function fetchMentions() {
			if (tweets.length < 1) {
				$.ajax({
					type: 'GET',
					url: feeds.mentions.script,
					data: {
						count:			settings.fetchNum,
						timestamp:		newestTweet
					},
					dataType: 'json',
					success: function(tweetData) {
						if (tweetData.length > 0) {
							// Reset counter
							unsuccessfulCalls = 0;
							// Insert tweets
							$(tweetData).each(function(i, tweet) {
								tweets.push(tweet);
							});
						} else {
							unsuccessfulCalls++;
						}
					}
				});
			}

			setTimeout(feeds.mentions.callback, ((unsuccessfulCalls < feeds.mentions.inactiveAfter || !settings.uniqueOnly) ? (settings.refreshSpeed) : (600000)));
		}

		function makeTinyScrollbar() {
			$this.append(
				$(document.createElement("div")).addClass("scrollbar").append(
					$(document.createElement("div")).addClass("track").append(
						$(document.createElement("div")).addClass("thumb").append(
							$(document.createElement("div")).addClass("end")
						)
					)
				)
			);
			$this.append(
				$(document.createElement("div")).addClass("viewport").append(
					$(document.createElement("div")).addClass("overview")
				)
			);
		}

	};

})( jQuery );
