/** @file tachometer.c
 *
 *  A versatile software tool to analyse and configure CANopen devices.
 *
 *  Copyright (c) 2026, Michael Fitzmayer. All rights reserved.
 *  SPDX-License-Identifier: MIT
 *
 **/

#include "tachometer.h"
#include "ascii.h"
#include "os.h"
#include "palette.h"
#include "primitives.h"
#include "window.h"

void widget_tachometer(uint32 pos_x, uint32 pos_y, uint32 size, const uint32 max, uint32 value)
{
    os_renderer* renderer = window_get_renderer();
    uint8 r, g, b;

    char buffer[10] = {0};
    float angle;
    float radians;
    int center_x;
    int center_y;
    int needle_length;
    int needle_x;
    int needle_y;
    int indicator_length = size / 20;
    uint8 scale = 2u;

    size_t len;
    int text_width;

    if (size <= 100)
    {
        scale = 1u;
    }

    if (! renderer)
    {
        return;
    }

    r = (WIDGET_COLOR & 0xff0000) >> 16;
    g = (WIDGET_COLOR & 0x00ff00) >> 8;
    b = (WIDGET_COLOR & 0x0000ff);

    os_set_color(renderer, r, g, b, 0xff);
    draw_circle(renderer, pos_x + (size / 2), pos_y + (size / 2), size / 2, true);

    r = (WIDGET_COLOR_HIGHLIGHT & 0xff0000) >> 16;
    g = (WIDGET_COLOR_HIGHLIGHT & 0x00ff00) >> 8;
    b = (WIDGET_COLOR_HIGHLIGHT & 0x0000ff);

    os_set_color(renderer, r, g, b, 0xff);
    draw_circle(renderer, pos_x + (size / 2), pos_y + (size / 2), size / 2, false);
    os_draw_line(renderer, pos_x, pos_y + (size / 2), pos_x + indicator_length, pos_y + (size / 2));
    os_draw_line(renderer, pos_x + (size - indicator_length), pos_y + (size / 2), pos_x + size, pos_y + (size / 2));

    angle = 180.0f - ((float)value / max * 180.0f);
    radians = angle * (3.14159f / 180.0f);

    center_x = pos_x + size / 2;
    center_y = pos_y + size / 2;
    needle_length = size / 2;

    needle_x = center_x + (int)(needle_length * SDL_cos(radians));
    needle_y = center_y - (int)(needle_length * SDL_sin(radians));

    r = (DRAW_COLOR & 0xff0000) >> 16;
    g = (DRAW_COLOR & 0x00ff00) >> 8;
    b = (DRAW_COLOR & 0x0000ff);

    os_set_color(renderer, r, g, b, 0xff);
    os_draw_line(renderer, center_x, center_y, needle_x, needle_y);

    os_snprintf(buffer, 9, "%Xh", value);
    len = os_strlen(buffer);
    text_width = (CHAR_WIDTH + CHAR_SPACING) * scale * len - (CHAR_SPACING);

    widget_print(
        pos_x + (size / 2) - (text_width / 2),
        pos_y + size / 2 + (CHAR_HEIGHT * 2),
        DRAW_WHITE, scale, "%s", buffer);
}
