// :: JaZzStars by Andreas Glaser (www.andreas-glaser.com)
// :: Prototype based content rating class
// :: v1.0.1
// :: 12/4/2009 4:21:59 PM

// :: + License
// ::   Licensed under the Creative Commons Attribution 3.0 License - http://creativecommons.org/licenses/by/3.0/
// :: 	- Free for use in both personal and commercial projects
// :: 	- Attribution requires leaving author name, author link, and the license info intact.

function callbackExample(userRating) {
  alert('<b>Rated:</b> ' + userRating);
}

var JaZzStars = Class.create();
JaZzStars.prototype = {

  initialize: function(options) {    
    
    // :: Extend object with options
    this.options = {
      
      scale: 5,
      initialValue: 3,
      locked: false,
      
      lockAfterRating: true,
      setBackAfterRating: false,
      
      ID: 0,
      
      ajax: false,
      ajaxMethod: 'post',
      ajaxAction: 'ajax-request-processor.php',
      ajaxVariable: 'Rating',
      ajaxAdditional: '&AJAX=true',
      
      callFunction: true,
      callFunctionName: 'callbackExample',
      
      // :: Images
      starFilled: '../images/star-filled.png',
      starEmpty: '../images/star-empty.png'
    };
    Object.extend(this.options, options);
    
    // :: Input Check
    this.options.scale = (this.options.scale < 2) ? 2 : this.options.scale;
    this.options.initialValue = (this.options.initialValue > this.options.scale) ? this.options.scale : this.options.initialValue;
    this.options.initialValue = (this.options.initialValue < 0) ? 0 : this.options.initialValue;
    
    this.options.ID = 'JaZzStars-' + this.options.ID;
    
    // :: Generate XHTML  		
    document.write('<div id="' + this.options.ID + '" class="JaZzStars"></div>');
    
    var objBody = $(this.options.ID);
    
    // :: Loop through scale
    for(var i = 1; i <= this.options.scale; i++) {
    
      if(this.options.initialValue>=i) {
        // :: Add Tag Info
        objBody.insert(new Element('img',{'src':this.options.starFilled, 'id':this.options.ID + '-star-' + i,  'rel': i}));
      } else {
        objBody.insert(new Element('img',{'src':this.options.starEmpty, 'id':this.options.ID + '-star-' + i,  'rel': i}));
      }
      
      // :: Add Eventlisteners
      $(this.options.ID + '-star-' + i).observe('click', function(event) { event.stop(); this.rate(event); }.bindAsEventListener(this));
      $(this.options.ID + '-star-' + i).observe('mouseover', function(event) { event.stop(); this.preview(event); }.bindAsEventListener(this));
      $(this.options.ID).observe('mouseleave', function(event) { event.stop(); this.setback(event); }.bindAsEventListener(this));
    }
  },

  preview: function(e) {
    // :: Make sure rating is not locked
    if(this.options.locked) {
      return;
    }
    
    // :: Get element parameters
    var id = e.element().getAttribute('id');
    var num = e.element().getAttribute('rel');
    
    // :: Loop through stars
    for(var i = 1; i <= this.options.scale; i++) {
      if(i<=num) {
        $(this.options.ID + '-star-' + i).src = this.options.starFilled;
      } else {
        $(this.options.ID + '-star-' + i).src = this.options.starEmpty
      }
    }
  },
  
  setback: function(e, force) {
    if(this.options.locked && (typeof force == 'undefined' && !force)) {
      return;
    }
    for(var i = 1; i <= this.options.scale; i++) {
      $(this.options.ID + '-star-' + i).src = (i <= this.options.initialValue) ? this.options.starFilled : this.options.starEmpty;
    }
    return true;
  },
  
  rate: function(e) {
   
    // :: Make sure rating is not locked
    if(this.options.locked) {
      return false;
    }
    
    // :: Lock rating
    if(this.options.lockAfterRating) {
      this.lock();
    }
    
    // :: Get element parameters
    var id = e.element().getAttribute('id');
    var num = e.element().getAttribute('rel');
   
   
    // :: Send ajax is necesarry
    if(this.options.ajax) {
      new Ajax.Request(this.options.ajaxAction, {
        method: this.options.ajaxMethod,
        parameters: this.options.ajaxVariable + '=' + num + this.options.ajaxAdditional,
        onCreate: function() {}.bind(this),
        onSuccess: function(transport) {
          if(this.options.callFunction) {
            eval(this.options.callFunctionName + '(' + num + ');'); 
          }
        }.bind(this),
        onFailure: function() {
          alert('001: Unexpected failure occured');
        }.bind(this),
        onComplete: function(transport) {}.bind(this),
      });
    } else {
      // :: Callback
      if(this.options.callFunction) {
        eval(this.options.callFunctionName + '(' + num + ');'); 
      }
    }
    
    return true;  
  },

  unlock: function() {
    this.options.locked = false;
    return true;
  },
  lock: function() {
    this.options.locked = true;
    return true;
  },
}