﻿/// <reference path="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.4.3-vsdoc.js" />

// See http://daringfireball.net/2010/07/improved_regex_for_matching_urls
var url_regexp = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/gi;

function Trace(msg) {
    try {
        if (window.console)
            console.log(msg);
    } catch (e) {
    }
}

function getParameterByName(name)
{
      name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
      var regexS = "[\\?&]" + name + "=([^&#]*)";
      var regex = new RegExp(regexS);
      var results = regex.exec(window.location.href);
      if(results == null)
        return "";
      else
        return decodeURIComponent(results[1].replace(/\+/g, " "));
}

var TwitterWidget = {
    reloadInterval: null,
    template: null,
    ids: new Array(),
    tweets: new Array(),
    screenName: null,
    interval: 30,
    twitterUrl: "twitter.com",
    twitterApiUrl: "api.twitter.com",
    twitterSearchUrl: "search.twitter.com",
    Reload: function () {
        Trace('Updating times on ' + TwitterWidget.tweets.length + ' tweets...');
        for (var j = 0; j < TwitterWidget.tweets.length; j++) {
            var tweetItem = TwitterWidget.tweets[j];
            var twtElement = $('#' + tweetItem.tweet_id);
            Trace('Updating time for tweet ' + tweetItem.tweet_id);

            tweetItem.tweet_relative_time = TwitterWidget.RelativeTime(tweetItem.tweet_time);

            var time = twtElement.find('.time');
            if (time.length > 0)
                Trace('Found time field, updating....');
            else
                Trace('Time field not found for id ' + tweetItem.tweet_id);

            twtElement.find('.time a').html(tweetItem.tweet_relative_time);
            twtElement.find('.time a').attr('href', 'http://twitter.com/#!/Gatwick_Airport/status/' + tweetItem.tweet_id);
        }

        Trace('loading new tweets...');
        try {
            if (getParameterByName("uselocal").length) {
                Trace('Detected uselocal, bypassing live api, using local api');
                $.ajax({
                    url: "/resources/code/json/api.ashx?op=gettwitterfeed",
                    success: function (data) {
                        TwitterWidget.OnFeedLoad(data);
                    },
                    error: function (d, msg) {
                        // Failed
                        if (TwitterWidget.tweets.length == 0) {
                            Trace('Local proxy call failed' + msg + ', displaying unavailable message');
                            $('ol.tweets').hide();
                            $('#tweetsError').show();
                        }
                    }
                });
            } else {
                $.jsonp({
                    "url": 'http://api.twitter.com/1/statuses/user_timeline.json?screen_name=' + TwitterWidget.screenName + '&count=3&callback=?',
                    "success": function (data) {
                        TwitterWidget.OnFeedLoad(data);
                    },
                    "error": function () {
                        // Fallback to use our server proxy
                        Trace('Primary call failed, using local proxy');
                        $.ajax({
                            type: "POST",
                            url: "/resources/code/json/api.ashx?op=gettwitterfeed",
                            data: { count: 3 },
                            success: function (data) {
                                TwitterWidget.OnFeedLoad(data);
                            },
                            error: function (d, msg) {
                                // Failed
                                if (TwitterWidget.tweets.length == 0) {
                                    Trace('Local proxy call failed' + msg + ', displaying unavailable message');
                                    $('ol.tweets').hide();
                                    $('#tweetsError').show();
                                }
                            }
                        });
                    }
                });
            }
        } catch (e) {
            Trace(e);
        }
    },
    Init: function (interval, username, startupData) {
        $.ajaxSetup({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            data: "{}",
            dataType: "json",
            dataFilter: function (data) {
                var msg;

                if (typeof (JSON) !== 'undefined' &&
                typeof (JSON.parse) === 'function')
                    msg = JSON.parse(data);
                else
                    msg = eval('(' + data + ')');

                if (msg.hasOwnProperty('d'))
                    return msg.d;
                else
                    return msg;
            }
        });

        if (TwitterWidget.interval > 30)
            TwitterWidget.interval = interval;

        TwitterWidget.screenName = username;
        var w = this;
        w.template = $('<li class="tweetInfoTemplate">' +
            '<div class="tweetInfoInner">' +
                '<div class="tweetText"></div>' +
                '<div class="tweetDetails">' +
                    '<span class="time"><a href="" target="_blank"></a></span>' +
                    '<span class="timestamp"></span>' +
                    '<span class="separator">&nbsp;-&nbsp;</span>' +
                    '<a href="" class="reply" target="_blank">reply</a>' +
                    '<span class="separator">&nbsp;-&nbsp;</span>' +
                    '<a href="" class="retweet" target="_blank">retweet</a>' +
                '</div>' +
            '</div>' +
        '</li>');

        // Load our tweet data objects based on what has already been rendered
        $.each(startupData, function (i, item) {
            var tweetItem = TwitterWidget.BuildTweetDataItem(item);
            Trace(tweetItem);
            w.tweets.push(tweetItem);
            w.ids.push(tweetItem.tweet_id);
        });

        var schedule = (TwitterWidget.interval * 1000);

        reloadInterval = setInterval("TwitterWidget.Reload()", schedule);
        TwitterWidget.Reload();
    },
    OnFeedLoad: function (data) {
        $('#tweets').show();
        $('#tweetsError').hide();
        Trace('loaded!');

        var newTweets = new Array();

        $.each(data, function (i, item) {
            var isNew = true;

            for (var x = 0; x < TwitterWidget.ids.length; x++) {
                if (item.id_str == TwitterWidget.ids[x]) {
                    isNew = false;
                    break;
                }
            }

            if (isNew) {
                Trace('Building new tweet ' + item.id_str);
                var tweet = TwitterWidget.BuildTweetDataItem(item);
                TwitterWidget.ids.push(tweet.tweet_id);
                TwitterWidget.tweets.push(tweet);
                newTweets.push(tweet);
                if (TwitterWidget.tweets.length > 3)
                    TwitterWidget.tweets.shift();
            } else {
                Trace('No new tweets');
            }
        });

        // Sort by most recent
        TwitterWidget.tweets.sort(function (tweet1, tweet2) {
            return tweet1["tweet_time"] - tweet2["tweet_time"];
        });
        newTweets.sort(function (tweet1, tweet2) {
            return tweet1["tweet_time"] - tweet2["tweet_time"];
        });

        $(newTweets).each(function(i, tweet) {

            if ($('#twitter .tweets li').length > 2) {
                $('#twitter .tweetInfo').last().fadeOut('slow', function() {
                    $(this).remove();
                });
            }

            var t = TwitterWidget.template.clone();
            t.attr('id', tweet.tweet_id);
            t.css('display', 'none');
            t.attr('class', 'tweetInfo');
            t.find('.tweetText').html(tweet.tweet_text.toString());
            t.find('.time a').html(tweet.tweet_relative_time);
            t.find('.time a').attr('href', 'http://twitter.com/#!/Gatwick_Airport/status/' + tweet.tweet_id);
            t.find('.timestamp').html(tweet.tweet_time);
            t.find('.reply').attr('href', tweet.reply_url);
            t.find('.retweet').attr('href', tweet.retweet_url);
            Trace('Adding new tweet (' + tweet.tweet_id + ')');
            $('#twitter .tweets').prepend(t);

            // Apply tracking
            t.find('.time a').click(function() {
                if (_gaq)
                    _gaq.push(['_trackpageview', 'vpv/goal/engaged-visit/twitter'], ['_trackEvent', 'useful-exits', 'Twitter', 'VIEW-STATUS']);
            });
            t.find('.reply').click(function() {
                if (_gaq)
                    _gaq.push(['_trackpageview', 'vpv/goal/engaged-visit/twitter'], ['_trackEvent', 'useful-exits', 'Twitter', 'STATUS-REPLY']);
            });
            t.find('.retweet').click(function() {
                if (_gaq)
                    _gaq.push(['_trackpageview', 'vpv/goal/engaged-visit/twitter'], ['_trackEvent', 'useful-exits', 'Twitter', 'STATUS-RETWEET']);
            });

            t.fadeIn('slow', function() {
                t.animate({ backgroundColor: '#ffffff' }, 1000);
            });
        });
    },
    // Convert twitter API objects into our data objects ready for display
    BuildTweetDataItem: function (item) {
        var o = {};
        o.item = item;
        o.source = item.source || '';
        o.screen_name = item.from_user || item.user.screen_name || '';
        o.avatar_url = item.profile_image_url || item.user.profile_image_url || '';
        o.retweet = typeof (item.retweeted_status) != 'undefined';
        o.tweet_time = TwitterWidget.ParseDate(item.created_at);
        o.tweet_id = item.id_str || item.tweet_id;
        o.twitter_base = "http://" + TwitterWidget.twitterUrl + "/";
        o.user_url = o.twitter_base + o.screen_name;
        o.tweet_url = o.user_url + "/status/" + o.tweet_id;
        o.reply_url = o.twitter_base + "intent/tweet?in_reply_to=" + o.tweet_id;
        o.retweet_url = o.twitter_base + "intent/retweet?tweet_id=" + o.tweet_id;
        o.favorite_url = o.twitter_base + "intent/favorite?tweet_id=" + o.tweet_id;
        o.retweeted_screen_name = o.retweet && item.retweeted_status ? item.retweeted_status.user.screen_name : '';
        o.tweet_relative_time = TwitterWidget.RelativeTime(o.tweet_time);
        o.tweet_raw_text = o.retweet && item.retweeted_status ? ('RT @' + o.retweeted_screen_name + ' ' + item.retweeted_status.text) : item.text; // avoid '...' in long retweets
        o.tweet_text = TwitterWidget.MakeUrl(o.tweet_raw_text);
        o.tweet_text = TwitterWidget.LinkUser(o.tweet_text);
        o.tweet_text = TwitterWidget.LinkHash(o.tweet_text);

        return o;
    },
    ParseDate: function (dateStr) {
        // The non-search twitter APIs return inconsistently-formatted dates, which Date.parse
        // cannot handle in IE. We have to perform the following transformation:
        // "Wed Apr 29 08:53:31 +0000 2009" => "Wed, Apr 29 2009 08:53:31 +0000"
        return Date.parse(dateStr.replace(/^([a-z]{3})( [a-z]{3} \d\d?)(.*)( \d{4})$/i, '$1,$2$4$3'));
    },
    RegexReplace: function (text, regex, replacement) {
        var returning = [];
        returning.push(text.toString().replace(regex, replacement));
        return $(returning);
    },
    MakeUrl: function (text) {
        return TwitterWidget.RegexReplace(text, url_regexp, function (match) {
            var url = (/^[a-z]+:/i).test(match) ? match : "http://" + match;
            return "<a href=\"" + url + "\" target=\"_blank\" onclick=\"_gaq.push(['_trackpageview', 'vpv/goal/engaged-visit/twitter'], ['_trackEvent', 'useful-exits', 'Twitter', 'IN-TWEET-LINK']);\">" + match + "</a>";
        })[0];
    },
    LinkUser: function (text) {
        return TwitterWidget.RegexReplace(text, /@(\w+)/gi, "@<a href=\"http://" + TwitterWidget.twitterUrl + "/$1\" target=\"_blank\" onclick=\"_gaq.push(['_trackpageview', 'vpv/goal/engaged-visit/twitter'], ['_trackEvent', 'useful-exits', 'Twitter', 'USERNAME']);\">$1</a>")[0];
    },
    LinkHash: function (text) {
        return TwitterWidget.RegexReplace(text, /(?:^| )[\#]+([\w\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u00ff\u0600-\u06ff]+)/gi,
              "<a href=\"http://" + TwitterWidget.twitterSearchUrl + "/search?q=&tag=$1&lang=all\" target=\"_blank\" onclick=\"_gaq.push(['_trackpageview', 'vpv/goal/engaged-visit/twitter'], ['_trackEvent', 'useful-exits', 'Twitter', 'HASHTAG']);\">#$1</a>")[0];
    },
    RelativeTime: function (date) {
        var relativeTo = new Date();
        var delta = parseInt((relativeTo.getTime() - new Date(date)) / 1000, 10);
        var r = '';
        if (delta < 60) {
            r = delta + ' seconds ago';
        } else if (delta < 120) {
            r = 'a minute ago';
        } else if (delta < (45 * 60)) {
            r = (parseInt(delta / 60, 10)).toString() + ' minutes ago';
        } else if (delta < (2 * 60 * 60)) {
            r = '1 hour ago';
        } else if (delta < (24 * 60 * 60)) {
            r = '' + (parseInt(delta / 3600, 10)).toString() + ' hours ago';
        } else if (delta < (48 * 60 * 60)) {
            r = 'a day ago';
        } else {
            r = (parseInt(delta / 86400, 10)).toString() + ' days ago';
        }
        return r;
    }
};

