﻿(function(jQuery) {

    jQuery.fn.twitter = function(options) {

        var opts = $.extend({}, $.fn.twitter.defaults, options);

        var timeline = 'http://twitter.com/statuses/user_timeline/' + opts.user + '.json';

        // a in AJAX == aysyncronous, hence 'this' has vanished by the time of the callback. Use 'sender' for closure;
        var sender = this;

        showLoader(sender);

        $.get(timeline, { count: opts.tweets_to_pull }, function(data) {

            var tweets = extractData(data);
            if (tweets.length > 0) {
                showTweets(sender, tweets, opts.show_status_link);
            }
        }, "jsonp");

        return this;
    };

    jQuery.fn.twitter.defaults =
    {
        user: 'HughJampton',
        tweets_to_pull: 5,
        show_status_link: true
    };


    function showLoader(sender) {

        sender.each(function() {

            $this = $(this);

            $this.empty();

            var div = $this.append('<div></div>').find('div');
            div.css('width', '100%');
            div.css('height', '100%');
            div.css('position', 'relative');


            var img = div.append('<img>').find('img:last');
            img.attr('src', '/Content/images/ajax-loader.gif');
            img.css('position', 'absolute');
            img.css('top', '55%');
            img.css('left', '40%');
        });
    }

    function showTweets(sender, tweets, showStatusLink) {

        sender.each(function() {

            $this = $(this);

            $this.empty();

            var list = $this.append('<ol></ol>').find('ol');

            for (var i = 0; i < tweets.length; i++) {

                var tweet = tweets[i];

                var listItem = list.append('<li></li>').find('li:last');

                var span = listItem.append('<span></span>').find('span');
                span.html(tweet.status);

                var link = listItem.append('<a class="status"></a>').find('a:last');
                link.html(tweet.time);
                link.attr('href', tweet.statusUrl);
            }

            $this.find("a").click(function() {
                $(this).attr("target", "_blank");
            });

            $this.fadeIn(500);
        });
    }

    function extractData(data) {

        var twitters = new Array();

        for (var i = 0; i < data.length; i++) {

            twitters.push({
                status: extractStatus(data[i]),
                time: extractTime(data[i]),
                statusUrl: extractStatusUrl(data[i]),
                userUrl: extractUserUrl(data[i])
            });
        }

        return twitters;
    }

    function extractUserName(twitter) {
        return twitter.user.screen_name;
    }

    function extractStatus(twitter) {
        return twitter.text.replace(/((https?|s?ftp|ssh)\:\/\/[^"\s\<\>]*[^.,;'">\:\s\<\>\)\]\!])/g, function(url) {
            return '<a href="' + url + '">' + url + '</a>';
        }).replace(/\B@([_a-z0-9]+)/ig, function(reply) {
            return reply.charAt(0) + '<a href="http://twitter.com/' + reply.substring(1) + '">' + reply.substring(1) + '</a>';
        });
    }

    function extractUserUrl(twitter) {
        return "http://twitter.com/" + extractUserName(twitter);
    }

    function extractStatusUrl(twitter) {
        return extractUserUrl(twitter) + "/statuses/" + twitter.id;
    }

    function extractTime(twitter) {
        return toRelativeTime(twitter.created_at);
    }

    function toRelativeTime(time_value) {

        var values = time_value.split(" ");
        time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
        var parsed_date = Date.parse(time_value);
        var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
        var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
        delta = delta + (relative_to.getTimezoneOffset() * 60);

        if (delta < 60) {
            return 'less than a minute ago';
        } else if (delta < 120) {
            return 'about a minute ago';
        } else if (delta < (60 * 60)) {
            return (parseInt(delta / 60)).toString() + ' minutes ago';
        } else if (delta < (120 * 60)) {
            return 'about an hour ago';
        } else if (delta < (24 * 60 * 60)) {
            return 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
        } else if (delta < (48 * 60 * 60)) {
            return '1 day ago';
        } else {
            return (parseInt(delta / 86400)).toString() + ' days ago';
        }
    }

    //
    // end of closure
    //
})(jQuery);