var TWEETS_PER_PAGE = 20;
var loader = '<img width="16" style="padding: 0; width: 16px; height: 16px;" src="/images/small_loader.gif"/>';
var GAME_MODE_UPCOMING = 'upcoming';
var GAME_MODE_ARCHIVED='archived';
var GAME_MODE_WARMUP='warmup';
var GAME_MODE_FIGHT='fight';
var GAME_MODE_FINISHED='finished';
var Languages = {'en':'english','fr':'french'};

TweetQueue=function(container, height, spy, stream){
    this.items=[];
    this.delay=1000; //todo 1000
    this.timeout=undefined;
    this.height = height;
    this.container = container;
    this.spy = spy;
    this.unob_update = typeof(stream.unob_update)!='undefined' && stream.unob_update;
};

TweetQueue.prototype.start=function(){
    if(!this.timeout){
        this.schedule();
    }
};

TweetQueue.prototype.stop=function(){
    if(this.timeout){
        clearTimeout(this.timeout);
        this.timeout=undefined;
    }
};

TweetQueue.prototype.pause=function(){
    if(this.timeout){
        this.stop();
        return true;
    }
}

TweetQueue.prototype.play=function(){
    if(!this.timeout){
        this.start();
        return false;
    }
}

TweetQueue.prototype.pause_toggle=function(){
    if(this.timeout){
        this.stop();
        return true;
    }
    else{
        this.start();
        return false;
    }
};

TweetQueue.prototype.restart=function(){
    this.stop();
    this.schedule();
};

TweetQueue.prototype.schedule=function(){
    var t=this;
    this.timeout=setTimeout(function(){
        t.schedule();
        t.update();
    } ,this.delay);
};

TweetQueue.prototype.update=function(){
    if (this.unob_update)
        return;
    var scroll_offset='-'+this.height+'px';
    if($('.streams-body > .tweet', this.container).size()>TWEETS_PER_PAGE){
        /*$('.streams-body > .tweet:last', this.container).fadeOut(200,function(){
            $(this).next('.tweethsep').remove();
            $(this).remove();
        });*/
        var el = $('.streams-body > .tweet:last', this.container);
        $(el).next('.tweethsep').remove();
        $(el).remove();
    }

    var item=this.items.shift();
    if(item){
        var element=$(".streams-update > #"+item, this.container);
        if (element.length > 0)
        {
            $('.streamscroll', this.container).css('top',scroll_offset);
            $('.streams-body', this.container).prepend(element.html());
            //make sure there is enough room for the tweets as they fall down
            MAX_TWEET_WIDTH = 760;
            queue = this;
            $('.streams-body', this.container).each(function(eindex,element){
                element=$(element);
                if (eindex>TWEETS_PER_PAGE)
                    return;
                //game
                if (queue.competing_queue)
                {
                    var parallel_element = $('.streams-body', queue.competing_queue.container).eq(eindex);
                    if (!parallel_element)
                        return; //todo test this. Its returning without adding 'ready' class
                    var this_pos = parseInt(element.attr('pos'));
                    var parallel_pos = parseInt(parallel_element.attr('pos'));
                    if (queue.pos > 50)
                        parallel_pos = (100-this_pos);
                    else if ((parallel_pos + this_pos)!=100) {
                        parallel_pos = queue.competing_queue.pos;
                        this_pos = (100 - parallel_pos);
                    }
                    //Adjust the parallel tweet
                    var new_width = parseInt(MAX_TWEET_WIDTH*(parallel_pos)/100);
                    var cur_width = parallel_element.css('width');
                    if ((new_width+'px') != cur_width){
                         parallel_element.animate({width: new_width+'px'}, {duration: 1500, queue: "global"});
                        $('.innerbox', parallel_element).animate({width: (new_width - 6)+'px'}, {duration: 1500, queue: "global"});
                        $('.letsfighttxt1', parallel_element).animate({width: (new_width - 6 - 65 - 90 - 41)+'px'}, {duration: 1500, queue: "global"});
                        var shift_dir = (queue.competing_queue.pos > 50)? -1:1;
                        if (queue.index_other==2 && queue.competing_queue.pos!=50)
                            parallel_element.animate({marginLeft: shift_dir*(MAX_TWEET_WIDTH*(1.0*queue.competing_queue.pos/100-0.5))+'px'},
                                                            {duration: 1500, queue: "global"});
                    }
                }

                element.addClass('ready');
            });
            $('.streamscroll', this.container).animate({top:0},{duration: 600, queue: "global"},'easeInOutQuad');
            element.remove();
            ////resize_twitts_containers();
        }
    }

    //if (this.items.length==0) this.pause(); //stop after inserting the init data
};

