/**
 * Pluck handler. This file handles calls to Pluck. Callbacks are handed off to a this.callbackHandler object.
 * Pass in a callback object. Expect that the following methods are implemented in the callback object:
 * setViewType
 * suppressPluck
 * renderReviewPage
 * updateAbuse
 * updateRecommendation
 */
//Check for MAGNET namespace
if (typeof MAGNET == "undefined") {
var MAGNET = {};
}
// Adds pluck to the magnet Namespace
MAGNET.pluck = {};

function Pluck(callbackHandler) {
// instance properties
// Allows you to override the callback object. By default it's the
// PluckMarkupGenerator, but you can pass in other objects.
if (typeof(callbackHandler) != "undefined") {
  this.callbackHandler = callbackHandler;
} else {
  this.callbackHandler = PluckMarkupGenerator;
}
this.callbackHandler.parentHandler=this;
this.serverUrl = ""; // Pluck server url.
this.commentForm = new Object();
this.crLogicHelper = new Object();
this.programUrl = ""; // Used by the private comments.
this.artId = "";
this.pluckBatchSize = 10; // Max number of requests pluck can handle.
this.currentPage = 1;
this.numberPerPage = "";
this.currentRating = -1;
this.isLoggedIn = "";
this.loginUrl = "";
this.pluckActive = true;
this.requestBatch = "";
this.gatewayHandler = ""; // Object used for guest state.


/**
 * Initializes the server and article id.
 * @param {String} serverUrl URL of the Pluck server
 * @param {Number} numberPerPage Number of Pluck items to display per pages.
 * @param {String} loginUrl URL user goes to when they need to log in.
 */
Pluck.prototype.init= function(serverUrl, numberPerPage, loginUrl) {
  // see if pluck is responding.
  try {
    this.requestBatch = new RequestBatch();
  }
  catch (ex) {
    this.pluckActive = false;
  }

  this.numberPerPage = numberPerPage;
  this.loginUrl = loginUrl;
  this.isLoggedIn = this.LoggedIn();// was userLoggedIn;

  var domain = location.host.toString();
  var domainSplit = domain.split(".");
  domain = domainSplit[domainSplit.length-2] + "." + domainSplit[domainSplit.length-1];
  var removePort = domain.split(":");
  domain = removePort[0];
  document.domain=domain;
  this.serverUrl = serverUrl;
}

Pluck.prototype.LoggedIn = function () {
        var cookie_name="amg_user";
        var nameEQ = cookie_name + "=";
        var ca = document.cookie.split(';');
        for (var i=0; i<ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0)==' ') c = c.substring(1,c.length);
            if (c.indexOf(nameEQ) == 0) return true;
        }
        return false;
}

// Listener that will handle case when user is not logged in.
Pluck.prototype.addGatewayListener = function(gatewayListener) {
  this.gatewayHandler = gatewayListener;
}

// Attach onsubmit to the comment form.
Pluck.prototype.initCommentForm = function(frmId, artId, frmDiv, type) {
  if (type === undefined) { type = "comment"; }
  if (document.getElementById(frmId)) {
  this.commentForm[artId] = document.getElementById(frmId);
  if (this.commentForm[artId] == null) { return false; }

  if (this.pluckActive) {
    var oThis = this;
    this.commentForm[artId].name = frmId;
    if (type == "comment") {
        this.commentForm[artId].onsubmit = function(){
            return oThis.submitComment(artId);
        }
    } else {
        this.commentForm[artId].onsubmit = function(){
            return oThis.submitReview(artId);
        }

    }

//Form gateway events
if(!this.isLoggedIn){
    //Get the form button
    oThis = this;
    oTarget = document.getElementById("frmPostBtn_" + artId);
    oTarget.disabled = "true";
    oTarget.onmousedown = function () {return oThis.gatewayHandler.loginHandler('comment', oTarget);}
      //Get the form text
      oTarget = document.getElementById("commentText_" + artId);
      oTarget.onblur= function () {oTarget.value='';}
      oTarget.onfocus= function () {oTarget.focus='off'; return oThis.gatewayHandler.loginHandler('comment', oTarget);}
  }
  } else {
    document.getElementById(frmDiv).style.display = "none";
  }
  }
}


