/**
 * @author tomohiro tsutsumi
 */


$(function(){
	$.fn.rating = function(params){
		$(this).each(function(){
			new RatingStar().init($(this), params);
		});
	}
	
	$('.ratingStars').rating({});
	
})

/*--------------------------------------------------------*/

var ratingStars = function(){
	
	var _obj = {
		readOnly : false,
		starSrc : 'images/star.gif',
		deleteSrc : 'images/delete.gif',
		starParams : { width : 16, height : 16 , margin : 2},
		deleteParams : { width : 16, height : 16 },
		separate : 2
	};
	
	return {
		setParams : function(obj){
			if(!!obj) _obj = obj;
		},
		getParams : function(){
			return _obj;
		}
	}
	
}();

/*--------------------------------------------------------*/

//constructor
function RatingStar(){
	//
	var _initObj = ratingStars.getParams();
	//定数
	this.CONTAINER_CLASS = 'ratingStarsContainer'
	this.TYPE_RADIO = 'radio';
	this.TYPE_SELECT = 'select';
	
	//private
	this._inputs;
	this._starObjs;
	this._container;
	this._deleteObj;
	this._stars;
	this._type;
	
	//public
	this.readOnly = _initObj.readOnly;
	this.starParams = _initObj.starParams;
	this.deleteParams = _initObj.starParams;
	this.selectNum = _initObj.selectNum;
	this.separate = _initObj.separate;
	this.starSrc = _initObj.starSrc;
	this.deleteSrc = _initObj.deleteSrc;
}