//shows newer tweets on user request. no animation
TweetQueue.prototype.showNew = function() {
    if (this.items.length > 0)
    {
        var item=this.items.shift();
        while(item)
        {
            var element=$(".streams-update > #"+item, this.container);
            if (element.length > 0)
            {
                $('.streams-body', this.container).prepend(element.html());
                element.remove();
            }
            item=this.items.shift();
        }
    }            
            
    this.items = [];

    /*var elements = $(".streams-update > div", this.container);
    if (elements.length > 0)
    {
        var q = this;
        $('.streams-update > div', this.container).each(function(eindex,element){
            element=$(element);
            $('.streams-body', q.container).prepend(element.html());
            element.remove();
        });
        //resize_twitts_containers();
    }
    }*/

   $('.new-tweets', this.container).hide();
   $('.new-tweets-count', this.container).text('0');
   //resize_twitts_containers();
};

//returns the last tweet id in this tweet stream
TweetQueue.prototype.getLastTweetTime = function() {
    var last = $('.streams-body div.tweet:last', this.container);
    if (last.length > 0) return last.attr('unixtime');
    return 0;
};

TweetQueue.prototype.add=function(id){
    this.items.push(id);
};

TweetQueue.prototype.clear_timeline=function(){
    this.items = [];
    this.fresh = true;
    //$('.streamscroll', this.container).html('');
    $('.new-tweets', this.container).hide();
};



var TweetSpy=function(streams, url, init, cur_page, query_string){
    this.streams = streams;
    this.queues = new Array();
    for (var i in this.streams)
    {
        this.queues[i] = new TweetQueue(this.streams[i].selector, this.streams[i].height, this, this.streams[i]);
        //game
        if (i=='parent1' || i=='parent2')
            this.queues[i].pos = this.streams[i].game.pos;
    }
    //Set each other pointers
    for (var i in this.queues[i])
    {
        //game
        if (i=='parent1')
            this.queues[i].competing_queue = this.queues['parent2'];
        //game
        if (i=='parent2')
            this.queues[i].competing_queue = this.queues['parent1'];
    }
    this.cur_page = (cur_page)? cur_page:1;
    this.init = true;
    this.auto_refresh = typeof(init.auto_refresh)=='undefined' || init.auto_refresh;
    
    this.fresh = false; //will be set to true if the tweets are being fetched in pagination or language change
    this.more_tweets = false; //will be set to true when user clicks "more"
    this.delay=25000; //todo 25000
    this.timeout=undefined;
    this.url=url;
    this.user_request = false;
    this.last_request = false;
    this.query_string = query_string;

    //do initial population
    this.tweetsHandler(init);
};

TweetSpy.prototype.start=function(){
    if(!this.timeout){
        if (this.cur_page==1)
            this.schedule();
        for (var i in this.queues)
            this.queues[i].start();
    }
};

TweetSpy.prototype.stop=function(){
    if(this.timeout){
        clearTimeout(this.timeout);
        this.timeout = undefined;
        if (this.last_request!=false)
            this.last_request.abort();
        for (var i in this.queues)
            this.queues[i].stop();
    }
};


TweetSpy.prototype.restart=function() {
    $.fn.fancybox.showLoading();
    this.clear_timeline();

    this.stop();

    if (this.cur_page==1)   //todo can show updates in pages > 1?
        this.schedule();
    this.update(null, true);
    for (var i in this.queues)
        this.queues[i].restart();
};

TweetSpy.prototype.clear_timeline=function(){
    this.fresh = true;
    //this.since = 0;
    for (var i in this.queues)
    {
        this.queues[i].clear_timeline();
        //this.streams[i].max_tweet_time = 0;
        this.streams[i].since = 0;
    }
};

TweetSpy.prototype.schedule=function(){
    var t=this;
    if (this.auto_refresh && this.cur_page == 1)
    {
        this.timeout=setTimeout(function(){
            t.schedule();
            t.update(null, true);
        },this.delay);
    }
};

