/**
 * @projectDescription Code and widgets for building lists of discussions.
 * @author             James Skinner
 * @version            0.1
 */

(function() { // closure to prevent namespace pollution

  /**
   * Simpler function which allows us to get data from any server by
   * wrapping it in a Javascript function 
   * @param {String} jsonSource Path to load file.
   * @param {String} jsonCallback Name of function defined in remote file which returns the data.
   * @param {Number} numberOfItems Number of discussions to pass to callback.
   * @param {Function} callback Method to pass final Discussion list to.
   */
  function loadFeedFile(opt, callback) {
    //jQuery.bmj.log("Loading %d items from JSON file at %s", opt.numberOfItems, opt.source);
    
    window[opt.callback] = function(data) {
      //jQuery.bmj.log("%s: received %d items", opt.callback, data.length);
      var disclist = data.slice(0, opt.numberOfItems);
      callback(disclist);
    }
    
    var url = opt.source + "?callback=?";
    jQuery.getJSON(url, function(d) { });
  }

  /*
   * Note: if closedContentGroups is true, then use forumKeys to call ForumDiscussionPage,
   * otherwise use groupKeys and the standard CommunityGroupRecentForumDiscussions call.
   */
  var defaultOptions = {
    title: "Latest discussions",
    blurb: "",
    customCss: "",
    showLogo: false,
    useAjax: false,
    showMoreItems: true,
    moreItemsUrl: "/forums.html",
    moreItemsText: "More discussions",
    numberOfItems: 8,
    dataSource: document.location.host,
    dataFile: null,
    callback: null,
    debug: false,
    ageOfItems: 15,
    showAuthor: false,
    showAvatar: false,
    stripeRows: true,
    linkTarget: ""
  };
  
  /*
   * Include a new latest discussions widget into the selected node e.g.
   *
   *   jQuery("#discussions").feedWidget({
   *     widgetTitle: "Recent clinical posts",
   *     dataSource: "doc2doc.bmj.com",
   *     dataFile: "clinical.js",
   *     callback: "displayClinical"
   *   });
   */
  jQuery.fn.feedWidget = function(options) {
    var self = this, opt = jQuery.extend({}, defaultOptions, options);
    opt.source = "http://{dataSource}/server/{dataFile}".fmt(opt),
    //console.dir(opt);
    
    // Build widget on each matched element.
    this.each(function() {
      // Generate body of discussions widget.

      jQuery(this)
        .append(jQuery.bmj.runTemplate("feed", opt))
        .find(".feed-items")
          .addClass("loading");
          
      if (opt.showLogo) {
        jQuery(".widget-header", this).css({
          background: "url(http://doc2doc.bmj.com/images/logo-small.gif) top right no-repeat",
          minHeight: "38px"
        });
      }

      if (opt.useAjax) {
        jQuery("h2", this)
          .addClass("expandable-header icon-open")
          .bind("click.feed", function(e) {
            jQuery(e.target)
              .toggleClass("icon-open").toggleClass("icon-closed")
            	.next().slideToggle();
          });
      }
    });
    
    var expandedState = true, images = [opt.iconOpen, opt.iconClose], disps = ["none", "block"];
    
    // Do request and process results.
    function displayDiscussions(discussions) {
      jQuery(".feed-items", self).removeClass("loading");
      
      function cutto(s, l) {
        return s.length > l ? (s.substr(0, l - 3) + "...") : s; 
      }
      
      /**
       * Replaces <br> tags with line breaks, </p> tags with two line breaks, replaces entities
       * and finally strips all remaining tags and returns the result.
       * @param {String} Initial HTML string.
       * @return {String} Formatted and stripped text.
       */
      function stripHtml(s) {
        var text = s.replace(/<br\s*\/?>/gi, "\n").replace(/<\/p>/gi, "\n\n").replace(/<[^>]*?>/gi, "");
        return text.replace(/&nbsp;/gi, " ").replace(/&amp;/gi, "&").replace(/&lt;/gi, "<").replace(/&gt;/gi, ">");
          //.replace(/&[lr]\w?quo;/gi, "'").replace(/&(\w)(acute|tilde|grave|circ|uml);/gi, "$1");
      }
      
      // Hack working urls pointing to discussions, because we get
      // ForumDiscussion objects returned instead of DiscoveredContent objects.
      for (var i = 0; i < discussions.length; i++) {
        var cur = discussions[i];
        cur.Url = jQuery.bmj.getGroupUrl(cur);
        cur.DiscussionSnippet = cutto(stripHtml(cur.DiscussionBody.replace(/\\>/g, ">")), 240); // Not sure where that odd \> comes from!
        //cur.DiscussionSnippet = cutto(jQuery(cur.DiscussionBody.replace(/\\>/g, ">")).text(), 240);
      }
      
      // Add new row to discussions table.
      jQuery("table", self)
        .append(jQuery.bmj.runTemplate("feed-items", { discussions: discussions }));
        
      if (opt.stripeRows) {
        jQuery("tr:odd", self).addClass("altrow");
      }
      if (opt.linkTarget) {
        jQuery("a", self).attr("target", opt.linkTarget);
      }
    }
    
    // Use simple method to load a JSON source file.
    loadFeedFile(opt, displayDiscussions);

    return this;
  }

})(); // end closure
