(function ($) {
	
	$.tumblr = function (options) {
		return $.tumblr.impl.init(options);
	};
	
	$.fn.tumblr = function (options) {
		return $.tumblr.impl.init(this, options);
	};
	
	/*
	 * default options
	 */
	$.tumblr.defaults = {
	    viewing:        0,
	    lastLoaded:     0, 
	    count:          1,
	    postsPerPage:   10,
	    threshold:      0,
	    getURL:         'http://pie0.tumblr.com/api/read/json/'
	};
	
	$.tumblr.impl = {
		
		/*
		 * options
		 */
		opts:   null,
		
		/*
		 * helper
		 */
		helper:     {},
		
		/*
		 * is loading
		 */
		isLoading:    false,
		
		/*
		 * Initialize the template
		 */
		init: function (options) {
            
            var self = this;
            
            self.opts = $.extend({}, $.tumblr.defaults, options);
            
            // helpers
            self.helper.pages = $('ul.page-set');
            self.helper.posts = $('ul.post-set');
            
            // selectors
            self.selectors();
            
            // bind the events
            self.events();
            
			return self;
		},
		
		/*
		 * Selectors
		 */
		selectors: function () {
		    
		    var self = this;
		    
		    if (self.helper.posts.children().length == 1)
		        return;
		    
		    self.helper.selectors = $('<ul class="selector-set"></ul>').appendTo('body');
		    
		    for (var i = 0; i < self.opts.count; i++)
		    {
		        var $selector = $('<li class="selector"><a href="#page-' + i + '">' + (self.opts.count - i) + '</a></li>');
		        
		        if (i == 0)
		        {
		            $selector
		                .addClass('selector-enabled')
		                .addClass('selector-active')
		                ;
		        }
		        
		        $selector
		            .appendTo(self.helper.selectors)
		            ;
		    }
		    
		    return;
		},
		
		/*
		 * Binds the events
		 */
		events: function () {
		    
		    var self = this;
		    
		    // post hover
		    self.helper.posts.children().hover(
		        function(){
		            $(this)
		                .addClass('post-hover')
		                ;
		        },
		        function(){
		            $(this)
		                .removeClass('post-hover')
		                ;
		        }
		    );
		    
		    // scroll
		    $(window).scroll(function(){
		        
		        var winH = $(window).height();
		        var end = $(document).height() - winH - $(window).scrollTop();
                
                self.viewing();
                
                if (!self.isLoading && end <= (self.opts.threshold*winH) && (self.opts.lastLoaded + 1) < self.opts.count)
                {
                    self.isLoading = true;
                    self.page();
                }
		    });
		    
		    // selector click
		    self.helper.selectors.find('.selector-enabled a').click(function(e){
		        e.preventDefault();
		        
		        var pageId = $(this).attr('href').split('#')[1];
		        
		        $(window).scrollTo(self.helper.pages.children(pageId), {
	                duration:   1000, 
	            });
		        
		    });
		    
		    // selector click
		    self.helper.selectors.find('.selector a').click(function(e){
		        e.preventDefault();
		    });
		    
		    return;
		},
		
		/*
		 * Determines the page currently within view
		 */
		viewing: function () {
		    
		    var self = this;
		    var fold = $(window).height() + $(window).scrollTop();
		    
		    self.helper.pages.children().each(function(i, item){
		        
		        var offset = $(item).offset().top;
		        var height = $(item).outerHeight();
		        
		        if (fold >= offset && fold <= (offset + height))
		        {
		            if (self.opts.viewing != i)
		            {
		                self.opts.viewing = i;
		                
		                $(self.helper.selectors.children()[self.opts.viewing])
            		        .addClass('selector-active')
            		        .siblings()
            		        .removeClass('selector-active')
            		        ;
		            }
		            		            
		            return false;
		        }
		        
		    });
		    
		    return;
		},
		
		/*
		 * Loads the page
		 */
		page: function () {
		    
		    var self = this;
		    var pageId = 'page-' + (self.opts.lastLoaded + 1);
		    var $page = $('<li class="page" id="' + pageId + '"></li>');
		    var $selector = $(self.helper.selectors.children()[self.opts.lastLoaded + 1]);
		    
		    $selector
		        .addClass('selector-loading')
		        ;
		    
		    $.ajax({
        		url: 			self.opts.getURL, 
    			dataType: 		'jsonp',
    			jsonp_callback: 'jsonp_callback',
    		  	data: {
    				start: 		(self.opts.lastLoaded + 1)*self.opts.postsPerPage,
    				num: 		self.opts.postsPerPage
    			},
    		  	success: function (data) {
    		  		
    		  		var $posts = $('<ul class="post-set"></ul>');
    		  		
    		  		$.each(data.posts, function(i, post){
    		  		    
    		  		    var $post = $('<li class="post"></li>');

    		  		    if (post.type == 'video')
    		  		    {
    		  		        $post
    		  		            .addClass('video')
    		  		            .prepend("<div class='video-player'>" + post['video-player'] + "</a></div>");
                      if(post['video-caption'] != '') $post.append('<div class="content">' + post['video-caption'] + '</div>');
    		  		    }
    		  		    else if (post.type == 'photo')
    		  		    {
    		  		        $post
    		  		            .addClass('photo')
    		  		            .prepend("<span class='photo-box'><a href='" + post['photo-url-500'] + "' class='photo-link'><img src='" + post['photo-url-500'] + "' alt='" + post['photo-caption'] + "' class='photo' /></a><a href='" + post['url-with-slug'] + "' class='linker'>Permalink</a></span>");
                          if (post['photo-caption'] != '') $post.append('<div class="conten caption">' + post['photo-caption'] + '</div>');
    		  		    }
    		  		    else if (post.type == 'link')
    		  		    {
                      $post
                        .addClass('link')
                        .prepend("<h3 class='title'><a href='" + post['link-url'] + "' target='" + post['target'] + "'>" + post['link-text'] + "</a></h3>");
                      if (post['description']) $post.append("<div class='content'>" + post['description'] + "</div>")
    		  		    }
    		  		    else if (post.type == 'audio') {
    		  		      $post
    		  		        .addClass('audio')
    		  		        .prepend(post['audio-player']);
                    if (post['audio-caption']) $post.append("<div class='content'>" + post['audio-caption'] + "</div>")
                  }
                  else if (post.type == 'quote')
                  {
                    $post
                      .addClass('quote')
                      .append("<div class='content'><blockquote>" + post['quote-text'] + "</blockquote></div>");
                    if (post['quote-source"']) $post.find('.content').append('<div class="source">â€” ' + post['quote-source'] + '</div>')
                  }
                  else if (post.type == 'chat')
                  {
                    var chat = '';
                    $.each(post['conversation-lines'], function (line) {
                      chat += "<li class='user_" + line['name'] + "'>"
                      if (line['name'] != '') {
                        chat += line['label'] + "<span class='person'><strong>" + line['name'] + "</strong></span>"
                      }
                      chat += line['phrase'] + "</li>";
                    });
                    
                    $post
                      .addClass('chat');
                    if (post['conversation-title'] != '') {
                      $post.append('<h3 class="title"><a href="' + post['url-with-slug'] + '">' + post['conversation-title'] + '</a></h3>');
                    }
                    $post.append("<div class='content'><ul>" + chat + "</ul></div>");
                  }
                  else if (post.type == 'regular')
                  {
  		  		        $post
  		  		          .addClass('text')
        		  		    .append("<div class='content'>" + post['regular-body'] + "</div>");
        		  		  if (post['regular-title'] != '') $post.prepend("<h3><a href='" + post['url-with-slug'] + "'>" + post['regular-title'] + "</a></h3>");
    		  		    }
    		  		
    		  		    $post.appendTo($posts)
		  		    
		  		        // post hover
            		    $posts.children().hover(
            		        function(){
            		            $(this)
            		                .addClass('post-hover')
            		                ;
            		        },
            		        function(){
            		            $(this)
            		                .removeClass('post-hover')
            		                ;
            		        }
            		    );
    		  		});
    		  		
    		  		$page
    		  		    .append($posts)
    		  		    .appendTo(self.helper.pages)
    		  		    ;
    		  		
    		  		$selector
        		        .removeClass('selector-loading')
        		        .addClass('selector-enabled')
        		        .find('a').click(function(e){
        		            e.preventDefault();
        		            
        		            $(window).scrollTo($page, {
        		                duration:   1000, 
        		            });
        		            
        		        })
        		        ;
    		  		
    		  		self.opts.lastLoaded++;
    		  		self.isLoading = false;
    		  	}
        	});
		    
		    return;
		}
		
	};
})(jQuery);