
var statuses   = [];
var allTweets  = [];
var timer = 0;
var timeFormat;

(function($) {
    /*
    Edited version of jquery.page-realtime-twitter-reactions.js v1.0
    Last updated: 27 April 2010

    Originally created by Chico Charlesworth
    http://blog.niteviva.com/development/realtime-twitter-reactions-using-jquery

    Adapted by Gil Kirschner
    */

    $.fn.getPageRealtimeReactions = function(options) {
        timeFormat = options.timeFormat;

        var o = $.extend({}, $.fn.getPageRealtimeReactions.defaults, options);

        // hide container element
        $(this).hide();
        $(this).html('');

        // add heading to container element
        if (o.showHeading)
            $(this).append('<h4 class="twitterHeader">'+o.headingText+'</h4>');

        // add twitter list to container element
        $(this).append('<ul id="twitter_update_list"></ul>');

        // hide twitter list
        //$("ul#twitter_update_list").hide();

        // add preLoader to container element
        var pl = $('<ul id="loader">'+o.loaderText+'</p>');
        $(this).append(pl);

        // show container element
        $(this).show();

        // twitter search only supports queries up to 130 characters,
        // so call it as many times is needed by splitting up the
        // query into queries of 130 characters or less.
        var searches = o.query.split(" OR ");
        var query = "";
        for (var i=0; i < searches.length; i++) {
            if ((query + " OR " + searches[i]).length < 130) {
                if (i > 0)
                    query += " OR ";
                query += searches[i];
            } else {
                searchTwitter(pl, query, o.numTweets, o.slideIn, false, o.showThumbs);
                query = searches[i];
            }
        }
        searchTwitter(pl, query, o.numTweets, o.slideIn, true, o.showThumbs);
    };

    // plugin defaults
    $.fn.getPageRealtimeReactions.defaults = {
        userName: null,
        numTweets: 5,
        query: "",
        preloaderId: "preloader",
        loaderText: "Loading tweets...",
        slideIn: false,
        showHeading: true,
        headingText: "Latest Tweets",
        showProfileLink: true,
        showThumbs: true
    };

})(jQuery);

function searchTwitter(pl, query, numTweets, slideIn, lastCall, showThumbs) {

    //Update the tweet list using the tweet callback function.
    $.getScript("http://search.twitter.com/search.json?callback=pageRealtimeReactionsCallback&q=" + query + "&rpp=" + numTweets, function() {
        if (lastCall) {
            var status;

            /*
             * If the list of tweets is larger than the allowed number, shorten it to double the maxTweets number.
             * Remove the oldest tweets first.
             * Mark that the tweet list has been changed
             */
            if(allTweets.length > numTweets)
            {
                allTweets.splice(0, allTweets.length - (numTweets));
            }

            //If the tweet list has been changed, clear all the tweets and display a fresh list.
            $('#twitter_update_list').html('');
 
            //Loop through the available tweets
            $.each(allTweets, function(i, tweet){
                if(i >= numTweets)
                {
                    return false;
                }
    
                //Pull out the actual status text
                status = tweet.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>';
                    });
                //If the status us not currently being displayed in the twitter box, add it to the top of the list.
                if($('#twitter_update_list').html().lastIndexOf("</a> : "+status+"</span>") == -1)
                {
                    //If this is the first tweets to be added and the time format is relative, clear the whole list and display fresh, to allow the relative times to update
                    var userThumbTag = '';
                    var userThumbClose = '';
                    var finalClose = '';
                    if(showThumbs == true)
                    {
                        userThumbTag = '<a href="http://twitter.com/'+tweet.from_user+'"><img class="twitterThumb" src="'+tweet.profile_image_url+'" width="40" height="40" /></a><p class="twitter">';
                        userThumbClose = '</p><div class="twitter">';
                        finalClose = '</div>';
                    }
                    //Create the whole string of the twitter comment
                    var realtimeReaction = '<li class="twitter">'+userThumbTag;
                    realtimeReaction += '<a href="http://twitter.com/'+tweet.from_user+'">';
                    realtimeReaction += '<strong>'+tweet.from_user+'</strong></a> : '+status+userThumbClose;
                    realtimeReaction += '<a href="http://twitter.com/'+tweet.from_user+'">' + absoluteDate(tweet.created_at) + '</a>'+finalClose+'</li>';
                    //Add it to the top of the tweet list.
                    $('#twitter_update_list').prepend(realtimeReaction);
                }
            });

            // remove preLoader from container element
            $(pl).remove();

            // show twitter list
            if (slideIn) 
                $("ul#twitter_update_list").slideDown(1000);
            else 
                $("ul#twitter_update_list").show();
            

            // give first list item a special class
            $("ul#twitter_update_list li:first").addClass("top");

            // give last list item a special class
            $("ul#twitter_update_list li:last").addClass("last");
        }
    });
}