// Make request for multiple articles from an array of ids.
// Used on the list page.
Pluck.prototype.doMultArticleRequest = function(aIds) {
  var useRatings = false;
  if (this.pluckActive) {
       for (var j=0; j<aIds.length; j++) {
               var multRequest = new RequestBatch();
              if (this.crLogicHelper[aIds[j]].indexOf('R') != "-1") {
                useRatings = true;
                var articleKey = new ArticleKey(aIds[j]);
                multRequest.AddToRequest(articleKey);
                   multRequest.BeginRequest(this.serverUrl, this.callbackHandler.renderReviewPage);
                   multRequest = new RequestBatch();
              }
            if (this.crLogicHelper[aIds[j]].indexOf('V') != "-1") {
                if (this.crLogicHelper[aIds[j]].indexOf('R') == "-1") {var articleKey = new ArticleKey(aIds[j]);}
                var reviewPage = new ReviewPage(articleKey, this.numberPerPage, this.currentPage, "TimeStampAscending");
                multRequest.AddToRequest(reviewPage);
                   multRequest.BeginRequest(this.serverUrl, this.callbackHandler.renderReviewPage);
              }
            if (this.crLogicHelper[aIds[j]].indexOf('C') != "-1") {
                if (this.crLogicHelper[aIds[j]].indexOf('V') == "-1") {var articleKey = new ArticleKey(aIds[j]);}
                var commentPage = new CommentPage(articleKey, this.numberPerPage, this.currentPage, "TimeStampAscending");
                multRequest.AddToRequest(commentPage);
                   multRequest.BeginRequest(this.serverUrl, this.callbackHandler.renderReviewPage);
              }

            if (this.crLogicHelper[aIds[j]].indexOf('A') != "-1") {
              var articleKey = new ArticleKey(aIds[j]);
              multRequest.AddToRequest(articleKey);
                 multRequest.BeginRequest(this.serverUrl, this.callbackHandler.renderReviewPage);
                 multRequest = new RequestBatch();
            }

        }
     if (useRatings) {
      this.callbackHandler.initRatings(aId, this.isLoggedIn);
    }

  } else {
   this.callbackHandler.suppressPluck(aIds);
  }

}

// Make request for multiple articles from an id.
// Used on the detail page.
Pluck.prototype.doArticleRequest = function(aId) {
  // Store the article id for later use.
  if (this.pluckActive) {
    this.requestBatch = new RequestBatch();
    if (this.crLogicHelper[aId].indexOf('R') != "-1") {
      this.addToRequest(aId, "article");
      this.callbackHandler.initRatings(aId, this.isLoggedIn);
    }
    if (this.crLogicHelper[aId].indexOf('V') != "-1") {this.addToRequest(aId, "review");}
    if (this.crLogicHelper[aId].indexOf('C') != "-1") {this.addToRequest(aId, "comment");}
    if (this.crLogicHelper[aId].indexOf('A') != "-1") {this.addToRequest(aId, "article");}


    this.submitRequest();
  } else {
    this.callbackHandler.suppressPluck(aId);
  }
}

//Requests a new batch of reviews
//Used on the list page
Pluck.prototype.updateMultReviews = function(aIds, type) {
  // Store the article id for later use.

  if (this.pluckActive) {
    this.requestBatch = new RequestBatch();
    for (var j=0; j<aIds.length; j++) {
    this.artId = aids[j];
      this.addToRequest(aIds[j], "review");
    }
    this.submitRequest();
    var oThis = this;
    if (this.commentForm[aIds[j]] != null) {
    for (var j=0; j<aIds.length; j++) {

      this.commentForm[aids[j]].onsubmit = function () { return oThis.submitComment(aIds[j]); }
    }
    }
    this.callbackHandler.setViewType(type);
  } else {
    this.callbackHandler.suppressPluck(aIds);
  }
}
/**
 * Requests a new batch of reviews.
 * Used on a detail type page.
 * @param {String} aId
 * @param {String} type
 */
Pluck.prototype.updateReviews = function(aId, type) {
  // Store the article id for later use.
  this.artId = aId;
  if (this.pluckActive) {
    this.requestBatch = new RequestBatch();
    this.addToRequest(aId, "review");
    this.submitRequest();
    var oThis = this;
    if (this.commentForm[aId] != null) {
      this.commentForm[aId].onsubmit = function () { return oThis.submitComment(aId); }
    }
    this.callbackHandler.setViewType(type);
  } else {
    this.callbackHandler.suppressPluck(aId);
  }
}

