#!/usr/bin/env python3

from cm_rgb.ctrl import LedChannel, LedMode, CMRGBController
import click


import click

@click.group(chain=True)
@click.pass_context
def setup_group(ctx):
    ctx.obj = {
            'ctrl': CMRGBController(),
            'lChannel': LedChannel.OFF,
            'fChannel': LedChannel.OFF,
            'rChannels': [LedChannel.OFF]*15,
            'mirage': [0,0,0],
            'save': False
    }
    pass


@setup_group.resultcallback()
@click.pass_context
def setup_finish(ctx,processors):
    c = ctx.obj['ctrl']

    # Configure mirage
    c.enableMirage(*ctx.obj['mirage'])

    # Map LED's
    c.assign_leds_to_channels(ctx.obj['lChannel'], ctx.obj['fChannel'], *ctx.obj['rChannels'])

    # Apply above
    c.apply()

    if ctx.obj.get('save',False):
        c.save()


@setup_group.command('logo')
@click.option('--color','color', default='#00FFFF')
@click.option('--mode', type=click.Choice(['off', 'static', 'breathe'], case_sensitive=False), default='static')
@click.option('--speed', type=click.IntRange(1, 5, clamp=True), default=3)
@click.option('--brightness', type=click.IntRange(1, 5, clamp=True), default=3)
@click.pass_context
def setup_logo(ctx, mode, color, brightness, speed):
    c = ctx.obj['ctrl']  

    color = color.lstrip('#')
    color = [int(color[i:i+2], 16) for i in (0, 2, 4)]

    speed = [0x3C,0x34,0x2c,0x20,0x18][speed-1]

    brightness = [0x33,0x66,0x99,0xCC,0xFF][brightness-1]

    if mode != 'off':
        c.set_channel(LedChannel.LOGO, LedMode[mode.upper()], brightness, color[0], color[1], color[2], speed)
        ctx.obj['lChannel'] = LedChannel.LOGO


@setup_group.command('fan')
@click.option('--color','color', default='#00FFFF')
@click.option('--mode', type=click.Choice(['off', 'static', 'breathe'], case_sensitive=False), default='static')
@click.option('--speed', type=click.IntRange(1, 5, clamp=True), default=3)
@click.option('--brightness', type=click.IntRange(1, 5, clamp=True), default=3)
@click.option('--mirage-red-freq',   type=click.IntRange(3, 32768, clamp=True))
@click.option('--mirage-green-freq', type=click.IntRange(3, 32768, clamp=True))
@click.option('--mirage-blue-freq',  type=click.IntRange(3, 32768, clamp=True))
@click.pass_context
def setup_fan(ctx, mode, color, brightness, speed, mirage_red_freq, mirage_green_freq, mirage_blue_freq):
    c = ctx.obj['ctrl']  

    color = color.lstrip('#')
    color = [int(color[i:i+2], 16) for i in (0, 2, 4)]

    speed = [0x3C,0x34,0x2c,0x20,0x18][speed-1]

    brightness = [0x33,0x66,0x99,0xCC,0xFF][brightness-1]

    if mode != 'off':
        c.set_channel(LedChannel.FAN, LedMode[mode.upper()], brightness, color[0], color[1], color[2], speed)
        ctx.obj['fChannel'] = LedChannel.FAN
        ctx.obj['mirage'] = [mirage_red_freq or 0, mirage_green_freq or 0, mirage_blue_freq or 0]


@setup_group.command('ring')
@click.option('--color','color', default='#00FFFF')
@click.option('--mode', type=click.Choice(['off', 'static', 'breathe', 'swirl','rainbow','cycle'], case_sensitive=False), default='static')
@click.option('--speed', type=click.IntRange(1, 5, clamp=True), default=3)
@click.option('--brightness', type=click.IntRange(1, 5, clamp=True), default=3)
@click.pass_context
def setup_ring(ctx, mode, color, brightness, speed):
    c = ctx.obj['ctrl']  

    color = color.lstrip('#')
    color = [int(color[i:i+2], 16) for i in (0, 2, 4)]

    
    if mode == 'cycle':
        speed = [0x72,0x68,0x64,0x62,0x61][speed-1]
        brightness = [0x10,0x20,0x40,0x60,0x7F][brightness-1]
    elif mode == 'rainbow':
        speed = [0x72,0x68,0x64,0x62,0x61][speed-1]
        brightness = [0x16,0x33,0x66,0x88,0xFF][brightness-1]
    elif mode == 'swirl':
        speed = [0x90,0x85,0x77,0x74,0x70][speed-1]
        brightness = [0x33,0x66,0x99,0xCC,0xFF][brightness-1]
    else:    
        speed = [0x3C,0x34,0x2c,0x20,0x18][speed-1]
        brightness = [0x33,0x66,0x99,0xCC,0xFF][brightness-1]

    if mode == 'cycle':
        c.set_channel(LedChannel.R_CYCLE, LedMode.CYCLE, brightness, color[0], color[1], color[2], speed)
        ctx.obj['rChannels'] = [LedChannel.R_CYCLE]*15

    elif mode == 'rainbow':
        c.set_channel(LedChannel.R_RAINBOW, LedMode.R_RAINBOW, brightness, color[0], color[1], color[2], speed)
        ctx.obj['rChannels'] = [LedChannel.R_RAINBOW]*15

    elif mode == 'static':
        c.set_channel(LedChannel.R_STATIC, LedMode.R_DEFAULT, brightness, color[0], color[1], color[2], speed)
        ctx.obj['rChannels'] = [LedChannel.R_STATIC]*15

    elif mode == 'breathe':
        c.set_channel(LedChannel.R_BREATHE, LedMode.R_DEFAULT, brightness, color[0], color[1], color[2], speed)
        ctx.obj['rChannels'] = [LedChannel.R_BREATHE]*15

    elif mode == 'swirl':
        c.set_channel(LedChannel.R_SWIRL, LedMode.R_DEFAULT, brightness, color[0], color[1], color[2], speed)
        ctx.obj['rChannels'] = [LedChannel.R_SWIRL]*15


@setup_group.command('save')
@click.pass_context
def save(ctx):
    ctx.obj['save'] = True


@click.group()
@click.pass_context
def main_group(ctx):
    pass


@main_group.command('restore')
@click.pass_context
def restore(ctx):
    CMRGBController().restore()


@main_group.command('version')
@click.pass_context
def version(ctx):
    print(CMRGBController().getVersion())


@main_group.command('add-udev-rule')
@click.pass_context
def add_udev_rule(ctx):
    import os
    rule = "SUBSYSTEM==\"usb\", ATTR{idVendor}==\"2516\", ATTR{idProduct}==\"0051\", TAG+=\"uaccess\", TAG+=\"udev-acl\""
    if os.geteuid() == 0:
        try: 
            with open("/etc/udev/rules.d/60-cm-rgb.rules","w") as f:
                f.write(rule)
                print("Created /etc/udev/rules.d/60-cm-rgb.rules")
                print("udev should apply new rule automatically. If not, try running 'sudo udevadm trigger'.")
        
        except:
            print("Failed to create /etc/udev/rules.d/60-cm-rgb.rules")
            raise
    else:
        print("This command must be run as root in order to create udev rule. (sudo cm-rgb-cli add-udev-rule)")
        print("You can also do this manually by creating /etc/udev/rules.d/60-cm-rgb.rules with following content:")
        print(rule)

main_group.add_command(setup_group,'set')

if __name__ == '__main__':
    main_group()
