#include "primitives.h"
#include "raylib.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

void InitScopeView(ScopeView* view, WaveformData data, int x, int y, int width, int height)
{
    view->data = data;
    view->x = x;
    view->y = y;
    view->width = width;
    view->height = height;
    view->viewStart = 0.0f;
    view->viewEnd = 1.0f;
    view->ampMin = -1.0f;
    view->ampMax = 1.0f;
    view->cursorT = -1.0f;  // -1 means no cursor
    view->showGrid = true;
    view->gridAlpha = 0.3f;
    view->bgColorR = 20;
    view->bgColorG = 20;
    view->bgColorB = 25;
    view->bgColorA = 255;
    view->gridR = 80;
    view->gridG = 80;
    view->gridB = 100;
    view->gridA = 180;
}

static int AmplitudeToY(ScopeView* view, float amp)
{
    return view->y + view->height - (int)((amp - view->ampMin) / (view->ampMax - view->ampMin) * view->height);
}

static int TimeToX(ScopeView* view, float t)
{
    return view->x + (int)(t * view->width);
}

void DrawScopeView(ScopeView* view, float cursorT)
{
    if (!view || !view->data.samples) return;

    int totalSamples = view->data.numSamples;
    if (totalSamples <= 0) return;

    // Draw background
    DrawRectangle(view->x, view->y, view->width, view->height,
                  (Color){ view->bgColorR, view->bgColorG, view->bgColorB, view->bgColorA });

    DrawRectangleLines(view->x, view->y, view->width, view->height,
                       Fade((Color){ view->gridR, view->gridG, view->gridB, view->gridA }, 0.5f));

    // Grid lines
    if (view->showGrid) {
        Color gridColor = (Color){ view->gridR, view->gridG, view->gridB, (int)(view->gridAlpha * 255) };

        // Vertical time divisions
        for (int i = 0; i <= 10; i++) {
            int x = TimeToX(view, (float)i / 10.0f);
            DrawLineV((Vector2){ x, view->y }, (Vector2){ x, view->y + view->height }, gridColor);
        }

        // Horizontal amplitude divisions
        for (int i = 0; i <= 10; i++) {
            float amp = view->ampMin + (float)i / 10.0f * (view->ampMax - view->ampMin);
            int y = AmplitudeToY(view, amp);
            DrawLine(view->x, y, view->x + view->width, y, gridColor);
        }

        // Zero line
        int zeroY = AmplitudeToY(view, 0.0f);
        DrawLine(view->x, zeroY, view->x + view->width, zeroY,
                 Fade((Color){ 255, 255, 255, 150 }, 0.7f));

        // Amplitude labels
        char label[32];
        for (int i = 0; i <= 10; i++) {
            float amp = view->ampMin + (float)i / 10.0f * (view->ampMax - view->ampMin);
            int y = AmplitudeToY(view, amp);
            sprintf(label, "%.1f", amp);
            DrawText(label, view->x - 35, y - 5, 8,
                     Fade((Color){ view->gridR, view->gridG, view->gridB, view->gridA }, 0.7f));
        }
    }

    // Visible sample range
    int startSample = (int)(view->viewStart * totalSamples);
    int endSample = (int)(view->viewEnd * totalSamples);
    if (startSample < 0) startSample = 0;
    if (endSample > totalSamples) endSample = totalSamples;

    int visibleSamples = endSample - startSample;
    if (visibleSamples <= 0) return;

    // Compute samples-per-pixel so every pixel gets a column
    int spp = (visibleSamples + view->width - 1) / view->width;
    if (spp < 1) spp = 1;

    // Draw envelope: per-pixel min/max (Audacity-style)
    Color waveColor = (Color){ 200, 220, 255, 255 };
    for (int px = 0; px < view->width; px++) {
        int s0 = startSample + px * spp;
        int s1 = startSample + (px + 1) * spp;
        if (s0 >= endSample) s0 = endSample - 1;
        if (s1 > endSample) s1 = endSample;

        float minAmp = view->data.samples[s0];
        float maxAmp = view->data.samples[s0];
        for (int s = s0 + 1; s < s1; s++) {
            float v = view->data.samples[s];
            if (v < minAmp) minAmp = v;
            if (v > maxAmp) maxAmp = v;
        }

        int yTop = AmplitudeToY(view, maxAmp);
        int yBot = AmplitudeToY(view, minAmp);
        DrawLine(px + view->x, yTop, px + view->x, yBot, waveColor);
    }

    // Cursor
    if (cursorT >= 0.0f && cursorT <= 1.0f) {
        int cursorX = TimeToX(view, cursorT);
        if (cursorX >= view->x && cursorX <= view->x + view->width) {
            Color cc = (Color){ 255, 80, 80, 255 };
            DrawLine(cursorX, view->y, cursorX, view->y + view->height, cc);
            Vector2 p1 = (Vector2){ cursorX, view->y };
            Vector2 p2 = (Vector2){ cursorX - 6, view->y + 10 };
            Vector2 p3 = (Vector2){ cursorX + 6, view->y + 10 };
            DrawTriangle(p1, p2, p3, cc);
        }
    }
}