function pageRealtimeReactionsCallback(response) {
    var tweets = response.results;
    tweets.reverse();
    var i;

    //Loop through all the new tweets received
    $.each(tweets, function(i, tweet) {

        //Pull out the actual status text
        var status = tweet.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>';
            });

        //Calculate the created date, unique to this tweet
        var date = new Date((tweet.created_at || "").replace(/-/g,"/").replace(/[TZ]/g," "));

        //Check if we have got this combination of status text and date already being displayed
        if($.inArray(status+date.getTime(), statuses) == -1)
        {
            //If not add this tweet to the list of tweets to be displayed
            allTweets.push(tweet);
            statuses.push(status+date.getTime());
        }
    });
}

// absoluteDate function editted from prettyDate
function absoluteDate(time){

    //if the time is relative use the prettyDate function
    if(timeFormat == 'relative')
        return prettyDate(time);

    //if no time is given, leave a blank value.
    if (!time)
        return "";

    //calculate the js Date object from the given time
    var date = new Date((time || "").replace(/-/g,"/").replace(/[TZ]/g," "));

    if(timeFormat == 'short')   // format to 13:10 Mon 10 Jan 10
        return twoDigit(date.getHours())+':'+twoDigit(date.getMinutes())+' '+dayText(date.getDay(),'short')+' '+date.getDate()+' '+monthText(date.getMonth(), 'short')+' '+twoDigit(date.getFullYear()%100);
    if(timeFormat == 'long')    // format to 13:10 Monday 10 January 2010
        return twoDigit(date.getHours())+':'+twoDigit(date.getMinutes())+' '+dayText(date.getDay(),'long')+' '+date.getDate()+' '+monthText(date.getMonth(), 'long')+' '+date.getFullYear();
    if(timeFormat == 'numeric') // format to 13:10 10/01/10
        return twoDigit(date.getHours())+':'+twoDigit(date.getMinutes())+' '+twoDigit(date.getDate())+'/'+twoDigit((date.getMonth()+1))+'/'+twoDigit(date.getFullYear()%100);

    return '';
}

//Gets the textual version of the month in short or long versions
function monthText(day, type)
{
    switch(day)
    {
        case 0:
            if(type == 'short')
                return 'Jan';
            return 'January';
        case 1:
            if(type == 'short')
                return 'Feb';
            return 'February';
        case 2:
            if(type == 'short')
                return 'Mar';
            return 'March';
        case 3:
            if(type == 'short')
                return 'Apr';
            return 'April';
        case 4:
            return 'May';
        case 5:
            if(type == 'short')
                return 'Jun';
            return 'June';
        case 6:
            if(type == 'short')
                return 'Jul';
            return 'July';
        case 7:
            if(type == 'short')
                return 'Aug';
            return 'August';
        case 8:
            if(type == 'short')
                return 'Sep';
            return 'September';
        case 9:
            if(type == 'short')
                return 'Oct';
            return 'October';
        case 10:
            if(type == 'short')
                return 'Nov';
            return 'November';
        case 11:
            if(type == 'short')
                return 'Dec';
            return 'December';
    }
}

//gets a textual version of the Day name
function dayText(day, type)
{
    switch(day)
    {
        case 0:
            if(type == 'short')
                return 'Sun';
            return 'Sunday';
        case 1:
            if(type == 'short')
                return 'Mon';
            return 'Monday';
        case 2:
            if(type == 'short')
                return 'Tue';
            return 'Tuesday';
        case 3:
            if(type == 'short')
                return 'Wed';
            return 'Wednesday';
        case 4:
            if(type == 'short')
                return 'Thu';
            return 'Thursday';
        case 5:
            if(type == 'short')
                return 'Fri';
            return 'Friday';
        case 6:
            if(type == 'short')
                return 'Sat';
            return 'Saturday';
    }
}

//Adds the leading '0' to numeric representations of hour, minute, second, day and month
function twoDigit(text)
{
    text = ''+text;
    if(text.length == 1)
        return '0'+text;
    return text;
}

// prettyDate function borrowed from http://ejohn.org/files/pretty.js :)
function prettyDate(time){
    if (!time)
        return "sometime ago";

    var date = new Date((time || "").replace(/-/g,"/").replace(/[TZ]/g," ")),
        diff = (((new Date()).getTime() - date.getTime()) / 1000),
        day_diff = Math.floor(diff / 86400);

    if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 )
        return "sometime ago";

    return day_diff == 0 && (
        diff == 1 && "just now" ||
        diff < 60 && Math.floor(diff) + "seconds ago" ||
        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") ||
        day_diff == 1 && "Yesterday" ||
        day_diff < 7 && day_diff + " days ago" ||
        day_diff == 7 && " 1 week ago" ||
        day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago";
}

