import util from 'util';
import events from 'events';

let Light = function () {
	this.lightOn = true;
	this.brightness = 0.5;
	this.colorTemp = 0.5;
	this.color = 0.5;
	this.saturation = 0.5;
	this.positionX = 3;
	this.positionY = 97.5;
	this.formatedColor = this.formatColor(this.color, this.saturation);
};

util.inherits(Light, events.EventEmitter);

Light.prototype.setLightOn = function (lightOn) {
	if (this.lightOn != lightOn) {
		this.lightOn = lightOn;
		this.emit('lightOn', lightOn);
	}
};

Light.prototype.setBrightness = function (brightness) {
	if (this.brightness != brightness) {
		this.brightness = brightness;
		this.emit('brightness', brightness);
	}
};
Light.prototype.formatBrightness = function (brightness) {
	return "" + parseInt((brightness)*100) + "%";
};

Light.prototype.setColorTemp = function (colorTemp) {
	if (this.colorTemp != colorTemp) {
		this.colorTemp = colorTemp;
		this.emit('colorTemp', colorTemp);
	}
};

Light.prototype.setColorTempPosition = function (x, y) {
	if (this.positionX != x) {
		this.positionX = x;
	}
	if (this.positionY != y) {
		this.positionY = y;
	}
};

Light.prototype.formatColorTemp = function (colorTemp) {
	return "" + parseInt((5400 - 2700) * colorTemp + 2700) + "K";
};

Light.prototype.setColor = function (color, saturation) {
	if (this.color != color || this.saturation != saturation) {
		this.color = color;
		this.saturation = saturation;
		this.formatedColor = this.formatColor(this.color, this.saturation);
		this.emit('color', color, saturation);
	}
};
let evaluateColor = function (fraction, sr, sg, sb, sa, er, eg, eb, ea) {
	let rr = Math.max(0, Math.min(255, sr + (fraction * (er - sr))));
	let rg = Math.max(0, Math.min(255, sg + (fraction * (eg - sg))));
	let rb = Math.max(0, Math.min(255, sb + (fraction * (eb - sb))));
	let ra = Math.max(0, Math.min(1, sa + (fraction * (ea - sa))));
	return [rr, rg, rb, ra];
}
let blendColor = function (sr, sg, sb, sa, dr, dg, db, da) {
	if (sa == 0 && da == 0) {
		return [0, 0, 0, 0];
	}
	let a = 1 - (1 - sa) * (1 - da); // alpha
	let r = Math.round((sr * sa / a) + (dr * da * (1 - sa) / a)); // red
	let g = Math.round((sg * sa / a) + (dg * da * (1 - sa) / a)); // green
	let b = Math.round((sb * sa / a) + (db * da * (1 - sa) / a)); // blue
	return [r, g, b, a];
};
Light.prototype.formatColor = function (color, saturation) {
	let sc, ec;
	let f;
	if (color < 0.18) {
		sc = [0xFF, 0x0, 0x0, 1];
		ec = [0xF2, 0xFF, 0x0, 1];
		f = color / 0.18;
	} else if (color < 0.35) {
		sc = [0xF2, 0xFF, 0, 1];
		ec = [0x0, 0xFF, 0x20, 1];
		f = (color - 0.18) / (0.35 - 0.18);
	} else if (color < 0.52) {
		sc = [0x0, 0xFF, 0x20, 1];
		ec = [0x0, 0xF5, 0xFF, 1];
		f = (color - 0.35) / (0.52 - 0.35);
	} else if (color < 0.71) {
		sc = [0x0, 0xF5, 0xFF, 1];
		ec = [0x06, 0x0, 0xFF, 1];
		f = (color - 0.52) / (0.71 - 0.52);
	} else if (color < 0.89) {
		sc = [0x06, 0x0, 0xFF, 1];
		ec = [0xF4, 0x0, 0xFF, 1];
		f = (color - 0.71) / (0.89 - 0.71);
	} else {
		sc = [0xF4, 0x0, 0xFF, 1];
		ec = [0xFF, 0x0, 0x0, 1];
		f = (color - 0.89) / (1 - 0.89);
	}
	let dest = evaluateColor(f, sc[0], sc[1], sc[2], sc[3], ec[0], ec[1], ec[2], ec[3]);
	let src = evaluateColor(saturation, 0xFF, 0xFF, 0xFF, 1, 0xFF, 0xFF, 0xFF, 0x0);
	let c = blendColor(src[0], src[1], src[2], src[3], dest[0], dest[1], dest[2], dest[3]);
	return `rgba(${c[0]},${c[1]},${c[2]},${c[3]})`;
};

export default new Light;