(function($) {
    
    var settings = {
        getNews: true,
        getBlog: true,
        getTwitter: true,
        gotNews: false,
        gotBlog: false,
        gotTwitter: false,
        newsUrl: '/ssi/select_news/index.html',
        blogUrl: '/ssi/select_blog/index.html',
        twitterUrl: '/ssi/select_twitter/index.html',
        twitterAvatar: '',
        newsAvatar: '',
        blogAvatar: '',
        avatarWidth: 60,
        avatarHeight: 60,
        forceNewsAvatar: true,
        forceBlogAvatar: true,
        forceTwitterAvatar: true,
        minNews: 0,
        minBlog: 0,
        minTwitter: 0,
        ignoreTwitterReplies: true,
        showShareButtons: true,
        count : 5, // how many items to return
        twitterTemplate : '<div class="listeditem feeditem twitteritem twocol_left clearfix"><div class="img"><a href="http://twitter.com/#{screenName}/"><img src="#{profileImageUrl}" height="#{avatarHeight}" width="#{avatarWidth}" alt="#{screenName}" title="#{screenName}" /></a></div><div class="txt"><p class="type">#{feedType}</p><p class="teaser">#{text}</p><p class="date"><span>#{createdAt}</span> (<a  href="http://twitter.com/intent/tweet?in_reply_to=#{id}">Reply</a>) (<a  href="http://twitter.com/intent/retweet?tweet_id=#{id}">RT</a>)</span></p><div class="fs-share-wrapper clearfix"><div class="fs-share-fb"><fb:share-button class="url" href="http%3A%2F%2Ftwitter.com%2F%23!%2F#{screenName}%2Fstatus%2F#{id}" type="button_count"></fb:share-button></div></div></div></div>',
        newsBlogTemplate : '<div class="listeditem feeditem newsblogitem twocol_left clearfix"><div class="img"><a href="#{storyUrl}"><img src="#{teaserImageUrl}" height="#{teaserImageHeight}" width="#{teaserImageWidth}" alt="#{title}" title="#{title}" /></a></div><div class="txt"><p class="type">#{feedType}</p><h3 class="title"><a href="#{storyUrl}">#{title}</a></h3><div class="teaser">#{teaser} <a href="#{storyUrl}">Read more &#187;</a></div><p class="date">#{coverDate}</p><div class="fs-share-wrapper clearfix"><div class="fs-share-fb"><fb:share-button class="url" href="#{storyUrl}" type="button_count"></fb:share-button></div><div class="fs-share-twitter"><a href="http://twitter.com/share" data-url="#{storyUrl}" data-text=#{title}" class="twitter-share-button">Tweet</a></div></div></div></div>'
    };
    
    $.fn.feedSelect = function(options) {
        if (options) {
            $.extend(settings, options);
        }
        
        return this.each(function() {
            feedSelect(this);
        });
    };
    
    function feedSelect(container) {
        var combinedFeed = [];

        if (settings.getNews) {
            $.getJSON(settings.newsUrl, function(json) {
                $.each(json, function(i, item) {
                    item.feedType = 'News';
                    combinedFeed.push(item);
                });
                settings.gotNews = true;
            });
        }

        if (settings.getBlog) {
            $.getJSON(settings.blogUrl, function(json) {
                $.each(json, function(i, item) {
                    item.feedType = 'Blog';
                    combinedFeed.push(item);
                });
                settings.gotBlog = true;
            });
        }
        if (settings.getTwitter) {
            var dataType = 'json';
            if (settings.twitterUrl.match('twitter\.com')) {
                dataType = 'jsonp';
            }
            $.ajax({
                url: settings.twitterUrl,
                dataType: dataType,
                type: 'GET',
                success: function(json) {
                    settings.twitterResultsObject = (typeof json.results === 'undefined') ? false : true;
                    $.each((settings.twitterResultsObject ? json.results : json), function(i, item) {
                        item.feedType = 'Twitter';
                        item.hasResultsObject = settings.twitterResultsObject;
                        item.cover_date_epoch = epochTime(item.created_at);
                        combinedFeed.push(item);
                    });
                    settings.gotTwitter = true;
                }
            });
        }

        buildHTML(container, combinedFeed);
    }
        
    function buildHTML(container, combinedFeed) {
        var timeoutId;
        var countNews = 0, countBlog = 0, countTwitter = 0;
        var skipNews = false, skipBlog = false, skipTwitter = false;
        var numReserved = settings.minNews + settings.minBlog + settings.minTwitter;
        var numLeft = settings.count;
        
        if ((settings.getNews == settings.gotNews) && (settings.getBlog == settings.gotBlog) && (settings.getTwitter == settings.gotTwitter)) {
            if ((settings.gotNews === false) && (settings.gotBlog === false) && (settings.gotTwitter === false)) {
                $(container).html('<p><strong>Please check one of the checkboxes to display content in this section.</strong></p>');
                return;
            }
            if (combinedFeed.length === 0 ) {
                $(container).html('<p><strong>No content exists for the categories you have selected.</strong></p>');
            }
            combinedFeed.sort(function(a, b) {
                return b.cover_date_epoch - a.cover_date_epoch;
            });
            
            $.each(combinedFeed, function(i, item) {
                if (i === 0) {
                    $(container).empty();
                }
                if ((item.feedType === 'Twitter') && (settings.ignoreTwitterReplies === true)) {
                    if (item.text.charAt(0) === '@') {
                        return true;
                    }
                }
                if (numLeft <= 0) {
                    return false;
                }
                
                // assume all checkboxes are checked
                if ((numReserved > 0) && (numReserved === numLeft)) {
                    if (settings.minTwitter === 0) {
                        skipTwitter = true;
                    } else if ((settings.minTwitter > 0) && (countTwitter >= settings.minTwitter)) {
                        skipTwitter = true;
                    }
                    if (settings.minNews === 0) {
                        skipNews = true;
                    } else if ((settings.minNews > 0) && (countNews >= settings.minNews)) {
                        skipNews = true;
                    }
                    if (settings.minBlog === 0) {
                        skipBlog = true;
                    } else if ((settings.minBlog > 0) && (countBlog >= settings.minBlog)) {
                        skipBlog = true;
                    }
                }
                
                // but sometimes they aren't, so...
                // case 1: 1 has a min, and it's unchecked
                if ((settings.minTwitter > 0) && (settings.getTwitter === false)) {
                    if ((settings.minNews == 0) && (settings.minBlog == 0)) {
                        skipNews = false;
                        skipBlog = false;
                     }
                 }
                if ((settings.minNews > 0) && (settings.getNews === false)) {
                    if ((settings.minTwitter == 0) && (settings.minBlog == 0)) {
                        skipTwitter = false;
                        skipBlog = false;
                     }
                 }
                if ((settings.minBlog > 0) && (settings.getBlog === false)) {
                    if ((settings.minNews == 0) && (settings.minTwitter == 0)) {
                        skipNews = false;
                        skipTwitter = false;
                     }
                 }
                 
                 // case 2: 1 has a min, and it's the only one checked
                 if ((settings.minTwitter > 0) && (settings.getTwitter === true)) {
                    if ((settings.getNews === false) && (settings.getBlog === false)) {
                        skipTwitter = false;
                     }
                 }
                 if ((settings.minNews > 0) && (settings.getNews === true)) {
                    if ((settings.getTwitter === false) && (settings.getBlog === false)) {
                        getNews = false;
                     }
                 }
                 if ((settings.minBlog > 0) && (settings.getBlog === true)) {
                    if ((settings.getNews === false) && (settings.getTwitter === false)) {
                        skipBlog = false;
                     }
                 }
                 
                 /* NOTE: we might want to redo all of this. Perhaps we satisfy the minimums first, then loop thru
                    the rest until we get our count, then order that array. */
               
                var itemHtml = '';
                if ((item.feedType == 'Twitter') && !skipTwitter) {
                    itemHtml = template(settings.twitterTemplate, {
                        feedType: item.feedType,
                        screenName : item.hasResultsObject ? item.from_user : item.user.screen_name,
                        avatarHeight : settings.avatarHeight,
                        avatarWidth : settings.avatarWidth,
                        profileImageUrl : (settings.twitterAvatar ? settings.twitterAvatar : item.user.profile_image_url),
                        createdAt : localTimeFromEpoch(item.cover_date_epoch),
                        id : item.id_str,
                        text : formatText(item.text),
                        plainText : item.text,
                        encodedText : encodeURIComponent(item.text)
                    });
                    countTwitter++;
                    numLeft--;
                } else if ((item.feedType == 'News') && !skipNews) {
                    var newsImgUrl = '';
                    var usingNewsAvatar = true;
                    if (settings.newsAvatar && settings.forceNewsAvatar) {
                        newsImgUrl = settings.newsAvatar;
                    } else if (settings.newsAvatar && !!!item.teaser_image_url) {
                        newsImgUrl = settings.newsAvatar;
                    } else if (item.teaser_image_url) {
                        newsImgUrl = item.teaser_image_url;
                        usingNewsAvatar = false;
                    }
                    itemHtml = template(settings.newsBlogTemplate, {
                        feedType: item.feedType,
                        title : item.title,
                        encodedTitle: encodeURIComponent(item.title),
                        storyUrl: item.story_url,
                        encodedStoryUrl: encodeURI(item.story_url),
                        coverDate: localTimeFromEpoch(item.cover_date_epoch),
                        teaser: $.trim(item.teaser).replace(/&lt;/g, '<').replace(/&gt;/g, '>'),
                        altTeaser: $.trim(item.alt_teaser).replace(/&lt;/g, '<').replace(/&gt;/g, '>'),
                        teaserImageUrl: newsImgUrl,
                        teaserImageHeight: (usingNewsAvatar ? settings.avatarHeight : item.teaser_image_height),
                        teaserImageWidth: (usingNewsAvatar ? settings.avatarWidth : item.teaser_image_width)
                    });
                    countNews++;
                    numLeft--;
                } else if ((item.feedType == 'Blog') && !skipBlog) {
                    var blogImgUrl = '';
                    var usingBlogAvatar = true;
                    if (settings.blogAvatar && settings.forceBlogAvatar) {
                        blogImgUrl = settings.blogAvatar;
                    } else if (settings.blogAvatar && !!!item.teaser_image_url) {
                        blogImgUrl = settings.blogAvatar;
                    } else if (item.teaser_image_url) {
                        blogImgUrl = item.teaser_image_url;
                        usingBlogAvatar = false;
                    }
                    itemHtml = template(settings.newsBlogTemplate, {
                        feedType: item.feedType,
                        title : item.title,
                        encodedTitle: encodeURIComponent(item.title),
                        storyUrl: item.story_url,
                        encodedStoryUrl: encodeURI(item.story_url),
                        coverDate: localTimeFromEpoch(item.cover_date_epoch),
                        teaser: $.trim(item.teaser).replace(/&lt;/g, '<').replace(/&gt;/g, '>'),
                        altTeaser: $.trim(item.alt_teaser).replace(/&lt;/g, '<').replace(/&gt;/g, '>'),
                        teaserImageUrl: blogImgUrl,
                        teaserImageHeight: (usingBlogAvatar ? settings.avatarHeight : item.teaser_image_height),
                        teaserImageWidth: (usingBlogAvatar ? settings.avatarWidth : item.teaser_image_width)
                    });
                    countTwitter++;
                    numLeft--;
                }

                $(container).append(itemHtml);

                if (settings.showShareButtons === true) {
                    $.ajax({ url: 'http://platform.twitter.com/widgets.js', dataType: 'script', cache:true});
                    window.fbApiInitialized && FB.XFBML.parse();
                } else {
                    $('.fs-share-wrapper').hide();
                }

            });
            if (timeoutId) {
                clearTimeout(timeoutId);
            }
            
            // reinitialize
            settings.gotNews = false;
            settings.gotBlog = false;
            settings.gotTwitter = false;
            settings.twitterAvatar = '';
        } else {
            timeoutId = setTimeout(function() { buildHTML(container, combinedFeed); }, 500);
        }
    }
    
    function formatText(txt) {
        var exp = /(\b(https?|ftp|file):\/\/[\-A-Z0-9+&@#\/%?=~_|!:,.;]*[\-A-Z0-9+&@#\/%=~_|])/ig;
        txt = txt.replace(exp, '<a href="$1" class="external">$1</a>');
        exp = /[\@]+([A-Za-z0-9-_]+)/ig;
        txt = txt.replace(exp, '<a href="http://twitter.com/$1" class="profile">@$1</a>');
        exp = /[\#]+([A-Za-z0-9-_]+)/ig;
        
        return txt;
    }
    
    function epochTime(dateStr) {
        if ($.browser.msie) {
            dateStr = dateStr.replace(' +0000', '') + ' UTC';
        }
        var dt = new Date(Date.parse(dateStr));
        return dt.valueOf() / 1000;
    }
    
    function localTimeFromEpoch(secs) {
        var dt = new Date(secs * 1000);
        return strftime('%B %d, %Y %l:%M %p', dt);
    }
    
    function template(string, values) {
        var pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
        while (match = string.match(pattern)) {
            string = string.replace(new RegExp(match[2], 'g'), values[match[3]]);
        }
        return string;
    }

    function strftime(format, date, locale) {
        if (!date ) {
            date = new Date(); // default to today
        }
        if (format == 'pretty') {
            return vanilla.pretty_date(date);
        }
        if (!locale) {
            locale = 'en';
        }
        var A_values, B_values;
        if (locale == 'en') {
            A_values = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
            B_values = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 
                        'September', 'October', 'November', 'December'];
        } else if (locale == 'es') {
            A_values = ['Domingo','Lunes','Martes','MiÃ©rcoles','Jueves','Viernes','SÃ¡bado'];
            B_values = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto',
                        'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];
        }

        var pattern = /%(a|A|b|B|d|m|M|H|l|p|P|y|Y)/;
        while (match = format.match(pattern)) {
            var repl;
            switch (match[1]) {
                case 'a' : repl = A_values[date.getDay()].substr(0,3); break;
                case 'A' : repl = A_values[date.getDay()]; break;
                case 'b' : repl = B_values[date.getMonth()].substr(0,3); break;
                case 'B' : repl = B_values[date.getMonth()]; break;
                case 'd' : repl = date.getDate(); break;
                case 'H' : repl = date.getHours(); break;
                case 'l' : repl = date.getHours(); if ( repl > 12 ) { repl = repl % 12; } break;
                case 'm' : repl = date.getMonth() + 1; break;
                case 'M' : repl = date.getMinutes(); if ( repl < 10 ) { repl = '0' + repl; } break;
                case 'p' : repl = (date.getHours() >= 12) ? 'pm' : 'am'; break;
                case 'P' : repl = (date.getHours() >= 12) ? 'PM' : 'AM'; break;
                case 'y' : repl = (date.getFullYear() + '').substr(2); break;
                case 'Y' : repl = date.getFullYear(); break;
            }
            format = format.replace(RegExp(match[0], 'g'), repl);
        }
        return format;
    }
    
})(jQuery);

