/*
 *
 *    Copyright (c) 2022 Project CHIP Authors
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

#include "LEDWidget.h"
#ifdef CFG_PLF_RV32
#include "asr_gpio.h"
#include "asr_pinmux.h"
#include "asr_pwm.h"
#define duet_pwm_dev_t asr_pwm_dev_t
#define duet_pwm_config_t asr_pwm_config_t
#define duet_pwm_para_chg asr_pwm_para_chg
#define duet_pwm_init asr_pwm_init
#define duet_pwm_start asr_pwm_start
#else
#include "duet_gpio.h"
#include "duet_pinmux.h"
#include "duet_pwm.h"
#endif
#include "AppConfig.h"
#include <platform/CHIPDeviceLayer.h>

/*******************************************************************************
 * Macro Definitions
 *******************************************************************************/
/* Allowed TCPWM compare value for maximum brightness */
#define LED_MAX_BRIGHTNESS (100u)

/* Allowed TCPWM compare value for minimum brightness*/
#define LED_MIN_BRIGHTNESS (0u)

#define PWM_LED_FREQ_HZ (1000u) /* in Hz */

/* subtracting from 100 since the LED is connected in active low configuration */
#define GET_DUTY_CYCLE(x) (100 - x)

// PWM period in micro seconds
#define LED_PWM_PERIOD_US (255u)

static void show_pwm(duet_pwm_dev_t * pwm_dev, uint8_t val)
{
    duet_pwm_config_t pwm_cfg;

    if (val < LED_MIN_BRIGHTNESS)
        val = LED_MIN_BRIGHTNESS;
    pwm_cfg.duty_cycle = (float) (val) / LED_PWM_PERIOD_US;
    pwm_cfg.freq       = PWM_LED_FREQ_HZ;

    duet_pwm_para_chg(pwm_dev, pwm_cfg);
}

static void init_pwm(duet_pwm_dev_t * pwm_dev, uint8_t ledNum, uint8_t val)
{
    pwm_dev->port              = ledNum;
    pwm_dev->config.duty_cycle = val;
    pwm_dev->config.freq       = PWM_LED_FREQ_HZ;
    pwm_dev->priv              = NULL;
    duet_pwm_init(pwm_dev);
}

void LEDWidget::Init(uint8_t ledNum)
{
    mLastChangeTimeMS = 0;
    mBlinkOnTimeMS    = 0;
    mBlinkOffTimeMS   = 0;
    mState            = 0;
    mbrightness       = LED_MIN_BRIGHTNESS;
    mHue              = 0;
    mSaturation       = 0;

    if (ledNum == LIGHT_RGB_GREEN)
    {
#ifdef CFG_PLF_RV32
        asr_pinmux_config(LIGHT_RGB_RED_PAD, PF_PWM);
#endif
        init_pwm(&pwm_led_g, ledNum, LED_MIN_BRIGHTNESS);
    }
    else if (ledNum == LIGHT_RGB_BLUE)
    {
#ifdef CFG_PLF_RV32
        asr_pinmux_config(LIGHT_RGB_BLUE_PAD, PF_PWM);
#endif
        init_pwm(&pwm_led_b, ledNum, LED_MIN_BRIGHTNESS);
    }
    else
    {
#ifdef CFG_PLF_RV32
        asr_pinmux_config(LIGHT_RGB_GREEN_PAD, PF_PWM);
#endif
        init_pwm(&pwm_led, ledNum, LED_MIN_BRIGHTNESS);
    }
}

void LEDWidget::Invert(void)
{
    Set(!mState);
}

void LEDWidget::Set(bool state)
{
    mLastChangeTimeMS = mBlinkOnTimeMS = mBlinkOffTimeMS = 0;
    DoSet(state);
}

bool LEDWidget::Get()
{
    return mState;
}

void LEDWidget::Blink(uint32_t changeRateMS)
{
    Blink(changeRateMS, changeRateMS);
}

void LEDWidget::Blink(uint32_t onTimeMS, uint32_t offTimeMS)
{
    mBlinkOnTimeMS  = onTimeMS;
    mBlinkOffTimeMS = offTimeMS;
    Animate();
}