TweetSpy.prototype.invalidate=function(url){
    this.url = url;
    this.fresh = true;
    this.restart();
};

TweetSpy.prototype.update = function(streams, is_timer){
    var t=this;
    //hold on the timer, till the user initiated refresh has finished
    if (is_timer && t.user_request)
        return false;
    //cancel any timer requests, in case of user requested operations
    if (t.last_request!=false)
        t.last_request.abort();
    t.user_request = t.fresh;

    if (streams != null)
    {
        $.fn.fancybox.showLoading();
    }
    else
        streams = t.streams;    //update all streams
    
    $('#loading').show();
    t.last_request = $.post(t.url+"?"+t.query_string, {streams: streams, page: t.cur_page}, function(datas) {
        t.tweetsHandler(datas);
    }, "json");
};

//game
TweetSpy.prototype.gameStats = function(datas) {
    if ((typeof(datas.results.parent1) != 'undefined' || typeof(datas.results.parent2) != 'undefined'))
    {
        //state will be available in both team datas, but will be a common value
        //if (datas.results.parent1.game.state != GAME_MODE_UPCOMING )
        {
            if (datas.results.parent1.game.state == GAME_MODE_WARMUP ||
                datas.results.parent1.game.state == GAME_MODE_UPCOMING)
            {
                datas.results.parent1.game.pos = datas.results.parent2.game.pos = 50;
                datas.results.parent1.game.num_tweets = datas.results.parent1.game.total;          //todo warmup
                datas.results.parent2.game.num_tweets = datas.results.parent2.game.total;
            }
            var left_width = parseInt(158/50*datas.results.parent1.game.pos);
            var right_width = 316-left_width;
            $('#matchbar1').removeClass().addClass('matchbar '+ datas.results.parent1.game.band);
            $('#matchbar1').animate({width: left_width+'px'}, {duration: 1500, queue: "global"});
            $('#matchbar1 .num').html(datas.results.parent1.game.num_tweets);   //todo warmup num_total??

            $('#matchbar2').removeClass().addClass('matchbar '+ datas.results.parent2.game.band);
            $('#matchbar2').animate({width: right_width+'px'}, {duration: 1500, queue: "global"});
            $('#matchbar2 .num').html(datas.results.parent2.game.num_tweets);   //todo warmup num_total??
        }
        this.queues['parent1'].pos = datas.results.parent1.game.pos;
        this.queues['parent2'].pos = datas.results.parent2.game.pos;
    }

    return datas;
}

