(function($){
    // plugin initialization
    $.fn.feedviewer = function(o){
        var feedviewer = this;
        if (feedviewer.length==0) { return feedviewer; }
        
        // Initialize options for this call
        feedviewer.options = $.extend({
            url : null,
            showTitles : true,
            showDescriptions : true,
            showDates : true,
            showShare : true,
            showThumbnails : true,
            showSeparator : true,
            separatorColor: '#F2F2F2',
            showImages : true,
            truncate : true,
            numEntires : null,
            shareOptions: null,
            showHtml: true
        },o);
        
        function getFeedErrorHtml() {
            return '<div class="feed-error"> \
                No Content Available \
            </div>';
        }

        // Setup
        feedviewer.addClass("tp_feedviewer");
        // Don't show spinner if items already exists as this is a background update
        if (feedviewer.find('.feedspace').length < 1) {
            feedviewer.html('<div style="text-align:center; margin-top:20%; margin-bottom:60%;"><img src="'+$.imageUrl('img/tsclock.gif')+'" style="width:32px;display:block;margin:10px auto 0 auto;" /></div>');
        }
        
        
        // Get feed items we need to render
        $.serviceCall("/transponder/feed/json?u="+escape(feedviewer.options.url), null, function(data){ // for encoding info see: http://xkr.us/articles/javascript/encode-compare
            
            // Exit early if we have no new data
            if (data.items.length < 1 || data.items.length == feedviewer.find('.feedspace').length) {
                return;
            }
            
            var numEntires = feedviewer.options.numEntires;
            if  ((numEntires == null) || (data.items.length < numEntires)) {
                numEntires = data.items.length;
            }

            feedviewer.html( (numEntires) ? '' : getFeedErrorHtml() );
            
            for (var i=0;i<numEntires;i++) {
                var item = data.items[i];
                
                var itemContent = (feedviewer.options.showHtml) ? item.content : item.clean_content;
                var template = $('<div class="feedspace"><table><tr><td class="thumbnailimage"></td><td class="feeditem"><div class="feedinfo"><a href="'+item.link+'" target="_blank" class="title">'+item.title+'</a><div class="poststamp"><p class="date mediatitle">'+item.date+'</p></div><div class="ts_clearfix"></div></div><div class="feedcontent">'+itemContent+'</div><div class="tagline"><img class="fullarticletoggle" src="'+$.imageUrl("/img/expand_collapse.jpg")+'" /><div class="sharelink"></div><div class="ts_clearfix"></div></div></td></tr></table></div>');
                
                // Titles
                if (!feedviewer.options.showTitles) {
                    template.find(".title").hide();
                }

                // Descriptions
                if (!feedviewer.options.showDescriptions) {
                    template.find(".feedcontent").hide();
                    template.find(".fullarticletoggle").hide();
                }
                
                // Dates
                if (item.date == null || !feedviewer.options.showDates) {
                    template.find(".date").hide();
                }
                
                // External Links
                template.find(".feedcontent").find("a").attr("target","_blank").css("display","inline");
                
                // Full article toggle
                var readToggle = function(e){
                    var elem = $(this);
                    var itemElement = e.data;
                    var gaEngagementLabel = "";
                    
                    if (!itemElement.hasClass("expanded")) {
                        feedviewer.find(".expanded").removeClass("expanded");
                        itemElement.addClass("expanded");
                        itemElement.find(".feedcontent").find("object").show();
                        itemElement.find(".feedcontent").find("embed").show();
                        itemElement.find(".feedcontent").find("iframe").show();
                        if (feedviewer.options.showImages) {
                            itemElement.find(".feedcontent").find("img").show();
                        }
                        gaEngagementLabel = 'Expand Content';
                    } else {
                        feedviewer.find(".expanded").removeClass("expanded");
                        itemElement.find(".feedcontent").find("img").hide();
                        itemElement.find(".feedcontent").find("object").hide();
                        itemElement.find(".feedcontent").find("embed").hide();
                        itemElement.find(".feedcontent").find("iframe").hide();
                        gaEngagementLabel = 'Contract Content';
                    }
                    
                    $.galog.engagement('feed', gaEngagementLabel);
                    return false;
                };
                
                // Truncate event
                if (feedviewer.options.truncate) {
                    template.find(".feedcontent").find("img").hide();
                    template.find(".feedcontent").find("object").hide();
                    template.find(".feedcontent").find("embed").hide();
                    template.find(".feedcontent").find("iframe").hide();
                    template.find(".fullarticletoggle").bind("click",template,readToggle);
                } else {
                    template.addClass("expanded");
                    template.find(".fullarticletoggle").hide();
                    if (!feedviewer.options.showImages) {
                        template.find(".feedcontent").find("img").hide();
                    }
                }
                
                // Thumbnail Image
                if (feedviewer.options.showThumbnails) {
                    var imageUrl = null;
                    for (var x=0,elen=item.extended_items.length;x<elen;x++) {
                        imageUrl = item.extended_items[x].thumbnails[0];
                        break;
                    }

                    if (imageUrl != null && imageUrl.indexOf("googleusercontent.com") == -1) {
                        template.find(".thumbnailimage").html('<img src="'+imageUrl+'" alt="" />');
                    } else {
                        template.find(".thumbnailimage").hide();
                    }
                }
            
                // Share
                if (feedviewer.options.showShare) {
                    // Initialize options for this call
                    var shareOptions = $.extend({
                        url : item.link,
                        title : item.title,
                        description : item.bullet
                    },feedviewer.options.shareOptions);
                    
                    if (imageUrl != null && imageUrl.indexOf("googleusercontent.com") == -1) { // darwin: what is googleusercontent.com? some explanation would be nice here
                        shareOptions.images = [
                            {
                                "src" : imageUrl,
                                "href" : item.link
                            }
                        ];
                    }
                    
                    // apply placeholder replacement to all string-type fields in sharing options
                    for (var field in shareOptions) {
                        if (!shareOptions.hasOwnProperty(field)) continue;
                        if (typeof shareOptions[field]!="string") continue;
                        shareOptions[field] = shareOptions[field]
                            .replace("{itemtitle}",item.title)
                            .replace("{itemshortdescription}",item.bullet)
                            .replace("{itemdescription}",item.summary)
                            .replace("{itemlink}",item.link);
                    }
                    template.find(".sharelink").share(shareOptions);
                }
                
                // Border
                if (feedviewer.options.showSeparator && i < (numEntires-1)) {
                    template.find("table").css("border-bottom-width","1px");
                }
                if (feedviewer.options.separatorColor) {
                    template.find("table").css("border-color", feedviewer.options.separatorColor);
                }
                
                // Links for nokia
                if ($.currentPlatform() == 'nokia') {
                    if (window.widget) {
                        template.find("a").bind("click",function(){
                            var self = $(this);
                            if (self.attr("href").indexOf("http") > -1) {
                                window.widget.openURL(self.attr("href"));
                            }
                        });
                    
                    }
                }
                
                // Append 
                feedviewer.append(template);
            }
        });
        
        return feedviewer;
    };
    
})(jQuery);