if(!ch){
	var ch = {};
}
if(!ch.exmachina){
	ch.exmachina = {};
}
if(!ch.exmachina.bravofly){
	ch.exmachina.bravofly = {};
}
ch.exmachina.bravofly.Knob = function(/* object */ctorArgs){
	var nodeId = ctorArgs.nodeId, 
		targetNode = $(nodeId)
	;
	this.imgExt = Prototype.Browser.IE ? "gif" : "png"; 
	var isEnabled = (true == ctorArgs.enabled), 
		className = "ta_knob",
		value = ctorArgs.value || 0,
		_timestamp = (new Date()).getTime(),
		chkLabel = ctorArgs.label || targetNode.innerHTML,
		template = this.template.replace(/{\$KnobId}/g, _timestamp)
		.replace(/{\$ClassName}/, className)
		.replace(/{\$imgExt}/g, this.imgExt),
		self = this,
		cImg = null
	;
//	var t0 = (new Date()).getTime();
	for(var i = 0; i < 11; i++){
		cImg = new Image(83, 75);
		cImg.border = 0;
		cImg.src = "/images/pricefinder/knob_" + (i / 2).toFixed(1) + ".jpg";
		this.knobFrames.push(cImg);
	}
//	var t1 = (new Date()).getTime();
//	console.log("[knob] images loaded, time elapsed: " + (t1 - t0));
	for(i = 0; i < 10; i++){
		cImg = new Image(83, 75);
		cImg.border = 0;
		cImg.src = "/images/pricefinder/knob_available_" + ((i + 1) / 2).toFixed(1) + "." + this.imgExt;
//		$("ta_knob_reach_img_" + (i / 2).toFixed(1)).src = cImg.src;
		//this.reachFrames.push(cImg);
	}
	targetNode.innerHTML = template;
	this.onSetStatus = ctorArgs.onSetStatus || function(){};
	this.reachabilitySet = ctorArgs.reachabilitySet || this.reachabilitySet
	for(var i = 0, lbls = ["minus", "plus", "counter", "knob"]; i < lbls.length; i++){
		var lbl = lbls[i];
		this[lbl] = $(lbl + _timestamp);
		this[lbl].writeAttribute("id", null);	
	}
	
	this.minus.observe("click", function(){
		if(self.disabled){ return; }
		var prevStatus = self.getPrevValidStatus();
		self.setStatus(prevStatus);
	});
	this.plus.observe("click", function(){
		if(self.disabled){ return; }
		var nextStatus = self.getNextValidStatus();
		self.setStatus(nextStatus);
	});
	this.setStatus(value);
	this.domNode = $("node" + _timestamp);
	if(isEnabled){
		this.enable();
	}else{
		this.disable();
	}

	// avoid selection on doubleclick
	var stopSelection = function(evt){
		if(evt.target.className && (evt.target.className == "ta_knob_plus" || evt.target.className == "ta_knob_minus")){
			evt.stopPropagation();
			evt.preventDefault();
			return false;
		}else{
			return true;
		}
	};
	document.observe(Prototype.Browser.IE ? "selectstart" : "mousedown", stopSelection.bindAsEventListener());
};
ch.exmachina.bravofly.Knob.prototype = {
	hourDecode: {
		"0.0": "0h",
		"0.5": "&frac12;h",
		"1.0": "1h",
		"1.5": "1h&frac12;",
		"2.0": "2h",
		"2.5": "2h&frac12;",
		"3.0": "3h",
		"3.5": "3h&frac12;",
		"4.0": "4h",
		"4.5": "4h&frac12;",
		"5.0": "5h"
	},
	template: '<div id="node{$KnobId}" class="ta_knob_container"><div id="counter{$KnobId}" class="ta_knob_counter"></div>' +
				'<div id="minus{$KnobId}" class="ta_knob_minus"></div>' +
				'<div id="knob{$KnobId}" class="{$ClassName}"><img id="ta_knob_img" border="0" width="83" height="75" src="knob_0.0.{$imgExt}" />' +
				'</div><div class="ta_knob_reach"><img style="visibility:hidden" border="0" width="83" height="75" id="ta_knob_reach_img_1" src="/images/pricefinder/knob_available_0.5.{$imgExt}" />' +
				'</div><div class="ta_knob_reach"><img style="visibility:hidden" border="0" width="83" height="75" id="ta_knob_reach_img_2" src="/images/pricefinder/knob_available_1.0.{$imgExt}" />' +
				'</div><div class="ta_knob_reach"><img style="visibility:hidden" border="0" width="83" height="75" id="ta_knob_reach_img_3" src="/images/pricefinder/knob_available_1.5.{$imgExt}" />' +
				'</div><div class="ta_knob_reach"><img style="visibility:hidden" border="0" width="83" height="75" id="ta_knob_reach_img_4" src="/images/pricefinder/knob_available_2.0.{$imgExt}" />' +
				'</div><div class="ta_knob_reach"><img style="visibility:hidden" border="0" width="83" height="75" id="ta_knob_reach_img_5" src="/images/pricefinder/knob_available_2.5.{$imgExt}" />' +
				'</div><div class="ta_knob_reach"><img style="visibility:hidden" border="0" width="83" height="75" id="ta_knob_reach_img_6" src="/images/pricefinder/knob_available_3.0.{$imgExt}" />' +
				'</div><div class="ta_knob_reach"><img style="visibility:hidden" border="0" width="83" height="75" id="ta_knob_reach_img_7" src="/images/pricefinder/knob_available_3.5.{$imgExt}" />' +
				'</div><div class="ta_knob_reach"><img style="visibility:hidden" border="0" width="83" height="75" id="ta_knob_reach_img_8" src="/images/pricefinder/knob_available_4.0.{$imgExt}" />' +
				'</div><div class="ta_knob_reach"><img style="visibility:hidden" border="0" width="83" height="75" id="ta_knob_reach_img_9" src="/images/pricefinder/knob_available_4.5.{$imgExt}" />' +
				'</div><div class="ta_knob_reach"><img style="visibility:hidden" border="0" width="83" height="75" id="ta_knob_reach_img_10" src="/images/pricefinder/knob_available_5.0.{$imgExt}" />' +
				'</div><div id="plus{$KnobId}" class="ta_knob_plus"></div></div>',
	status: 0,
	imgExt: "png",
	reachabilitySet: ["0.0", "0.5", "1.0", "1.5", "2.0", "2.5", "3.0", "3.5", "4.0", "4.5", "5.0"],
	counter: null,
	minus: null,
	plus: null,
	knob: null,
	index: 0,
	knobFrames: [],
	reachFrames: [],
	toString: function(){
		return "[ch.exmachina.bravofly.Knob] id = " + this.cId + "\nclass = ch.exmachina.bravofly.Knob";
	},
	getNextValidStatus: function(){
		var newIndex = this.index + 1;
		if(this.reachabilitySet[newIndex] != null){
			this.index++;
		}
		return this.reachabilitySet[this.index];
	},
	getPrevValidStatus: function(){
		var newIndex = this.index - 1;
		if(this.reachabilitySet[newIndex] != null){
			this.index--;
		}
		return this.reachabilitySet[this.index];
	},
	setCounter: function(){
		this.counter.innerHTML = this.hourDecode[parseFloat(this.status).toFixed(1)];
	},
	getStatus: function(){
		return this.status;
	},
	setStatus: function(cStatus){
		this.status = cStatus;
		this.index = this.reachabilitySet.indexOf(parseFloat(cStatus).toFixed(1));
		this.setCounter(cStatus);
		this.setKnobPosition(cStatus);
		this.onSetStatus();
	},
	setKnobPosition: function(cStatus){
		if(this.disabled){ return; }
		this.knob.firstChild.src = this.knobFrames[parseInt(cStatus * 2)].src;
	},
	disable: function(){
		this.setStatus(0);
		this.index = 0;
		this.disabled = true;
		this.knob.setOpacity(0.4);
		this.plus.setOpacity(0.4);
		this.minus.setOpacity(0.4);
		this.counter.setOpacity(0.4);
		this.counter.className = "ta_knob_counter_off";
		this.hideReachability();
	},
	enable: function(){
		this.disabled = false;
		this.knob.setOpacity(1);
		this.plus.setOpacity(1);
		this.minus.setOpacity(1);
		this.counter.setOpacity(1);
		this.counter.className = "ta_knob_counter";
		this.renderReachability();
	},
	
	setReachabilitySet: function(/** Array */ rs){
		this.reachabilitySet.length = 0;
		for(var i = 0; i < rs.length; i++){
			this.reachabilitySet[i] = "" + rs[i].toFixed(1);
		}
		this.renderReachability();
		this.setStatus(0);
	},
	hideReachability: function(){
		for(var i = 1; i < 11; i++){
			$("ta_knob_reach_img_" + i).style.visibility = "hidden";
		}
	},
	renderReachability: function(){
		var rs = this.reachabilitySet; 
		for(var i = 1; i < 11; i++){
			$("ta_knob_reach_img_" + i).style.visibility = rs.indexOf("" + (i / 2).toFixed(1)) != -1 ? "visible" : "hidden";
		}
	},
	onSetStatus: function(){
		// hook
	}
};
// static members and methods
