/**
 * @author xandr
 */
jQuery.fw = jQuery.fw || {}; // create the namespace

(function($){jQuery.widget("fw.starsRating", {
    
  init: function() {
    // Check, if already it is starsRating widget
    if( this.element.hasClass('starsRating') )return;
    
//    this.$container = $(this.element);
//    var name_opts = this.$container.attr('name').split('|');
//    this.options.gameid = name_opts[0];
//    this.options.infavorite = name_opts[1];    
//    this.status = 'done';
    // Setup parameters from tag attribute 'href'
    //console.log('Init fw.starsRating for '+ $(this.element).html());
    
    var attr_options = {};
    if(this.element.attr('href')){
      attr_options = $.parseParamsString(this.element.attr('href'));
    }else{
      this.options.readonly = true;
    }
    this.options = $.extend( this.options, attr_options);
		//Initialize needed constants
		var self = this;
    this.options.initValue= parseFloat(this.element.text());
    //console.log('Init starsRatingg with options:', this.options);
    this.element.text('');
    this._setValue( isNaN(this._getValue()) ? this.options.initValue : this._getValue() );

    this.starsbox = $('<div/>').addClass('starsbox')
      .css('width', this.options.starWidth*this.options.max_rating)
      .css('height', this.options.starWidth)
      .appendTo(this.element);
    
    var line_height = this.options.starWidth;
		this.element
			.addClass('starsRating')
      .css('line-height', line_height+'px')
      //.css('display', 'inline')
      ;
      //.css('width', this.options.starWidth*this.options.max_rating)
      //.css('height', this.options.starWidth);
    this.indicator = $('<div/>').html('&nbsp;').addClass('indicator')
      .height(line_height)
      .appendTo(this.starsbox);
      
    
    this.buildStars();
	  $('<label>Text labels</label>').css('left', this.options.starWidth*this.options.max_rating+5)
      .appendTo(this.element);
	
    this.element.hover(function(){
		    if(self.canVote()){
			    self.prev_state = self.state;
			    self.setState('userinput');
		    }
      },
      function(){
		    if(self.prev_state){
			    self.setState(self.prev_state);
		    }
      }
    );
    
    if(this.options.readonly){
      this.setState('readonly');
    }else{
      // Already voted
      if(this.options.voted==1)   this.setState('voted');
	    else 						this.setState('normal');
    }
  },
  
  canVote:function(){
	  return (!this.options.voted || this.options.canrevote) && this.state!='saving' && this.state!='readonly';
  },
  
  setState:function(v){
    switch(v){
      case 'normal':
        this.element.find('.star').hide();this.indicator.show();
		    this.setText(this.options.texts.pleasevote);
        break;
      case 'voted':
        this.element.find('.star').hide();this.indicator.show();
		    this.setText(this.options.texts.alreadyvoted);
		    this.disable();
        break;		
      case 'userinput':
        if(!this.canVote())return;
		    this.enable();
        this.indicator.hide(); this.element.find('.star').show();
        break;
	    case 'saving':
		    this.setText(this.options.texts.saving);
		    this.disable();
		    break;
      case 'readonly':
        this.element.find('.star').hide();this.indicator.show();
        this.setText('');
        this.disable();
        break;        
    }
	  if(v!='userinput' && this.prev_state){
		  this.prev_state=false;
	  }
	  this.state=v;
    this.update();
  },
  
  setText: function(str){
	  $('label',this.element).text(str);
  },
  
  updateMarkLabel: function(id){
    var s = "";
    var hover_value = this._getValueOfStar(id);
	  if(this.options.texts.marks && this.options.texts.marks.length>=hover_value)
    {
		  s = this.options.texts.marks[ Math.floor(hover_value-0.001)];
    }
    if(this.options.showmark==1){
      s = hover_value + ' - ' + s;
    }
    this.setText(s);
  },
  
  buildStars: function(){
    var split = this.options.split;    
    this.options.stars_count = this.options.max_rating*split;
    for(var i=0;i<this.options.stars_count;i++)
      this.starsbox.append('<div class="star"><span/></div>');
     
    var self = this;
    var stw = this.options.starWidth;
    this.element.find('.star').each(
      function (i) {
        var $el = $(this);
        var element_i = i;
        var spi = (element_i % split), spw = Math.floor(stw/split);
        $el.width(spw);
        $el.find('span').css({ 'margin-left':'-'+ (spi*spw) +'px' });
        //$el.css({ 'background-position':'-'+ (spi*spw) +'px' });
        
        $el.hover(
          function(){
            if(!self.canVote())return;
            //console.log('can vote!');
            self.clearFill();      
            $(this).prevAll('.star').andSelf().addClass('star_hover');
		        self.updateMarkLabel(self.element.find('.star').index(this));
          },
          function(){
            if(!self.canVote())return;
            self.clearFill(); 
          }
        );
        $el.click(function(){self.onStarClick(this)});    
      });
  },
  
  clearFill:function(){
    this.element.find('.star').removeClass('star_hover')
    //this.indicator.show();
  },
  
  onStarClick:function(el){
    if(!this.canVote())return;
    var starnum = this.element.find('.star').index(el)+1;
    //console.log('clicked on star ',starnum);
    //console.log('set val to ', starnum/this.options.split);
    this._setValue(starnum/this.options.split);
    //console.log('new value ', this._getValue());
    this.update();
    var self=this;
	  $.ajax({
		  type: "GET",
		  url: this.options.ajax_url,
		  data: {
		  value: this._getValue(),      					 
				  gameid: this.options.gameid					
			  },
		  success: function(data) { self.onSubmit(data) },
		  dataType: "json"
	  });
	  this.setState('saving');
  },
  
  onSubmit:function(data){
    //console.log('Submiting success', data);
    this._setValue( parseFloat( data.rating/10));
    this.setState('voted'); 
	  this.setText(this.options.texts.savingdone);
  },
  
  update: function(){
    this.indicator.width(this._getValueWidth());
  },
  
  enable: function() {
		this.element
			.removeAttr('disabled')
			.siblings()
				.removeAttr('disabled')
			.parent()
				.removeClass('starsRating-disabled');
		this.disabled = false;
	},
	disable: function() {
		this.element
			.attr('disabled', true)
			//.siblings().attr('disabled', true)
			//.parent()				.addClass('starsRating-disabled')
        ;
		this.disabled = true;
	},
	_getValue: function() {
    var v = parseFloat(this._value); 
    if(v>this.options.max_rating)v = this.options.max_rating;
    if(v<0)v=0;
		return v;
	},
  _getValueOfStar: function(starid){
    return (starid+1)/this.options.split;
  },
	_getValueWidth: function() {
		return parseInt(this._getValue()*this.options.starWidth);
	},  
	_setValue: function(newVal) {
		if(isNaN(newVal)) newVal = this.options.initValue;
		this._value = newVal;
	}  
    /*-------------------------------*/
});})(jQuery);

jQuery.extend(jQuery.fw.starsRating, {   
    defaults: {
        // URL for ajax calls
        ajax_url:'/ajax/rategame',
        max_rating: 5,
        starWidth: 16,
        canrevote: 0, /* TODO: canvote */
        split: 1,
        showmark: 0,  /* Показывать оценку при выборе в подсказке*/
		    texts:{
			    marks: ['Very poor', 'Poor', 'OK', 'Good', 'Very Good'],
			    pleasevote: 'Please vote',
			    saving:	'Saving...',
			    savingdone: 'Thanks!',
			    alreadyvoted: 'You already voted'
		    }
    }
});  