RatingStar.prototype.init = function(target, params){
	//パラメーターを取得設定
	for (var tmpParamsId in params){
		/*if (!!this[tmpParamsId]) {
			this[tmpParamsId] = params[tmpParamsId];
		}*/
		this[tmpParamsId] = params[tmpParamsId];
		//console.log(params[tmpParamsId]);
	}
	
	//ユーザー設定パラメーターがない場合にreadOnlyがclassに設定されているかどうか
	if(!params['readOnly']) this.readOnly = target.hasClass('readOnly');
	
	//ユーザー設定パラメーターがない場合に[single][half]がclassに設定されているかどうか
	if(!params['separate']){
		if(target.hasClass('single')) this.separate = 1;
		else if(target.hasClass('half')) this.separate = 2;
	}
	
	if(!this.starParams['margin']) this.starParams['margin'] = 2;
	
	//
	var owner = this;
	
	this._container = $('<div>');
	this._container.addClass(this.CONTAINER_CLASS).css({
		position : 'relative',
		height : this.starParams['height']
	});
	
	this._stars = $('<div>');
	this._stars.css({
		'position' : 'absolute', cursor : 'pointer'
	});
	this._container.append(this._stars);
	target.append(this._container);
	
	
	var childSelector;
	if(target.find('input[type=radio]').length){
		this._type = owner.TYPE_RADIO;
		childSelector = 'input[type=radio]';
		this.selectNum = target.find("input[type='radio']:checked").val();
		/*console.log('====');
		console.log(this.selectNum);*/
	}else if(target.find('select').length){
		this._type = owner.TYPE_SELECT;
		childSelector = 'option';
		target.find('select').css({
			display : 'none'
		});
		this.selectNum = target.find("option:selected").val();
		/*console.log('====');
		console.log(this.selectNum);*/
	}	
	
	//setting input
	this._inputs = [];
	this._starObjs = [];
	if (childSelector) {
		target.find(childSelector).each(function(i){
			owner._inputs.push($(this));
			$(this).css({
				display: 'none'
			});
			
			//
			var starObj = $('<p>');
			starObj.addClass('star').css({
				top : 0, padding : 0, margin : 0,
				position: 'absolute',
				height: owner.starParams['height'] + 'px',
				overflow: 'hidden'
			});
			
			if (!owner.readOnly) {
				starObj.hover(function(){
					_onStarOver(i);
				}, function(){
					_onStarOut(i);
				}).click(function(){
					_onStarClick(i);
				});
			}
			
			_setStarParams(starObj, i);
			owner._stars.append(starObj);
			owner._starObjs.push(starObj);
		});
		
		//isReadOnly
		if (this.readOnly){
			this._stars.css({
				'cursor': 'auto'
			});
		}else {
			this._deleteObj = _createDeleteObj();
			this._container.append(this._deleteObj);
			this._stars.css({
				'left' : (this.deleteParams['width'] + 2) + 'px'
			});
		}
		
		//
		_setSelect();
	}
	
	/*==========================
		deleteObj
	==========================*/
	
	function _createDeleteObj(){
		var deleteObj = $('<p>');
		deleteObj.css({
			width : owner.deleteParams['width'],
			height : owner.deleteParams['height'],
			padding : 0, margin : 0,
			top : 0, left : 0,
			position: 'absolute', overflow : 'hidden', cursor : 'pointer',
			background : 'transparent url(' + owner.deleteSrc + ') no-repeat'
		});
		
		deleteObj.hover(function(){
			$(this).css({
				'background-position' : '0 -' + owner.deleteParams['height'] + 'px'
			});
			for(var i = 0, end = owner._starObjs.length; i < end; i++){
				_resetCss(owner._starObjs[i]);
			}
		}, function(){
			$(this).css({
				'background-position' : '0 0'
			});
			_setSelect();
		}).click(function(){
			_changeChecked(owner.selectNum - 1, false);
			
			owner.selectNum = 0;
			_setSelect();
		});
		
		return deleteObj;
	}
	
	
	/*==========================
		starObj event
	==========================*/
	function _onStarOver(id){
	var _initObj = ratingStars.getParams();
		for(var i = 0, end = owner._starObjs.length; i < end; i++){
			var starObj = owner._starObjs[i];
			_setBgPos(starObj, 0);
			if(i <= id){
				//red
				//_setBgPos(starObj, -_initObj.starParams.height);
				_setBgPos(starObj, - owner.starParams.height);
			}else{
				//grey
				_setBgPos(starObj, 0);
			}
		}
	}
	
	function _onStarOut(id){
		_setSelect();
	}
	
	function _onStarClick(id){
		owner.selectNum = id + 1;
		_setSelect();
		_setChecked();
	}
	
	//
	function _setChecked(){
		_changeChecked(owner.selectNum - 1, true);
	}
	
	function _changeChecked(id, isChecked){
		var inputObj = owner._inputs[id];
		if(owner._type == owner.TYPE_RADIO){
			if(isChecked) inputObj.attr("checked", "checked");
			else inputObj.attr("checked", false);
		}else if(owner._type == owner.TYPE_SELECT){
			if(isChecked) inputObj.attr("selected", "selected");
			else inputObj.attr("selected", false);
		}
	}
	
	function _setStarParams(target, id){
		var tmpId = Math.floor(id/owner.separate);
		var remainder = id % owner.separate;
		var base = (tmpId * owner.starParams['width']);
		
		var w = (owner.starParams['width'] / owner.separate);
		var l = w * (remainder-1);
		base = base + w;
		var m = owner.starParams['margin'] * tmpId;
		
		var bgPosition = -(remainder*w) + 'px 0px';
		/*if(!remainder) m = owner.starParams['margin'];
		console.log(m);
		*/
		
		target.css({
			left : (base + l + m) + 'px',
			width : (w + m) + 'px', 
			background : 'transparent url(' + owner.starSrc + ') no-repeat',
			'background-position' : bgPosition
		})
		
	}
	
	function _setBgPos(target, top){
		var left = _getBgPos(target).left;
		target.css({
			'background-position' : left + ' ' + top + 'px'
		});
	}
	
	function _setSelect(){
		//console.log(owner.selectNum);
		var _initObj = ratingStars.getParams();
		for(var i = 0, end = owner._starObjs.length; i < end; i++){
			var starObj = owner._starObjs[i];
			_setBgPos(starObj, 0);
			//if((i+1) <= owner.selectNum) _setBgPos(starObj, -_initObj.starParams.height*2);
			if((i+1) <= owner.selectNum) _setBgPos(starObj, - owner.starParams.height*2);
		}
	}
	
	function _resetCss(target){
		_setBgPos(target, 0);
	}
	
	function _getBgPos(target){
		var bgPos;
		if (target.css('background-position')) {
			bgPos = target.css('background-position').split(' ');
		}else{
			bgPos = [
				target.get(0).currentStyle["backgroundPositionX"],
				target.get(0).currentStyle["backgroundPositionY"]
			];
		}
		return { left : bgPos[0], top : bgPos[1] };
	}
}

