export function Name() { return "DRGB V3"; }
export function VendorId() { return 0x2023; }
export function ProductId() { return [0x1226, 0x1221, 0x1209]; }
export function Publisher() { return "YanZhi"; }
export function Size() { return [0, 0]; }
export function DefaultPosition(){ return [160, 100]; }
export function DefaultScale(){ return 1.0; }
export function Type() { return "Hid"; }
export function SubdeviceController(){ return true; }
export function DefaultComponentBrand() { return "CompGen"; }

export function ControllableParameters() {
	return [
		{"property":"seek", "group":"lighting", "label":"呼吸定位设备", description:"启用后，未添加模型的接口单色呼吸，根据接口颜色定位设备,设置完成后推荐关闭!推荐关闭！","type":"boolean", "default":"true"},
		{"property":"Turbo", "group":"lighting", "label":"高刷新率", description:"启用后，提升刷新率，但会占用更多系统资源,玩游戏等高负载使用时推荐关闭!！", "type":"boolean", "default":"true"},
		// {"property":"LightingMode", "group":"lighting", "label":"模式", "type":"combobox", "values":["Canvas", "Forced"], "default":"Canvas", "tooltip":"Canvas：画布模式__Forced：单色模式!"},
		// {"property":"forcedColor", "group":"lighting", "label":"单色", "min":"0", "max":"360", "type":"color", "default":"#FF0000"},
		{"property":"ColorCompression_enable", "group":"", "label":"启用颜色压缩（减少光谱并提高帧速率）", description:"推荐开启,设备灯珠越多效果越明显好", "type":"boolean", "default":"true"},
//		{"property":"HWL_led", "group":"", "label":"单击一次 保存开机灯效接口灯珠数量", "type":"boolean", "default":"false", "tooltip":"提醒：关闭[呼吸定位]，打开[Device Enabled]，关闭[调试开机灯效]。再 单击一次 保存每个接口灯珠数量"},
		{"property":"test_hwl", "group":"", "label":"调试开机灯效（软件灯效暂时无效）", description: "开启之后可以调试开机灯效，调试完成后最底下单击保存","type":"boolean", "default":"false"},
		{"property":"HWL_start", "group":"", "label":"开启开机灯效", description: "关闭：退出软件 则无灯效刷新，开启：退出软件或开机过程播放板载开机灯效!","type":"boolean", "default":"true"},
		{"property":"HWL_effectMode", "group":"", "label":"选择开机灯效", description: "Rainbow Wave彩虹通道/Color Shift单色循环/Color Breathe单色呼吸/Color Wave色波/Solid Color纯色/Meteor shower流星雨/Visor晴朗/Marquee跑马灯/ColorStrobing频闪/Sequential序列/Browse黑洞","type":"combobox", "values":["Rainbow Wave", "Color Shift","Color Breathe","Color Wave","Solid Color","Meteor shower","Visor","Marquee", "Color Strobing","Sequential", "Browse"], "default":"Rainbow Wave"},
		{"property":"HWL_effectSpeed", "group":"", "label":"减速开机灯效速度", description: "减速开机灯效的速度!","step":"1", "type":"number", "min":"0", "max":"2", "default":"1"},
		{"property":"HWL_direction", "group":"", "label":"开机灯效方向", description: "Front正向__After反向!","type":"combobox", "values":["Front", "After"], "default":"Front"},
		{"property":"HWL_random", "group":"", "label":"开机灯效颜色随机", description: "硬件照明灯效颜色随机（彩虹灯效无效）!","type":"boolean", "default":"true"},
		{"property":"HWL_color", "group":"", "label":"选择纯色或呼吸颜色1", description: "开机灯效颜色1","min":"0", "max":"360", "type":"color", "default":"#FF0000"},
		{"property":"HWL_colorB", "group":"", "label":"选择纯色或呼吸颜色2", description: "开机灯效颜色2","min":"0", "max":"360", "type":"color", "default":"#0000FF"},
		{"property":"HWL_brightness", "group":"", "label":"全局亮度", description: "修改全局亮度!包括开机灯效同样有效！（请勿频繁修改）","step":"10", "type":"number", "min":"0", "max":"100", "default":"60"},
		{"property":"HWL_enable", "group":"", "label":"单击一次 保存开机灯效和亮度", description: "调整完效果后 单击一次 修改开机灯效,3秒内保存一次!保存完关闭[调试开机灯效]否则软件灯效无效","type":"boolean", "default":"false"},
		{"property":"HWL_mode", "group":"", "label":"切换控制盒模式", description: "切换控制盒模式DRGB__华硕AURA__ICUE24", "type":"combobox", "values":["DRGB", "AURA", "ICUE8", "ICUE16", "ICUE24", "ICUE30", "ICUEBUT"], "default":"DRGB"},
			
			];
}

