// SPDX-License-Identifier: Unlicense

#include "api.h"

#ifdef SHR3D_SFX_CORE_EXTENSION_V2

#include "../../nuklear.h"

#include <string.h>
#include <stdio.h>

struct WaveformGraphInstance final : SfxCoreExtensionV2Instance
{
  f32 audioBuffer[512];

  ProcessBlockResult processBlock(f32** inBlock, f32** /*outBlock*/, const i32 blockSize) override
  {
    if (blockSize < ARRAY_SIZE(audioBuffer))
    {
      memmove(&audioBuffer[0], &audioBuffer[blockSize], (ARRAY_SIZE(audioBuffer) - blockSize) * sizeof(f32));
      memcpy(&audioBuffer[ARRAY_SIZE(audioBuffer) - blockSize], inBlock[0], blockSize * sizeof(f32));
    }
    else
    {
      memcpy(&audioBuffer[0], inBlock[0], ARRAY_SIZE(audioBuffer) * sizeof(f32));
    }

    return ProcessBlockResult::ProcessedInInBlock;
  }

  f32 getParameter(const i32 /*index*/) const override
  {
    unreachable();
  }

  void setParameter(const i32 /*index*/, const f32 /*value*/) override
  {
    unreachable();
  }

  void getParameterDisplay(const i32 /*index*/, char* /*text*/) override
  {
    unreachable();
  }

  void resetParameter(const i32 /*index*/) override
  {
    unreachable();
  }
};

static bool waveformGraph_uiCallback(nk_context* ctx, SfxCoreExtensionV2Base* extension, i32 instance)
{
  const bool showWindow = nk_begin(ctx, "Waveform Graph", { 20, 20, 700, 480 }, NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_TITLE | NK_WINDOW_CLOSABLE | NK_WINDOW_SCALABLE);
  if (showWindow)
  {
    nk_layout_row_dynamic(ctx, 140.0f, 1);
    nk_spacer(ctx);

    WaveformGraphInstance* waveformGraphInstance = static_cast<WaveformGraphInstance*>(extension->getInstance(instance));

    if (nk_chart_begin(ctx, NK_CHART_LINES, ARRAY_SIZE(waveformGraphInstance->audioBuffer), -1.0f, 1.0f))
      for (size_t i = 0; i < ARRAY_SIZE(waveformGraphInstance->audioBuffer); ++i)
        nk_chart_push(ctx, waveformGraphInstance->audioBuffer[i]);

    nk_chart_end(ctx);
  }
  nk_end(ctx);

  return showWindow;
}

static struct WaveformGraph final : SfxCoreExtensionV2Base
{
  WaveformGraph()
  {
    uiCallback = waveformGraph_uiCallback;
    RegisterSfxCoreExtensionV2(u8"Waveform Graph", this);
  }

  i32 getParameterCount() const override
  {
    return 0;
  }

  const char8_t* getParameterLabel(const i32 /*index*/) override
  {
    unreachable();
  }

  const char8_t* getParameterName(const i32 /*index*/) override
  {
    unreachable();
  }

  SfxCoreExtensionV2Instance* getInstance(const i32 /*instance*/) override
  {
    static WaveformGraphInstance waveformGraphInstance;
    return &waveformGraphInstance;
  }
} waveformGraph;

#endif // SHR3D_SFX_CORE_EXTENSION_V2
