export function Name() { return "GG75"; }
export function VendorId() { return 0xFDFE; }
export function ProductId() { return 0x000A; }
export function Publisher() { return "GG75"; }
export function Documentation(){ return "GG75"; }
export function Size() { return [17, 6]; }
export function DefaultPosition(){return [10, 100]; }
export function DefaultScale(){return 8.0}
/* global
shutdownColor:readonly
LightingMode:readonly
forcedColor:readonly
*/
export function ControllableParameters() {
	return [
		{"property":"LightingMode", "group":"lighting", "label":"Lighting Mode", "type":"combobox", "values":["Canvas", "Forced"], "default":"Canvas"},
		{"property":"forcedColor", "group":"lighting", "label":"Forced Color", "min":"0", "max":"360", "type":"color", "default":"009bde"},
	];
}

//Plugin Version: Built for Protocol V1.0.4

const vKeys =
    [
	 0,   1,   2,   3,   4,    5,   6,   7,    8,    9,   10,  11,  12,  13, 
	14,  15,  16,  17,  18,   19,  20,  21,   22,   23,   24,  25,  26,  27,       
	28,  29,  30,  31,  32,   33,  34,  35,   36,   37,   38,  39,  40,  41,  42,
	43,  44,  45,  46,  47,  48,   49,  50,  51,   52,   53,   54,  55,  56,  57,  58,  59,   
	60,  61,  62,  63,  64,   65,  66,  67,   68,   69,   70,  71,  72,  73,  74,  75, 
	76,  77,  78,  79,   80,   81,   82, 83,   84, 85, 
	86,87,88,89,90,92,93,94,95,96
    ];

const vKeyNames =
    [
	"ESC", "F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12","SLCT",
	"GRV", "1","2","3","4","5","6","7","8","9","0","MINS","EQL","BSPC",
	"TAB", "Q","W","E","R","T","Y","U","I","O","P","LBRC","RBRC","ENTER","BSLS",
	"CAPS","CAPS","A","S","D","F","G","H","J","K","L","SCLN","QUOT","BSLS","ENTER","DEL","PGUP",
	"LSFT","LSFT","NUBS","Z","X","C","V","B","N","M","COMM","DOT","SLSH","RSFT","UP","PGDN",
	"LCTL","LGUI","LALT","SPC","RALT","MO(1)","RCTL","LEFT","DOWN","RGHT",
	"BL0","BL1","BL2","BL3","BL4","BL5","BL6","BL7","BL8","BL9",
    ];
const vKeyPositions =
    [
        [0,0],[1,0],[2,0],[3,0],[4,0],[5,0],[6,0],[7,0],[8,0],[9,0],[10,0],[11,0],[12,0],[13,0],
        [0,1],[1,1],[2,1],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1],[9,1],[10,1],[11,1],[12,1],[13,1],
        [0,2],[1,2],[2,2],[3,2],[4,2],[5,2],[6,2],[7,2],[8,2],[9,2],[10,2],[11,2],[12,2],[13,2],[14,2],       
        [0,3],[1,3],[2,3],[3,3],[4,3],[5,3],[6,3],[7,3],[8,3],[9,3],[10,3],[11,3],[12,3],[13,3],[14,3], [15,3], [16,3], //DEL
		[0,4],[1,4],[2,4],[3,4],[4,4],[5,4],[6,4],[7,4],[8,4],[9,4],[10,4],[11,4],[12,4],[13,4],[14,4], [15,4], 
        [0,5],[1,5],[2,5],                  [6,5],                  [10,5],[11,5],[12,5],[13,5],[14,5], [15,5],
		[0,6],[1,6],[2,6],[6,6],                                    [15,0],[14,0],[12,6],[13,6],[14,6],[15,6],	// [15,0],[14,0]媒体
    ];

let LEDCount = 0;
let IsViaKeyboard = false;
const MainlineQMKFirmware = 1;
const VIAFirmware = 2;
const PluginProtocolVersion = "1.0.4"

export function LedNames() 
{
    return vKeyNames;
}

export function LedPositions() 
{
    return vKeyPositions;
}

export function Initialize() 
{
    requestFirmwareType();
    requestQMKVersion();
    requestSignalRGBProtocolVersion();
    requestUniqueIdentifier();
    requestTotalLeds();
    effectEnable();

}

export function Render() 
{
    sendColors();
}

export function Shutdown() 
{
    effectDisable();
}

function commandHandler()
{
    let readCounts = [];

    do
    {
        let returnpacket = device.read([0x00], 32, 10);
        processCommands(returnpacket);

        readCounts.push(device.getLastReadSize());

        // Extra Read to throw away empty packets from Via
        // Via always sends a second packet with the same Command Id.
        if(IsViaKeyboard)
        {
            device.read([0x00], 32, 10);
        }
    }
    while(device.getLastReadSize() > 0)

}

function processCommands(data)
{
    switch(data[1]) 
    {
        case 0x21:
            returnQMKVersion(data);
            break;
        case 0x22:
            returnSignalRGBProtocolVersion(data);
            break;
        case 0x23:
            returnUniqueIdentifier(data);
            break;
        case 0x24:
            sendColors();
            break;
        case 0x27:
            returnTotalLeds(data);
            break;
        case 0x28:
            returnFirmwareType(data);
            break;
    }
}