const ProductNames = {
	0x1226: "DRGB CORE V3",
	0x1221: "DRGB ULTRA V3F",
	0x1209: "DRGB LED V3",
};
const ChannelALed = 120;
const ChannelBLed = 60;
const ChannelCLed = 60;
const DeviceMaxLedLimit = 1800;
const ChannelArray =
[
	["Channel A1", ChannelALed],
	["Channel A2", ChannelALed],
	["Channel A3", ChannelALed],
	["Channel A4", ChannelALed],
	["Channel A5", ChannelALed],
	["Channel A6", ChannelALed],
	["Channel A7", ChannelALed],
	["Channel A8", ChannelALed],

	["Channel B1", ChannelBLed],
	["Channel B2", ChannelBLed],
	["Channel B3", ChannelBLed],
	["Channel B4", ChannelBLed],
	["Channel B5", ChannelBLed],
	["Channel B6", ChannelBLed],
	["Channel B7", ChannelBLed],
	["Channel B8", ChannelBLed],

	["Channel C1", ChannelCLed],
	["Channel C2", ChannelCLed],
	["Channel C3 Strimer GPU*3", 324],
	["Channel C4", ChannelCLed],
	["Channel C5 Strimer GPU*2", 216],
	["Channel C6", ChannelCLed],
	["Channel C7", ChannelCLed],
	["Channel C8", ChannelCLed],

	["Strimer ATX 24Pin", 240],

];

function SetupChannels() {
	device.SetLedLimit(DeviceMaxLedLimit);
	for(let i = 0; i < MChannel; i++) {
		device.addChannel(ChannelArray[i][0], ChannelArray[i][1]);
	}
}


const vKeyNames = [];
const vKeyPositions = [];
const MaxLedsInPacket = 21;
const ALeds = [0,20,0,20,0,20,0,20,0,20,0,20];
const AOLeds = [0,21,0,21,0,21,0,21,0,21,0,21];
const GDLeds = [0,27,0,27,0,27,0,27];
const GTLeds = [0,27,0,27,0,27,0,27,0,27,0,27];
const FZLeds = [0,0,0,0,0,0,0,0,0,0];
const ALed = 120;
const AOLed = 126;
const GDLed = 108;
const GTLed = 162;
const d30 = 4646;
const d8 = 4617;
let MChannel = 16;
let lastHWLchange = 0;
let HWLupdateRequested = false;
let	lastsaveHWLchange = 0;
let	lastsaveRequested = false;

export function LedNames() {
	return vKeyNames;
}

export function LedPositions() {
	return vKeyPositions;
}



export function Initialize() {
	device.setName(ProductNames[device.productId()]);
	if(device.productId()==d30) MChannel = 25;
	else if(device.productId()==d8) MChannel = 8;
	SetupChannels();
	requestFirmwareVersion();
	if(Turbo) device.setFrameRateTarget(60);
}

function compareFirmwareVersion() {
	const firmwarePacket = device.read([0x00],  6 );
	const FirmwareVersion = firmwarePacket[2] + "." + firmwarePacket[3] + "." + firmwarePacket[4]+ "." + firmwarePacket[5];
	device.log("DRGB Firmware version: " + FirmwareVersion);
}

function requestFirmwareVersion() {
	const packet = [ 0x00, 0x02 ];
	device.write(packet, 65);
	compareFirmwareVersion();
}

export function Render() {
	if(!test_hwl){
		SendChannel(); 
	}
	else if(HWLupdateRequested == true) {
		const currentTime = Date.now();
		if(currentTime - lastHWLchange >= 1000) {
			lastHWLchange = Date.now();
			updateHWLsettings(1);
		}
	}
	else if(lastsaveRequested == true){
		const saveTime = Date.now();
		if(saveTime - lastsaveHWLchange >= 500){
			lastsaveHWLchange = Date.now();
			updateHWLsettings(0);
		}
	}
}