/**
 * Grabs the next x number of comments.
 * @param {Object} target
 * @param {Object} aId
 */
Pluck.prototype.getNextPage = function(aId) {
   this.currentPage++;
   this.requestBatch = new RequestBatch();
   this.doArticleRequest(aId);
}

/**
 * Grabs the previous x number of comments.
 * @param {Object} aId
 */
Pluck.prototype.getPrevPage = function(aId) {
  this.currentPage--;
  if (this.currentPage < 1) { this.currentPage = 1; }
  this.requestBatch = new RequestBatch();
  this.doArticleRequest(aId);

}


// Adds either an article or review to the request batch.
Pluck.prototype.addToRequest = function(aid, ftype) {
// create and submit a request for info
// articleKey will be the uniq identifier of the TIP that being 'reviewed' by the users.

  if (ftype == "article") {
    var articleKey = new ArticleKey(aid);
    this.requestBatch.AddToRequest(articleKey);
  } else if (ftype == "review") {
    // articleKey will be the uniq identifier of the TIP that being 'reviewed' by the users.
    var articleKey = new ArticleKey(aid);
    // request the reviews that are associated with the TIP by using the articleKey, sort order if desired.
    var reviewPage = new ReviewPage(articleKey, this.numberPerPage, this.currentPage, "TimeStampAscending");
    this.requestBatch.AddToRequest(reviewPage);
   } else if (ftype == "comment") {
      var articleKey = new ArticleKey(aid);
    var commentPage = new CommentPage(articleKey, this.numberPerPage, this.currentPage, "TimeStampAscending");
    this.requestBatch.AddToRequest(commentPage);
  }

}
// this call to the Pluck server returns the comments/reviews associated with an article (TIP)
Pluck.prototype.submitRequest = function() {
  this.requestBatch.BeginRequest(this.serverUrl, this.callbackHandler.renderReviewPage);
}

// Submits a rating.
Pluck.prototype.submitRating = function(rating, artId, target) {
  if (this.isLoggedIn) {
    this.currentRating = rating;
    this.requestBatch = new RequestBatch();
    var articleKey = new ArticleKey(artId);
    var rateAction = new RateAction(articleKey, rating);
    this.requestBatch.AddToRequest(rateAction);
    this.requestBatch.AddToRequest(articleKey);
    this.requestBatch.BeginRequest(this.serverUrl, this.callbackHandler.renderReviewPage);
  } else {
    this.loginHandler(target, "rating");
  }
}




// Bumps a user to the log in page.
Pluck.prototype.loginHandler = function(target, mId) {
  if (this.gatewayHandler != "") {
    this.gatewayHandler.loginHandler(mId, target);
  }
}

/**
/**
 * Submit a review. Reset the page number because we want to take the user back to the first comment.
 * pass in the article id.
 * By default title is document.title.
 * @param {Object} artId
 * @param {Object} titleOverride
 */
Pluck.prototype.submitReview = function(artId, titleOverride) {
  var cmt=this.commentForm[artId]["commentText_" + artId].value;
  if (cmt == "" || cmt == null) {
    alert("You must enter comment text.");
    return false;
  }
 this.currentPage = 1;
  // get form elements and page info
  var articleKey = new ArticleKey(artId);
  var artIdString = artId + "";
  var pageUrl = "http://" + location.host.toString() + "/services/lookup/" + artIdString.substring(artIdString.indexOf('_')+1,artIdString.length); //was document.href
  var pageTitle = document.title;

  var title = document.title;
  var body = cmt;
  var pros = "";  // intentionally left blank as we are not using them
  var cons = "";  // intentionally left blank as we are not using them
  var currentRating = 0;

  if (this.crLogicHelper[artId].indexOf('R') != "-1") {
      currentRating = this.callbackHandler.articleRating;
      if (this.currentRating != currentRating && this.currentRating != -1) {
          currentRating = this.currentRating;
      }
  }
  // create and send request
  this.requestBatch = new RequestBatch();
  var reviewAction = new ReviewAction(articleKey, pageUrl, pageTitle, title, currentRating, body, pros, cons);
  this.requestBatch.AddToRequest(reviewAction);
  this.addToRequest(artId, "review",this.requestBatch);
  this.callbackHandler.setComment(reviewAction);
  this.requestBatch.BeginRequest(this.serverUrl, this.callbackHandler.renderReviewPage);
  var cmt=this.commentForm[artId]["commentText_" + artId];
  cmt.value="";
  return false;
}