void LEDWidget::Animate()
{
    if (mBlinkOnTimeMS != 0 && mBlinkOffTimeMS != 0)
    {
        uint64_t nowMS            = chip::System::SystemClock().GetMonotonicMilliseconds64().count();
        uint64_t stateDurMS       = ((mState) ? mBlinkOnTimeMS : mBlinkOffTimeMS);
        uint64_t nextChangeTimeMS = mLastChangeTimeMS + stateDurMS;

        if (nextChangeTimeMS < nowMS)
        {
            DoSet(!mState);
            mLastChangeTimeMS = nowMS;
        }
    }
}

void LEDWidget::DoSet(bool state)
{
    if (mState != state)
    {
        (state) ? PWM_start() : PWM_stop();
    }
    mState = state;
}

void LEDWidget::RGB_init()
{
    Init(LIGHT_RGB_RED);   // red light of RGB
    Init(LIGHT_RGB_GREEN); // green light of RGB
    Init(LIGHT_RGB_BLUE);  // blue light of RGB
}

void LEDWidget::PWM_start()
{
    if (!mState)
    {
        /* Start PWM to turn the LED on */
        if (0 != duet_pwm_start(&pwm_led))
        {
            ASR_LOG("PWM failed to start!");
        }

#if (LIGHT_SELECT == LIGHT_SELECT_RGB)
        /* Start PWM to turn the LED on */
        if (0 != duet_pwm_start(&pwm_led_g))
        {
            ASR_LOG("PWM failed to start!");
        }

        /* Start PWM to turn the LED on */
        if (0 != duet_pwm_start(&pwm_led_b))
        {
            ASR_LOG("PWM failed to start!");
        }
#endif
        mState = 1;
    }
}

void LEDWidget::PWM_stop()
{
    SetBrightness(LED_MIN_BRIGHTNESS);
    mbrightness = LED_MIN_BRIGHTNESS;
    mState      = 0;
}

void LEDWidget::SetBrightness(uint8_t brightness)
{
    mbrightness = brightness;
    SetColor(mHue, mSaturation);
}

void LEDWidget::SetColor(uint8_t Hue, uint8_t Saturation)
{
    uint8_t red, green, blue;
    uint8_t sSaturation, sbrightness;
    uint16_t sHue;

    sbrightness = (mState) ? mbrightness : 0;

    sHue        = static_cast<uint16_t>(Hue) * 360 / 254;       // sHue [0, 360]
    sSaturation = static_cast<uint8_t>(Saturation) * 100 / 254; // sSaturation [0 , 100]

    HSB2rgb(sHue, sSaturation, sbrightness, red, green, blue);
    ASR_LOG("brightness: %d, red: %d, green: %d, blue: %d", sbrightness, red, green, blue);

    mHue        = Hue;
    mSaturation = Saturation;

    showRGB(red, green, blue);
}

void LEDWidget::HSB2rgb(uint16_t Hue, uint8_t Saturation, uint8_t brightness, uint8_t & red, uint8_t & green, uint8_t & blue)
{
    uint16_t i       = Hue / 60;
    uint16_t rgb_max = brightness;
    uint16_t rgb_min = rgb_max * (100 - Saturation) / 100;
    uint16_t diff    = Hue % 60;
    uint16_t rgb_adj = (rgb_max - rgb_min) * diff / 60;

    switch (i)
    {
    case 0:
        red   = rgb_max;
        green = rgb_min + rgb_adj;
        blue  = rgb_min;
        break;
    case 1:
        red   = rgb_max - rgb_adj;
        green = rgb_max;
        blue  = rgb_min;
        break;
    case 2:
        red   = rgb_min;
        green = rgb_max;
        blue  = rgb_min + rgb_adj;
        break;
    case 3:
        red   = rgb_min;
        green = rgb_max - rgb_adj;
        blue  = rgb_max;
        break;
    case 4:
        red   = rgb_min + rgb_adj;
        green = rgb_min;
        blue  = rgb_max;
        break;
    default:
        red   = rgb_max;
        green = rgb_min;
        blue  = rgb_max - rgb_adj;
        break;
    }
}

void LEDWidget::showRGB(uint8_t red, uint8_t green, uint8_t blue)
{
    show_pwm(&pwm_led, red);

#if (LIGHT_SELECT == LIGHT_SELECT_RGB)
    show_pwm(&pwm_led_g, green);

    show_pwm(&pwm_led_b, blue);
#endif
}
