﻿/// <reference path="jquery-1.3.2-vsdoc2.js"/>

(function($) {
    var item = null;
    var avatarSize = null;
    var displaySource = null;

    $.fn.Twitter = function(options) {
        var opts = $.extend({}, $.fn.Twitter.defaults, options);

        return this.each(function() {
            item = $(this);

            _appendSection(item, opts.headerText, "header");
            item.append('<div id="' + item[0].id + '_contents"></div>');
            _appendSection(item, opts.footerText, "footer");

            _appendSection(item.find("#" + item[0].id + "_contents"), opts.loadingText, "loading");

            avatarSize = opts.avatarSize;
            displaySource = opts.appendSource;

            _getFeed(item, opts);
        });
    };

    $.fn.Twitter.defaults = {
        username: "",
        loadingText: "Loading...",
        headerText: "",
        footerText: "",
        avatarSize: false,
        itemCount: 5,
        appendSource: true
    };

    function _appendSection(item, stringVal, stringType) {
        if (stringVal != "")
            item.append('<div id="' + item[0].id + '_' + stringType + '">' + stringVal + '</div>');
    }

    function _getFeed(item, options) {
        if (options.username != "") {
            $.getJSON("http://twitter.com/statuses/user_timeline/" + options.username + ".json?count=" + options.itemCount + "&callback=?", function(data) {
                _loadFeed(data);
            });
        } else {
            _displayError("The Username parameter is required.");
        }
    }

    function _loadFeed(data) {
        if (data != null) {
            _displayFeed(data);
        }
    }

    function _displayError(error) {
        _clearLoading();
        _appendSection(item.find("#" + item[0].id + "_contents"), error, "error");
    }

    function _displayFeed(data) {
        var list = $('<ul id="' + item[0].id + '_contents_list">');
        var user = data[0].user;
        var userImage = $('<img src="' + user.profile_image_url + '" alt="' + user.screen_name + '\'s avatar">');

        for (var i = 0; i < data.length; i++) {
            var listItem = $('<li>');
            var dataItem = data[i];
            var userImageCopy = userImage.clone().height(avatarSize).width(avatarSize);
            var byLine = $('<span id="' + item[0].id + '_contents_list_byline">Posted ' + _prettyDate(dataItem.created_at) + '</span>');

            if (displaySource) {
                byLine.append(" from " + dataItem.source);
            }

            listItem.append(userImageCopy);
            listItem.append(_makeLinks(dataItem.text) + "<br/>");
            listItem.append(byLine);
            list.append(listItem);
        }

        _clearLoading();
        item.find("#" + item[0].id + "_contents").append(list);
    }

    function _clearLoading() {
        $("#" + item[0].id + "_contents_loading").remove();
    }

    function _makeLinks(text) {
        return text.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/, function(str) {
            return str.link(str);
        });
    }

    function _prettyDate(date) {
        var prettyDate = null;
        var uglyDate = _parseDate(date);
        var currentDate = new Date();

        var diff = Math.abs(((currentDate.getTime() - uglyDate.getTime()) / 1000));
        var dateDiff = Math.floor(diff / 86400);

        return dateDiff == 0 && (
			diff < 60 && "just now" ||
			diff < 120 && "1 minute ago" ||
			diff < 3600 && Math.floor(diff / 60) + " minutes ago" ||
			diff < 7200 && "1 hour ago" ||
			diff < 86400 && Math.floor(diff / 3600) + " hours ago") ||
		dateDiff == 1 && "Yesterday" ||
		dateDiff < 7 && dateDiff + " days ago" ||
		Math.ceil(dateDiff / 7) + " weeks ago";
    }

    function _parseDate(date) {
        var dateParts = date.split(" ");

        var itemDate = new Date();
        itemDate.setFullYear(dateParts[5], _parseMonth(dateParts[1]), dateParts[2]);
        itemDate = _parseTime(dateParts[3], itemDate);

        return itemDate;
    }

    function _parseMonth(month) {
        switch (month) {
            case "Jan":
                return 0;
            case "Feb":
                return 1;
            case "Mar":
                return 2;
            case "Apr":
                return 3;
            case "May":
                return 4;
            case "Jun":
                return 5;
            case "Jul":
                return 6;
            case "Aug":
                return 7;
            case "Sep":
                return 8;
            case "Oct":
                return 9;
            case "Nov":
                return 10;
            case "Dec":
                return 11;
        }
    }

    function _parseTime(time, date) {
        var timeParts = time.split(":");

        date.setHours(timeParts[0]);
        date.setMinutes(timeParts[1]);
        date.setMilliseconds(timeParts[2]);

        return date;
    }
})(jQuery);