define_namespace("com.homeCenter.ui.common.Slider");
com.homeCenter.ui.Control.extend("com.homeCenter.ui.common.Slider", {
	metadata: {
		properties: {
			value: {
				type: "float",
				defaultValue: 0.0
			},
			min: {
				type: "float",
				defaultValue: 0.0
			},
			max: {
				type: "float",
				defaultValue: 0.0
			},
			step: {
				type: "float",
				defaultValue: 0.5
			},
			color: {
				type: "com.homeCenter.css.Color", 
				defaultValue: null
			},
			enabled: {
				type: "boolean",
				defaultValue: true
			}
		},
		
		aggregations: {
			input: {
				type: "com.homeCenter.ui.common.Input",
				multiple: false
			}
		},
		
		events: {
			change: {}
		}
	},
	
	constructor: function(props) {
		this.base(props);
		
		this.setAggregation("input", new com.homeCenter.ui.common.Input({
			width: "35px",
			align: com.homeCenter.ui.common.InputAlign.RIGHT,
			change: jQuery.proxy(this._onInputChange, this)
		}));
	},
	
	onBeforeRendering: function() {
		this.getAggregation("input").setDisabled(!this.getEnabled(), true);
	},
	
	render: function(oRm) {
		var iPosX = (((this.getValue() - this.getMin()) / this.getMax()) * 100);
		
		oRm.write("<div");
		oRm.writeControlData(this);
		if(!this.getEnabled()) {
			oRm.addClass("disabled");
		}
		oRm.writeClasses();
		oRm.writeStyles();
		oRm.write(">");
		
		// Line
		oRm.write("<div");
		oRm.addClass("hcUISliderLine");
		oRm.writeClasses();
		oRm.writeStyles();
		oRm.write(">");
		
		// Indicator
		oRm.write("<div");
		oRm.addClass("hcUISliderLineIndicator");
		oRm.writeClasses();
		if(this.getColor()) {
			oRm.addStyle("background-color", this.getColor());
		}
		oRm.addStyle("width", iPosX + "%");
		oRm.writeStyles();
		oRm.write(">");
		oRm.write("</div>");
		
		// Tooltip
		oRm.write("<div");
		oRm.addClass("hcUISliderTooltip");
		oRm.writeClasses();
		oRm.addStyle("display", "none");
		if(this.getColor()) {
			oRm.addStyle("background-color", this.getColor());
		}
		oRm.addStyle("left", iPosX + "%");
		oRm.writeStyles();
		oRm.write(">");
		oRm.write("</div>");

		// Dragger
		oRm.write("<div");
		oRm.addClass("hcUISliderDragger");
		oRm.writeClasses();
		if(this.getColor()) {
			oRm.addStyle("background-color", this.getColor());
		}
		oRm.addStyle("left", iPosX + "%");
		oRm.writeStyles();
		oRm.write(">");
		oRm.write("</div>");
		
		// Dragger layer
		oRm.write("<div");
		oRm.addClass("hcUISliderDraggerLayer");
		oRm.writeClasses();
		if(this.getColor()) {
			oRm.addStyle("background-color", this.getColor());
		}
		oRm.addStyle("left", iPosX + "%");
		oRm.writeStyles();
		oRm.write(">");
		oRm.write("</div>");
		
		
		oRm.write("</div>");
		
		// Input
		oRm.write("<div");
		oRm.addClass("hcUISliderInput");
		oRm.writeClasses();
		oRm.writeStyles();
		oRm.write(">");
		this.getAggregation("input").setValue(this.getValue(), true);
		oRm.renderAggregation(this.getAggregation("input"));
		oRm.write("</div>");

		// Event handler
		oRm.write("<div");
		oRm.addClass("hcUISliderHandler");
		oRm.writeClasses();
		oRm.writeStyles();
		oRm.write(">");


		oRm.write("</div>");
		
		oRm.write("</div>");
	},
	
	onAfterRendering: function() {
		
	},
	
	onVmousedown: function(oEvent) {
		if(!this.getEnabled()) {
			return;
		}

		var $dragger = $(oEvent.target);
		if(!$dragger.hasClass("hcUISliderHandler") && !$dragger.hasClass("hcUISliderDragger") && !$dragger.hasClass("hcUISliderDraggerLayer")) {
			return;
		}
		
		oEvent.stopPropagation();
		//oEvent.preventDefault();
		
		this.$().find(".hcUISliderTooltip")
			.text(this.getValue())
			.fadeIn();
		this.$().find(".hcUISliderDragger").animate({
			width: "40px",
			height: "40px",
			"margin-left": "0px",
			"margin-top": "-20px"
		});
		
		this.$().find(".hcUISliderDraggerLayer").animate({
			width: "175%",
			height: "175%",
			"margin-left": "-37.5%",
			"margin-top": "-37.5%",
			opacity: 0.5
		});
		
		this._onMove(oEvent);
		$("body").addClass("selectionDisabled");
		$(document).on("vmousemove", jQuery.proxy(this._onMove, this));
		$(document).on("vmouseup", jQuery.proxy(this._onEnd, this));
		
		//return false;
	},
	
	_onMove: function(oEvent) {
		var $target = this.$().find(".hcUISliderHandler");
		var iPosX = oEvent.clientX;
		var iOffset = this.$().offset().left;
		var iMaxWidth = this.$().find(".hcUISliderLine").width();
		var fValue = 0;

		oEvent.stopPropagation();
		//oEvent.preventDefault();
		
		iPosX -= iOffset;
		
		if(iPosX < 0 || iPosX > iMaxWidth) {
			return;
		}
		
		fValue = this.calculate(iPosX, iMaxWidth);
		this.getAggregation("input").setValue(fValue);
		
		this.$().find(".hcUISliderDragger").css({
			left: (iPosX - ($target.width() / 2)) + "px"
		});
		this.$().find(".hcUISliderTooltip").css({
			left: (iPosX - ($target.width() / 2)) + "px"
		});
		this.$().find(".hcUISliderLineIndicator").css({
			width: ((iPosX / iMaxWidth) * 100) + "%"
		});
		
		this.$().find(".hcUISliderTooltip").text(fValue);
		
		//return false;
	},
	
	_onEnd: function(oEvent) {
		var fMaxValue = this.$().find(".hcUISliderLine").width();
		var fValue = this.$().find(".hcUISliderLineIndicator").width();
		
		fValue = this.calculate(fValue, fMaxValue);

		oEvent.stopPropagation();
		oEvent.preventDefault();
		$(document).off("vmousemove", this._onMove);
		$(document).off("vmouseup", this._onEnd);
		$("body").removeClass("selectionDisabled");

		this.$().find(".hcUISliderTooltip").fadeOut();
		this.$().find(".hcUISliderDragger").animate({
			width: "25px",
			height: "25px",
			"margin-left": "7px",
			"margin-top": "-15px"
		});
		
		this.$().find(".hcUISliderDraggerLayer").animate({
			width: "100%",
			height: "100%",
			"margin-left": "0%",
			"margin-top": "0%",
			opacity: 0
		});
		
		// Stop firing event when the new value is the same as before
		if(this.getValue() === fValue) {
			return;
		}
		
		this.setProperty("value", fValue, true);
		this.getAggregation("input").setValue(fValue);
		
		this.fireChange({
			value: fValue
		});
		
		//return false;
	},
	
	calculate: function(fValue, fMaxValue) {
		fValue = fValue / fMaxValue;
		fValue = ((this.getMax() - this.getMin()) * fValue) + this.getMin();
		fValue = this.round(fValue, 1, this.getStep());
		
		if(fValue < this.getMin()) {
			fValue = this.getMin();
		}
		
		if(fValue > this.getMax()) {
			fValue = this.getMax();
		}
		
		return fValue;
	},
	
	round: function(number) {
	    return (Math.round(number * 2) / 2).toFixed(1);
	},
	
	_onInputChange: function(oEvent) {
		if(!this.getEnabled()) {
			return;
		}
		
		var iValue = parseFloat(oEvent.getSource().getValue());
		
		if(isNaN(iValue)) {
			return;
		}
		
		if(iValue < this.getMin()) {
			iValue = this.getMin();
			this.getAggregation("input").setValue(iValue);
		}
		
		if(iValue > this.getMax()) {
			iValue = this.getMax();
			this.getAggregation("input").setValue(iValue);
		}
		
		// Stop firing event when the new value is the same as before
		if(this.getValue() === iValue) {
			return;
		}
		
		this.setValue(oEvent.getSource().getValue());
		this.fireChange({
			value: this.getValue()
		});
	}
});