/**
 * Submit a Comment. Reset the page number because we want to take the user back to the first comment.
 * pass in the article id.
 * By default title is document.title.
 * @param {Object} artId
 * @param {Object} titleOverride
 */
Pluck.prototype.submitComment = function(artId, titleOverride) {
  var cmt=this.commentForm[artId]["commentText_" + artId].value;
  if (cmt == "" || cmt == null) {
    alert("You must enter comment text.");
    return false;
  }

 this.currentPage = 1;
  // get form elements and page info
  var articleKey = new ArticleKey(artId);
  var artIdString = artId + "";
  var pageType = (typeof(this.commentForm[artId]["commentPageType_" + artId]) != 'undefined')? this.commentForm[artId]["commentPageType_" + artId].value:"";

  if (pageType == 'blog'){
  var pageUrl = "http://" + location.host.toString() + location.pathname.toString(); //was document.href
  } else{
  var pageUrl = "http://" + location.host.toString() + "/services/lookup/" + artIdString.substring(artIdString.indexOf('_')+1,artIdString.length); //was document.href
  }
  var pageTitle = (pageType != "" && pageType != null)? pageType: document.title;

  var pageSection = location.pathname.split('/')[1];
  var title = document.title;
  var body = cmt;

  // create and send request
  this.requestBatch = new RequestBatch();
  var updateArticle = new UpdateArticleAction(articleKey, pageUrl, pageTitle, pageSection, pageType);
  this.requestBatch.AddToRequest(updateArticle);
  var commentAction = new CommentAction(articleKey, pageUrl, pageTitle, body);
  this.requestBatch.AddToRequest(commentAction);
  this.addToRequest(artId, "comment",this.requestBatch);
  //this.callbackHandler.setComment(commentAction);
  this.requestBatch.BeginRequest(this.serverUrl, this.callbackHandler.renderReviewPage);
  var cmt=this.commentForm[artId]["commentText_" + artId];
  cmt.value="";
  return false;
}
// This is the individuals reviews on the TIP.
// has the individuals rating on the TIP plus the comments entered for the tip.
Pluck.prototype.ReviewPageHandler = function(reviewPage) {
    this.callbackHandler.drawReview(reviewPage);
}

/**
 * Submits Pluck recommendations.
 * @param {Object} contentKey
 * @param {Object} target
 * @param {String} type Optional param. Defaults to reviews, but can override by passing
 * in different types. Will need to add code to create proper Pluck key.
 */
Pluck.prototype.submitRecommendation = function(contentKey, target, type) {
  if (this.isLoggedIn) {
    var pluckKey;
    if (type === undefined) { type = "review"; } // Default behavior.
    if (type == "comment") {
      pluckKey = new CommentKey(contentKey);
    } else {
      pluckKey = new ReviewKey(contentKey);
    }
    this.requestBatch = new RequestBatch();

    this.requestBatch.AddToRequest(new RecommendAction(pluckKey));
    this.callbackHandler.setLastRecommendation(contentKey);
    this.requestBatch.BeginRequest(this.serverUrl,this.callbackHandler.updateRecommendation);
  } else {
    this.loginHandler(target, "recommendation");
  }
  return false;
}


/**
 * User clicks report abuse. Need to pass in a reason and desc of abuse.
 * @param {Object} contentKey
 * @param {Object} reason
 * @param {Object} desc
 * @param {String} type Optional param. Defaults to reviews, but can override by passing
 * in different types. Will need to add code to create proper Pluck key.
 */
Pluck.prototype.submitReportAbuse = function(contentKey, reason, desc, type) {
  if (type === undefined) { type = "review"; } // Default behavior.
    if (type == "comment") {
      pluckKey = new CommentKey(contentKey);
    } else {
      pluckKey = new ReviewKey(contentKey);
  }
  this.requestBatch = new RequestBatch();
  this.requestBatch.AddToRequest(new ReportAbuseAction(pluckKey, reason, desc));
  this.requestBatch.BeginRequest(this.serverUrl, this.callbackHandler.updateAbuse);
  //return false;
}

}