function SendChannel() {
	let RGBData = [];
	let ArrayData = [];
	const multiplier = ColorCompression_enable ? 2 : 1;
	const compressedRGB = [];

	for(let Channel = 0; Channel < MChannel; Channel++) {
	let ChannelData = [];
	const componentChannel = device.channel(ChannelArray[Channel][0]);
	let ChannelLedCount = componentChannel.ledCount > 800 ? 800 : componentChannel.ledCount;
	if(!ChannelLedCount){
		if(seek){
		ChannelLedCount = 30;
		const pulseColor = device.getChannelPulseColor(ChannelArray[Channel][0]);
		ChannelData = device.createColorArray(pulseColor, ChannelLedCount, "Inline");
		}
	}
	// else if(LightingMode === "Forced") {
	// 	ChannelData = device.createColorArray(forcedColor, ChannelLedCount, "Inline");
	// }
	else {
		ChannelData = componentChannel.getColors("Inline");
	}

	if(Channel == 18 || Channel == 24){
		let lmap = sch_Ledmap(ChannelLedCount);
		ArrayData.push(...lmap);
		if(lmap.length != 2){
			Channel += 5;
		}
	}else if(Channel == 20 && ChannelLedCount == GDLed){
		ArrayData.push(...GDLeds);
		Channel += 3;
	}else{
		let QLedCount = (ChannelLedCount & 0xFFFF) >> 8;
		let PLedCount = ChannelLedCount & 0xFF;
		ArrayData.push(QLedCount,PLedCount);
	}
	RGBData.push(...ChannelData);
	}

	let RGBLedCount = RGBData.length / 3 ;
	if(ColorCompression_enable) {
		for(let runCount = 0; runCount < RGBLedCount / multiplier; runCount++) {
			compressedRGB[(runCount*3)] = (((RGBData[(runCount*6)] & 0xFF) >> 4) | ((((RGBData[(runCount*6)+1] & 0xFF) >> 4) & 0xFF) << 4));
			compressedRGB[(runCount*3)+1] = (((RGBData[(runCount*6)+2] & 0xFF) >> 4) | ((((RGBData[(runCount*6)+3] & 0xFF) >> 4) & 0xFF) << 4));
			compressedRGB[(runCount*3)+2] = (((RGBData[(runCount*6)+4] & 0xFF) >> 4) | ((((RGBData[(runCount*6)+5] & 0xFF) >> 4) & 0xFF) << 4));
		}
	}

	const NumPackets = Math.ceil(RGBLedCount / MaxLedsInPacket / multiplier) + 100;
	const compressionenable = ColorCompression_enable == true ? 0xAA : 0xBB;
	let Arraypacket = [0x00,0x60,compressionenable];
	Arraypacket = Arraypacket.concat(ArrayData);
	device.write(Arraypacket, 65);
	for(let CurrPacket = 100; CurrPacket < NumPackets; CurrPacket++) {
		CurrPacket = CurrPacket == (NumPackets-1) ? CurrPacket+100 : CurrPacket;
		let packet = [0x00, CurrPacket];
		packet = packet.concat(ColorCompression_enable ? compressedRGB.splice(0, 63) : RGBData.splice(0, 63));
		device.write(packet, 65);
	}
}

function sch_Ledmap(led) {
	let ledmap = [];
		if(led == GTLed){
			return GTLeds;
		}else if(led == ALed){
			return ALeds;
		}else if(led == AOLed){
			return AOLeds;
		}else{
			ledmap[0] = (led & 0xFFFF) >> 8;
			ledmap[1] = led & 0xFF;
			return ledmap;
		}
}

