if (typeof com == "undefined") com = {};
if (typeof com.coremedia == "undefined") com.coremedia = {};
if (typeof com.coremedia.html == "undefined") com.coremedia.html = {};
com.coremedia.html.Functions = {
  urlEncode: function(data) {
    var e = "";
    for (name in data) {
      if (e.length > 0) e += "&";
      e += (encodeURIComponent(name) + "=" + encodeURIComponent(data[name]));
    }
    return e;
  },
  post: function(url, parameters, callback) {
    var xmlhttp=null;
    if (window.XMLHttpRequest){
      xmlhttp=new XMLHttpRequest();
    }
    else if (window.ActiveXObject){// code for IE5 and IE6
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    if (xmlhttp!=null){
      xmlhttp.onreadystatechange = function(){
        if (xmlhttp.readyState==4){
          if (xmlhttp.status==200){
            var json = eval('('+xmlhttp.responseText+')');
            callback(json);
          }
        }
      };
      var encodedParameters = com.coremedia.html.Functions.urlEncode(parameters);
      xmlhttp.open("Post", url, true);
      //Send the proper header information along with the request
      xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      xmlhttp.setRequestHeader("Content-length", encodedParameters.length);
      xmlhttp.setRequestHeader("Connection", "close");
      xmlhttp.send(encodedParameters);
    }
  },
  bind: function(object, method){
    var args = Array.prototype.slice.call(arguments, 2);
    return function() {
      var args2 = args.concat(Array.prototype.slice.call(arguments, 0));
      return method.apply(object, args2);
    };
  },
  show: function(element) {
    element.style.visibility = "visible";
  },
  hide: function(element) {
    element.style.visibility = "hidden";
  },
  setWidth: function(element, value) {
    element.style.width = value;
  },
  setContents: function(element, contents) {
    element.innerHTML = contents;
  }
};
if (typeof com.coremedia.rating == "undefined") com.coremedia.rating = {};
/**
 * Rating control for an item with several stars.
 *
 * Parameters:
 *   postUrl : URL to post to when the rating changes
 *   itemId: (content) ID of the item being rated
 *   maxRating: number of stars (e.g. 5)
 *   labelId: ID of the DHTML element holding the "X ratings" label
 *   labelSingular: localized label for one rating
 *   labelPlural: localized label for zero or >1 ratings
 **/
com.coremedia.rating.RatingControl = function(element, postUrl, itemId, maxRating,
                                              labelId, labelSingular, labelPlural, markupHelper) {
  return {
    helper: markupHelper,
    element: element,
    url: postUrl,
    itemId: itemId,
    maxRating: maxRating,
    isClicked: false, // once clicked, the rating control will become disabled
    labelId: labelId,
    labelSingular: labelSingular,
    labelPlural: labelPlural,
    hoverRating: function(val){
      if (!this.isClicked) {
        var my = this.getMyRating();
        this.helper.setWidth(my, val + "%");
        this.helper.show(my);
        this.helper.hide(this.getGlobalRating());
      }
    },
    blurRating: function(){
      if (!this.isClicked) {
        this.helper.hide(this.getMyRating());
        this.helper.show(this.getGlobalRating());
      }
    },
    rate: function(val){
      if (!this.isClicked) {
        this.disable();
        var params = {'item': itemId, 'userRating': val};
        var handler = this.helper.bind(this, this.handleResponse);
        this.helper.post(this.url, params, function(response) {
          handler(response);
        });
      }
    },
    handleResponse: function(response) {
      this.update(response);
    },
    update: function(newState) {
      var avg = newState.averageRating;
      var total = newState.totalRatings;
      this.helper.setWidth(this.getGlobalRating(), (avg * 20) + "%");
      this.helper.setContents(this.getRatingLabel(), "<span>" + total + " " + (total == 1 ? this.labelSingular : this.labelPlural) + "</span>");
    },
    disable: function() {
      this.isClicked = true;
      this.helper.show(this.getRatingOverlay());
    },
    getMyRating: function() {
      return this.element.getElementsByTagName('div')[0];
    },
    getGlobalRating: function() {
      return this.element.getElementsByTagName('div')[1];
    },
    getRatingLabel: function() {
      return document.getElementById(this.labelId);
    },
    getRatingOverlay: function() {
      var imgs = this.element.getElementsByTagName('div');
      return (imgs) ? imgs[imgs.length-1] : null;
    }
  };
};
com.coremedia.rating.HtmlRatingControl = function(element, postUrl, itemId, maxRating,
                                                  labelId, labelSingular, labelPlural) {
  return com.coremedia.rating.RatingControl(element, postUrl, itemId, maxRating, labelId, labelSingular, labelPlural,
    com.coremedia.html.Functions);
};
