/*!
 * Live-feed widgets for Twitter and Last.fm
 *
 * Copyright 2010, David Gill
 * http://gilldave.co.uk
 */

var liveFeed = { };

(function () {
    function addFeedItem (item, container, delayIndex, callback) {
        item.hide()
            .appendTo(container)
            .delay(delayIndex * 200)
            .fadeIn(1000, callback);
    }

    function injectFeed(feedName) {
        var feedArea = $(feedName);
        feedArea.find('.loading').fadeOut(500);
        return $('<ul></ul>').appendTo(feedArea);
    }

    liveFeed.lastfm = function (feedName, sourceMethod, limit, defaultImageSrc) {
        function invokeAPI (method, limit, callback) {
            var apiUrl = 'http://ws.audioscrobbler.com/2.0/?method=';
            var fixedApiParams = '&api_key=353c138f8299450e1e81c57a671466fa&format=json&callback=?';
            $.getJSON(apiUrl + method + '&limit=' + limit + fixedApiParams, callback);
        }

        function scrollTrack(scrobbletHolder, track, belt, gap, mainScrollSpeed, loopScrollSpeed) {
            var viewRange = scrobbletHolder.width() - track.position().left;
            var scrollRange = belt.children().width() - viewRange;

            function horizontalScroll () {
                belt.animate({'left': -(scrollRange + gap) + 'px'}, mainScrollSpeed, function () {
                    var childrenClone = belt.children().clone()
                    childrenClone.css('marginLeft', gap + 'px');
                    belt.append(childrenClone);
                    belt.animate({'left': '-=' + (viewRange + gap) + 'px'}, loopScrollSpeed, function () {
                        childrenClone.remove();
                        belt.css('left', 0);
                        setTimeout(horizontalScroll, 1000);
                    });
                });
            }

            if (scrollRange >= 0) {
                track.css('position', 'relative');  // \
                belt.css('position', 'relative');   // -- Needed to fade-in the text in IE
                belt.children().css('marginRight', gap + 'px');
                setTimeout(horizontalScroll, 1000);
            }
        }

        invokeAPI(sourceMethod, limit, function (tracks) {
            var recentTracks = tracks.recenttracks.track;
            recentTracks.length = limit; // truncate otherwise there are limit+1 tracks if one is currently playing.

            var feed = injectFeed(feedName);
            $.each(recentTracks, function (idx) {
                var artistName = this.artist['#text'];
                var trackName = this.name;
                var imageSrc = this.image[1]['#text']; // image[1] for medium

                var albumImage = $('<img src="' + imageSrc + '" alt="' + artistName + '" />');

                // attempt to get an artist image if one was not supplied with the track
                if (imageSrc == '') {
                    albumImage.attr('src', defaultImageSrc);
                    invokeAPI('artist.getimages&artist=' + artistName, 1, function (artists) {
                        if ('image' in artists.images) {
                            imageSrc = artists.images.image.sizes.size[3]['#text']; // size[3] for medium
                            albumImage.attr('src', imageSrc);
                        }
                    });
                }

                var artist = $('<div class="artist"><span>' + artistName + '</span></div>');
                var title = $('<div class="title"><span>' + trackName + '</span></div>');
                var track = $('<div class="track"></div>').append(artist).append(title);
                var scrobblet = $('<div class="scrobblet"></div>')
                    .append(albumImage)
                    .append(track);

                var nowPlaying = '@attr' in this && this['@attr'].nowplaying;
                if (nowPlaying) {
                    scrobblet
                        .addClass('nowplaying')
                        .append('<span class="status">Listening now!</span>');
                }

                var scrobbletHolder = $('<li></li>').appendTo(feed);
                addFeedItem(scrobblet, scrobbletHolder, idx, (idx + 1 < limit) ? null : function () {
                    feed.find('li').each(function () {
                        var track = $(this).find('.track');
                        scrollTrack($(this), track, track.find('.artist'), 20, 5000, 3000);
                        scrollTrack($(this), track, track.find('.title') , 20, 5000, 3000);
                    });
                });
            });
        });
    }

    liveFeed.twitter = function (feedName, screenName, sourceMethod, limit) {
        var url = 'http://api.twitter.com/1/statuses/' + sourceMethod + '.json?screen_name=' + screenName + '&count=' + limit + '&callback=?';
        $.getJSON(url, function (tweets) {
            var feed = injectFeed(feedName);
            $.each(tweets, function (idx) {
                addFeedItem($('<li>' + this.text + '</li>'), feed, idx);
            });

            if (typeof twttr != 'undefined') { // use Twitter Anywhere API, if available
                twttr.anywhere(function (T) {
                    T(feedName).hovercards();
                });
            }
        });
    }
})();