function hexToRgb(hex) {
	const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
	const colors = [];
	colors[0] = parseInt(result[1], 16);
	colors[1] = parseInt(result[2], 16);
	colors[2] = parseInt(result[3], 16);

	return colors;
}
export function onTurboChanged(){ 
	if(Turbo){
		device.setFrameRateTarget(60);
	}else{
		device.setFrameRateTarget(30);
	}
}
export function onHWL_startChanged(){ HWL_setting_updated(); }
export function onHWL_effectModeChanged(){ HWL_setting_updated(); }
export function onHWL_effectSpeedChanged(){ HWL_setting_updated(); }
export function onHWL_directionChanged(){ HWL_setting_updated(); }
export function onHWL_randomChanged(){ HWL_setting_updated(); }
export function onHWL_colorChanged(){ HWL_setting_updated(); }
export function onHWL_colorBChanged(){ HWL_setting_updated(); }
export function onHWL_brightnessChanged(){ HWL_setting_brightness(0); }
export function onHWL_modeChanged(){ HWL_setting_mode(); }
export function onHWL_enableChanged(){ 
	lastHWLchange = Date.now();
	HWLupdateRequested = true; 
}

function HWL_setting_updated() {
	lastsaveHWLchange = Date.now();
	lastsaveRequested = true ; 
}

function HWL_ledSave(save){
	const packet = [0x00, 0x35, save];
	device.write(packet, 65); 
	device.pause(200);
}

function HWL_setting_brightness(save) {
	const packet = [0x00, 0x39, 0x00, HWL_brightness,save];
	device.write(packet, 65);
	device.log(packet);
	device.pause(200);
}

function HWL_setting_mode() {
	let hwlmode;		
	if(HWL_mode == "DRGB") { hwlmode = 0x01; } else if(HWL_mode == "AURA") { hwlmode = 0x02; } else if(HWL_mode == "ICUE8") { hwlmode = 0x08; } else if(HWL_mode == "ICUE16") { hwlmode = 0x10; } else if(HWL_mode == "ICUE24") { hwlmode = 0x18; } else if(HWL_mode == "ICUE30") { hwlmode = 0x1E; }else if(HWL_mode == "ICUEBUT") { hwlmode = 0xF0; } 
	const packet = [0x00, 0x45, 0x35, hwlmode];
	device.write(packet, 65);
}

function updateHWLsettings(save) {
		HWL_ledSave(save);
		HWL_setting_brightness(save);
		HWLupdateRequested = false;
		lastsaveRequested = false;
		let hwleffectMode;	
		let hwldirection;	
		if(HWL_effectMode == "Rainbow Wave") { hwleffectMode = 0; } 
		else if(HWL_effectMode == "Color Shift") { hwleffectMode = 1; } 
		else if(HWL_effectMode == "Color Breathe") { hwleffectMode = 2; } 
		else if(HWL_effectMode == "Color Wave") { hwleffectMode = 3; } 
		else if(HWL_effectMode == "Solid Color") { hwleffectMode = 4; }
		else if(HWL_effectMode == "Meteor shower") { hwleffectMode = 5; }
		else if(HWL_effectMode == "Visor") { hwleffectMode = 6; } 
		else if(HWL_effectMode == "Marquee") { hwleffectMode = 7; } 
		else if(HWL_effectMode == "Color Strobing") { hwleffectMode = 8; } 
		else if(HWL_effectMode == "Sequential") { hwleffectMode = 9; }
		else if(HWL_effectMode == "Browse") { hwleffectMode = 11; }
		if(HWL_direction == "Front") { hwldirection = 1; } 
		else if(HWL_direction == "After") { hwldirection = 0; } 
		const random = HWL_random == true ? 0x01 : 0x00;
		const start = HWL_start == true ? 0x0F : 0xF0;
		const hwlcolor = hexToRgb(HWL_color);
		const hwlcolorB = hexToRgb(HWL_colorB);
		const packet = [0x00, 0x35, 0x00, 0x00, 0x00, hwleffectMode, HWL_effectSpeed, hwldirection, random, 0x00, hwlcolor[0], hwlcolor[1], hwlcolor[2], hwlcolorB[0], hwlcolorB[1], hwlcolorB[2], 0x00, 0x00, 0x00, 0x00, 0x00, start, save ];
		device.write(packet, 65);
		device.log(packet);
}

export function Validate(endpoint) {
	return endpoint.interface === 0 || endpoint.interface === 2;
}

export function ImageUrl() {
	return "https://gitee.com/drgb-controller/drgb/raw/master/Image/DRGBV3.png"
}