/*
 *  Copyright 1994-2022 Olivier Girondel
 *
 *  This file is part of lebiniou.
 *
 *  lebiniou is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  lebiniou is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with lebiniou. If not, see <http://www.gnu.org/licenses/>.
 */

#include "oscillo.h"
#include "../include/oscillo.h"


uint32_t version = 0;
uint32_t options = BO_SFX | BO_HOR | BO_SCHEMES;
char dname[] = "Oscillo horizontal";
enum LayerMode mode = LM_OVERLAY;
char desc[] = "Horizontal oscilloscope";


static void
run_ptr_mono(Context_t *ctx)
{
  Porteuse_draw(P[0], ctx, do_connect);
}


static void
run_ptr_stereo(Context_t *ctx)
{
  Porteuse_draw(P[1], ctx, do_connect);
  Porteuse_draw(P[2], ctx, do_connect);
}


static void (*run_ptr)(Context_t *) = &run_ptr_mono;


static void
set_run_ptr(void)
{
  if (!stereo) {
    run_ptr = &run_ptr_mono;
  } else {
    run_ptr = &run_ptr_stereo;
  }
}


static void
init_mono(void)
{
  uint32_t i;
  Transform_t t;

  memset(&t, 0, sizeof(t));

  P[0]->origin.x = 0;
  P[0]->origin.y = CENTERY;

  t.v_j_factor = HMAXY * volume_scale;
  t.v_i.x = 1.0 / (float)(P[0]->size - 1) * (float)MAXX;

  for (i = 0; i < P[0]->size; i++) {
    P[0]->trans[i] = t;
  }

  Porteuse_init_alpha(P[0]);
}


static void
init_stereo(void)
{
  uint32_t i;
  Transform_t t;

  memset(&t, 0, sizeof(t));

  P[1]->origin.x = P[2]->origin.x = 0;

  P[1]->origin.y = HHEIGHT/2;
  P[2]->origin.y = MAXY-HHEIGHT/2;

  t.v_j_factor = HMAXY * volume_scale;
  t.v_i.x = 1.0 / (float)(P[1]->size - 1) * (float)MAXX;

  for (i = 0; i < P[1]->size; i++) {
    P[1]->trans[i] = P[2]->trans[i] = t;
  }

  Porteuse_init_alpha(P[1]);
  Porteuse_init_alpha(P[2]);
}


void
set_parameters(const Context_t *ctx, const json_t *in_parameters)
{
  int init = 0;
  init |= set_parameters_oscillo(ctx, in_parameters);

  if (init) {
    init_mono();
    init_stereo();
    set_run_ptr();
  }
}


void
on_switch_on(Context_t *ctx)
{
  /* Initialize parameters */
  volume_scale = 1;
  do_connect = 1;
  stereo = b_rand_boolean();
  init_mono();
  init_stereo();
  set_run_ptr();
}


void
run(Context_t *ctx)
{
  Buffer8_clear(passive_buffer(ctx));
  run_ptr(ctx);
}