TweetSpy.prototype.tweetsHandler = function(datas) {
    //game
    datas = this.gameStats(datas);
    
    tweetSpy = this;
    var tweet;
    for (var i in datas.results)
    {
        var data = datas.results[i];
        var since_parsed = data.max_tweet_time;

        //do this only for auto updates
        if(!isNaN(since_parsed) && !tweetSpy.more_tweets)        //!tweetSpy.user_request &&
        {
            tweetSpy.streams[i].since =since_parsed;
            //var d = new Date(since_parsed*1000);
            //$('#last_updated_at').text(d.getHours() + ":" + d.getMinutes());
        }

        var container = null;
        //user initiated refresh or page navigation
        if (tweetSpy.user_request)  //change to t.fresh if it didn't work
        {
            //if no more tweets exist, hide the more tweets link
            if (data.more_exists)
                $('.all-twitts-tab-bottom', $(tweetSpy.queues[i].container)).show();
            else
                $('.all-twitts-tab-bottom', $(tweetSpy.queues[i].container)).hide();

            if (!tweetSpy.more_tweets)
                $('.streams-body', $(tweetSpy.queues[i].container)).html('');
            //tweetSpy.queues[i].clear_timeline();
            //unwrap the tweet and append to the end of container
            for (tweet in data['tweets'])
                $('.streams-body', $(tweetSpy.queues[i].container)).append($(data['tweets'][tweet]).find('.tweet'));

            //resize_twitts_containers();

            $("#fancy_loading").hide();
            //break; //uncomment this if response contains other streams
        }
        //show animation for the first time
        else if (tweetSpy.init)
        {
            data['tweets'].reverse(); //sort by oldest first

            container = $(tweetSpy.streams[i].selector);

            for (tweet in data['tweets'])
                $('.streams-update', container).prepend(data['tweets'][tweet]);

            $('.streams-update > div:not(.ready)', tweetSpy.streams[i].container).each(function(eindex,element){
                element=$(element);
                element.addClass('ready');
                tweetSpy.queues[i].add(element.attr('id'));
            });

            //if no more tweets exist, hide the more tweets link
            if (data.more_exists)
                $('.all-twitts-tab-bottom', $(tweetSpy.queues[i].container)).show();
            else
                $('.all-twitts-tab-bottom', $(tweetSpy.queues[i].container)).hide();
        }
        //Just update the count
        else if (data.tweets.length > 0)
        {
            data['tweets'].reverse(); //sort by oldest first
            
            container = $(tweetSpy.streams[i].selector);

            //game
            //Update column's class based on the win position'
            if (typeof(datas.results[i].game) != 'undefined')
            {
                var state = (datas.results[i].game.pos >= 50)? 'winner':'loser';
                var other_state = (state=='loser')? 'winner':'loser';
                if (!container.hasClass(state)) {
                    container.removeClass(other_state);
                    container.addClass(state);
                }
            }

            for (tweet in data['tweets'])
            {
                $('.streams-update', container).prepend(data['tweets'][tweet]);
                tweetSpy.queues[i].add($(data['tweets'][tweet]).attr('id'));
            }

            container.find('.new-tweets').show();
            var num_new = parseInt(container.find('.new-tweets-count').text()) + data.tweets.length;
            container.find('.new-tweets-count').text(num_new);
            container.find('.new-tweets-label').text((num_new==1)? 'new tweet':'new tweets');
            //container.find('.new-tweets').slideDown(1000, resize_twitts_containers);
        }
    }
    tweetSpy.last_request = false;
    tweetSpy.fresh = false;
    tweetSpy.more_tweets = false;
    tweetSpy.user_request = false;
    tweetSpy.init = false;
    //Do jQuery init here for components like slideshow etc
    $('#loading').hide();
};

TweetSpy.prototype.showNew = function(stream) {
    this.queues[stream].showNew();
    return false;
};

//load and show more tweets at the bottom of stream
TweetSpy.prototype.moreTweets = function(stream_key) {
    var stream = jQuery.extend({}, this.streams[stream_key]);
    stream.cur_page = 1;
    stream.max_time = this.queues[stream_key].getLastTweetTime();
    stream.since = 0;   //unsetting since time
    stream.cur_page = 1; //page # is always 1
    //update only this stream
    this.fresh = true;
    this.more_tweets = true;
    var streams = new Object();
    streams[stream_key] = stream;
    this.update(streams, false);
    return false;
};

TweetSpy.prototype.pause=function(){
    for (var i in this.queues)
        toggle = this.queues[i].pause();
    return toggle;
};

TweetSpy.prototype.play=function(){
    for (var i in this.queues)
        toggle = this.queues[i].play();
    return toggle;
};

TweetSpy.prototype.pause_toggle=function(){
    for (var i in this.queues)
        toggle = this.queues[i].pause_toggle();
    return toggle;
};

TweetSpy.prototype.toggle_players_filter=function(){
    this.only_links = !this.only_links;    
    $.cookie(this.cookie_name, this.only_links, {'expires': 10000, 'path' : '/'});
    //unset the twitter max id
    //this.query_string = this.query_string.replace(/twitter_max_id=[0-9]*?/, '') + '&twitter_max_id=0';
    this.restart();
};

function toggleFall(anchor, spy)
{
    if ($(anchor).text()=='Play')
    {
        spy.play();
        $(anchor).text('Pause');
    }
    else
    {
        spy.pause();
        $(anchor).text('Play');
    }
    return false;
}


jQuery.extend(jQuery.easing,{
    def:'easeOutQuad',
    easeInOutQuad:function(x,t,b,c,d){
        if((t/=d/2)<1)return c/2*t*t+b;return-c/2*((--t)*(t-2)-1)+b;
    }
});

TweetSpy.prototype.foottweet_toggle=function(){
    var only = $.cookie('only_foottweet')=='true';
    only = !only;
    $.cookie('only_foottweet', only, {'expires': 10000, 'path' : '/'});
    $('.btnonlyft img').attr('src', only? '/images/checked.png':'/images/unchecked.png')
    //reset the page to first one
    this.cur_page = 1;
    this.restart();
};
