ratings = {};

RatingComponent = Class.create();
RatingComponent.prototype = {
	
	initialize: function(id, app, options) {
		
		if (options.content_id || options.display) {
			this.id = id;
			this.self = $(this.id);
			this.app = app;
			this.options = options || {};
			
			this.type = this.options.type;
			this.content_id = this.options.content_id;
			
			this.range = this.options.range || 5;
			this.val = this.options.value || "0";
			this.cur_value = this.val;
			
			if (this.options.parent) {
				this.parent = ratings[this.options.parent];
			}
			
			this.initAjax();
			
			this.createStructure();
			this.targetValue(this.val);
			
			if (this.options.active) {
				this.injectBehaviours();	
			}
		}
		
	},
	
	initAjax: function() {
		ajaxEngine.registerRequest(this.id + '_request', this.app);		
		ajaxEngine.registerAjaxObject(this.id + '_update', this);
	},
	
	callRicoAjaxEngine: function(callParams) {
		if (console) console.log('PARAMS: '+callParams);
		ajaxEngine.sendRequest.apply(ajaxEngine, callParams);
	},
	
	saveValue: function() {
		var callParams = [];
		callParams.push( this.id + '_request');
		callParams.push('cmd=SaveRating');
		callParams.push('id=' + this.id);
		callParams.push('type=' + this.type);
		callParams.push('content_id=' + this.content_id);
		callParams.push('value=' + this.val);				
		this.callRicoAjaxEngine(callParams);
	},
	
	ajaxUpdate: function(ajaxResponse) {
		var updates = ajaxResponse.getElementsByTagName('update');
		if (updates) {
			for(var i=0; i<updates.length; ++i) {
				var id = updates[i].getAttribute('id');
				ratings[id].targetValue(RicoUtil.getContentAsString(updates[i]));
			}
		}
	},
	
	createStructure: function() {
		
		this.self.innerHTML = '';

		for (var i=1; i<=this.range; ++i) {
			var div = document.createElement('div');
			var classname = 'rating_mark ';
			div.className = classname;
			this.self.appendChild(div);
		}
		
		if (console) console.log('RATINGS: '+this.self.innerHTML);
		
		if (this.options.active) {
			this.self.className += ' rating_active';	
		}
	},
	
	injectBehaviours: function() {
		
		this.self.onmouseout = this.outHandler.bindAsEventListener(this);
		
		var num_nodes = this.self.childNodes.length;
		for (var i=0; i<num_nodes; ++i) {
			var node = this.self.childNodes[i];
			node.onmouseover = this.overHandler.bindAsEventListener(this, (i+1)+"");
			//node.onmouseout = this.outHandler.bindAsEventListener(this, this.value);
			node.onclick = this.clickHandler.bindAsEventListener(this, (i+1)+"");
		}
	},
	
	clickHandler: function(e, val) {
		this.self.style.cursor = 'pointer';
		this.val = val;
		this.saveValue();
		this.targetValue(this.val);
	},
	
	overHandler: function(e, val) {
		this.self.style.cursor = 'pointer';
		this.targetValue(val);
	},
	
	outHandler: function(e) {
		if (this.outsideBoundaries(e)) {
			this.self.style.cursor = '';
			this.targetValue(this.val);
		}
	},
	
	targetValue: function(val) {
		var parts = val.split('.');
		var num_nodes = this.self.childNodes.length;
		for (var i=0; i<this.range; ++i) {
			var slot = i+1;
			var node = this.self.childNodes[i];
			node.className = 'rating_mark';
			if (slot <= parts[0]) {
				node.className = ApexUtil.addClass(node, 'full');
			} else if (slot > parts[0] && parts[1]) {
				node.className = ApexUtil.addClass(node, 'fraction_'+parts[1]);
				parts[1] = null;
			} else {
				node.className = ApexUtil.addClass(node, 'empty');
			}
		}
	},
	
	outsideBoundaries: function(e) {
		
		var width = this.self.offsetWidth;
		var height = this.self.offsetHeight;
		
		var pos = RicoUtil.toDocumentPosition(this.self);
		var pageScroll = ApexUtil.getPageScroll();
		
		pos.x = pos.x;
		pos.y = pos.y;
		
		var mouseX = e.pageX;
		var mouseY = e.pageY;
		
		if (mouseX > pos.x && mouseX < pos.x + width) {
			if (mouseY > pos.y	&& mouseY < pos.y + height) {
				return false;	
			}
		}
		
		return true;
		
	}
	
};