function requestQMKVersion() //Check the version of QMK Firmware that the keyboard is running
{
    device.write([0x00, 0x21], 32);
    device.pause(30);
    commandHandler();
}

function returnQMKVersion(data)
{
    let QMKVersionByte1 = data[2];
    let QMKVersionByte2 = data[3];
    let QMKVersionByte3 = data[4];
    device.log("QMK Version: " + QMKVersionByte1 + "." + QMKVersionByte2 + "." + QMKVersionByte3);
    device.pause(30);
}

function requestSignalRGBProtocolVersion() //Grab the version of the SignalRGB Protocol the keyboard is running
{
    device.write([0x00, 0x22],32);  
    device.pause(30);
    commandHandler();
}

function returnSignalRGBProtocolVersion(data)
{
    let ProtocolVersionByte1 = data[2];
    let ProtocolVersionByte2 = data[3];
    let ProtocolVersionByte3 = data[4];

    let SignalRGBProtocolVersion = ProtocolVersionByte1 + "." + ProtocolVersionByte2 + "." + ProtocolVersionByte3;
    device.log(`SignalRGB Protocol Version: ${SignalRGBProtocolVersion}`);


    if(PluginProtocolVersion !== SignalRGBProtocolVersion)
    {
        device.notify("Unsupported Protocol Version: ", `This plugin is intended for SignalRGB Protocol version ${PluginProtocolVersion}. This device is version: ${SignalRGBProtocolVersion}`, 0)
    }

    device.pause(30);
}

function requestUniqueIdentifier() //Grab the unique identifier for this keyboard model
{
    device.write([0x00, 0x23],32);
    device.pause(30);
    commandHandler();
}

function returnUniqueIdentifier(data)
{
    let UniqueIdentifierByte1 = data[2];
    let UniqueIdentifierByte2 = data[3];
    let UniqueIdentifierByte3 = data[4];
    device.log("Unique Device Identifier: " + UniqueIdentifierByte1 + UniqueIdentifierByte2 + UniqueIdentifierByte3);
    device.pause(30);
}

function requestTotalLeds() //Calculate total number of LEDs
{
    device.write([0x00, 0x27],32);  
    device.pause(30);
    commandHandler();
}

function returnTotalLeds(data)
{
    LEDCount = data[2];
    device.log("Device Total LED Count: " + LEDCount);
    device.pause(30);
}

function requestFirmwareType()
{
    device.write([0x00, 0x28], 32);
    device.pause(30);
    commandHandler();
}

function returnFirmwareType(data)
{
    let FirmwareTypeByte = data[2];

    if(!(FirmwareTypeByte === MainlineQMKFirmware || FirmwareTypeByte === VIAFirmware))
    {
        device.notify("Unsupported Firmware: ", "Click Show Console, and then click on troubleshooting for your keyboard to find out more.", 0);
    }

    if(FirmwareTypeByte === MainlineQMKFirmware)
    {
        IsViaKeyboard = false;
        device.log("Firmware Type: Mainline");
    }

    if(FirmwareTypeByte === VIAFirmware)
    {
        IsViaKeyboard = true;
        device.log("Firmware Type: VIA");
    }

    device.pause(30);
}

function effectEnable() //Enable the SignalRGB Effect Mode
{
    device.write([0x00, 0x25],32);
    device.pause(30);
}

function effectDisable() //Revert to Hardware Mode
{
    device.write([0x00, 0x26],32);  
    device.pause(30);
}

function grabColors(shutdown = false) 
{
	let rgbdata = [];

	for(let iIdx = 0; iIdx < vKeys.length; iIdx++)
	{
		let iPxX = vKeyPositions[iIdx][0];
		let iPxY = vKeyPositions[iIdx][1];
		let color;

		if(shutdown)
		{
			color = hexToRgb(shutdownColor);
		}
		else if (LightingMode === "Forced")
		{
			color = hexToRgb(forcedColor);
		}
		else
		{
			color = device.color(iPxX, iPxY);
		}

		let iLedIdx = vKeys[iIdx] * 3;
		rgbdata[iLedIdx] = color[0];
		rgbdata[iLedIdx+1] = color[1];
		rgbdata[iLedIdx+2] = color[2];
	}

	return rgbdata;
}

function sendColors()
{
	let rgbdata = grabColors();

    const LedsPerPacket = 9;
    let BytesSent = 0;
    let BytesLeft = rgbdata.length;

    while(BytesLeft > 0)
    {
            const BytesToSend = Math.min(LedsPerPacket * 3, BytesLeft);
            StreamLightingData(Math.floor(BytesSent / 3), rgbdata.splice(0, BytesToSend))
    
            BytesLeft -= BytesToSend;
            BytesSent += BytesToSend;
    }
}

function StreamLightingData(StartLedIdx, RGBData)
{
	let packet = [0x00, 0x24, StartLedIdx, Math.floor(RGBData.length / 3)];

	packet.push(...RGBData);
	device.write(packet, 33);
}

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

	return colors;
}

export function Validate(endpoint) 
{
	return endpoint.interface === 1;
}

export function Image()
{
return ""
}