/**
 * Create namespaces
 */
if (typeof Nimbus === 'undefined') {
    Nimbus = {};
}
if (typeof Nimbus.widgets === 'undefined') {
    Nimbus.widgets = {};
}

Nimbus.widgets.Twitter = (function() {
    var my = {},
        element,
        options;

    my.init = function(selector) {
        element = $(selector);

        if (!element.length) {
            return;
        }

        options = {
            username: element.data('username'),
            count: element.data('count') ? element.data('count') : 3,
            separator: element.data('separator') ? element.data('separator') : '&mdash;',
            includeRts: element.data('include-rts').toLowerCase() === 'true' ? 'true' : 'false'
        }

        if (!options.username) {
            element.append('<p>No username found. Please configure your twitter account in the admin dashboard.</p>');
            return;
        }

        this.loadTweets();
    };

    my.loadTweets = function() {
        var uri = 'https://api.twitter.com/1/statuses/user_timeline.json'
                + '?include_entities=true&include_rts=' + options.includeRts
                + '&screen_name=' + options.username
                + '&count=' + options.count.toFixed()
                + '&callback=Nimbus.widgets.Twitter.displayTweets',
            loadTimeout;

        element.addClass('loading');

        $.ajax({
            url: uri,
            dataType: 'jsonp',
            success: function(data) {
                element.removeClass('loading');
                my.displayTweets(data);
            },
            timeout: 8000,
            error: function(response, status, error) {
                element.removeClass('loading');
                if (response.status !== 200) { // yes, the 'error' callback gets called upon successful completion. thanks jQuery. 
                    element.append('<p class="load-error">Error loading Twitter content.</p>');
                }
            }
        });
    };
           
    my.displayTweets = function(data) {
        var list = element.find(".nb-widget-tweets");

        element.removeClass('loading');
        element.find("p.load-error").remove();

        for (i in data) {
            list.append($("<li></li>").html(formatTweet(data[i])));
        }
    };

    var formatTweet = function(data) {
        var formatLinks = function(t) {
            for (i in data.entities.urls) {
                var u = data.entities.urls[i];
                // filter out mal-formed urls
                if (u.expanded_url && u.display_url) {
                    t = t.replace(u.url, '<a href="'+u.expanded_url+'">'+u.display_url+'</a>');
                }
            }
            return t;
        }

        var formatMentions = function(t) {
            for (i in data.entities.user_mentions) {
                var m = data.entities.user_mentions[i];
                t = t.replace('@'+m.screen_name, '<a href="http://twitter.com/'+m.screen_name+'">@'+m.screen_name+'</a>');
            }
            return t;
        }

        var formatHashes = function(t) {
            for (i in data.entities.hashtags) {
                var h = data.entities.hashtags[i];
                t = t.replace('#'+h.text, '<a href="http://twitter.com/search?q=%23'+h.text+'">#'+h.text+'</a>');
            }
            return t;
        }

        var tweetLink = function() {
            return 'http://twitter.com/' + data.user.screen_name + '/statuses/' + data.id_str;
        }

        var formattedDate = function() {
            // tweet 'created_at' comes in formatted like "Tue Oct 04 19:02:06 +0000 2011"
            // regex source: http://stackoverflow.com/a/2766516/212443
            var date = new Date(
                data.created_at.replace(/^\w+ (\w+) (\d+) ([\d:]+) \+0000 (\d+)$/,
                    "$1 $2 $4 $3 UTC"));

            var hour = date.getHours();
            var ampm = hour < 12 ? ' am' : ' pm';
            if (hour > 12) {
                hour -= 12;
            }
            if (hour == 0) {
                hour = 12;
            }
            var minutes = date.getMinutes();
            if (minutes < 10) {
                minutes = '0' + minutes;
            }

            return date.toDateString().substr(0, 10) + ' ' + hour + ':' + minutes + ampm;
        }

        return formatHashes(formatMentions(formatLinks(data.text))) + ' '
               + options.separator
               + ' <a href="' + tweetLink() + '">' + formattedDate() + '</a>';
    }

    return my;
})();

/**
 * DOM ready actions
 */
$(document).ready(function() {
    Nimbus.widgets.Twitter.init('.nb-widget-twitter');
});

