/*
 *  Copyright 1994-2022 Olivier Girondel
 *  Copyright 2014-2022 Frantz Balinski
 *
 *  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/>.
 */

/*
 * l'idée :
 *   diminuer la couleur du pixel jusqu'à zéro
 */

#include "context.h"
#include "parameters.h"


uint32_t version = 0;
uint32_t options = BO_BLUR | BO_NORANDOM;
char desc[] = "Color fade-out effect";
char dname[] = "Fadeout";

static double decay;
enum Mode { MODE_SELECTED = 0, MODE_RANDOM, MODE_NB } Mode_e;
const char *mode_list[MODE_NB] = { "Selected", "Random" };

/* parameters */
static enum Mode mode = MODE_RANDOM;

json_t *
get_parameters(const uint8_t fetch_all)
{
  json_t *params = json_object();

  plugin_parameters_add_string_list(params, BPP_MODE, MODE_NB, mode_list, mode, MODE_NB-1, "Mode");
  plugin_parameters_add_double(params, BPP_DECAY, decay, 0, 1, 0.01, "Decay");

  return params;
}


void
set_parameters(const Context_t *ctx, const json_t *in_parameters)
{
  int mode_idx = 0;
  if (plugin_parameter_parse_string_list_as_int_range(in_parameters, BPP_MODE, MODE_NB, mode_list, &mode_idx)) {
    mode = (enum Mode)mode_idx;
  }

  if (mode == MODE_SELECTED) {
    plugin_parameter_parse_double_range(in_parameters, BPP_DECAY, &decay);
  }
}


json_t *
parameters(const Context_t *ctx, const json_t *in_parameters, const uint8_t fetch_all)
{
  if (NULL != in_parameters) {
    set_parameters(ctx, in_parameters);
  }

  return get_parameters(fetch_all);
}


void
run(Context_t *ctx)
{
  const Pixel_t *src;
  Pixel_t *dst;
  Pixel_t col;

  src = active_buffer(ctx)->buffer;
  dst = passive_buffer(ctx)->buffer;

  for (uint32_t i = 0; i < BUFFSIZE; i++) {
    col = *src++;

    if (col > PIXEL_MINVAL) {
      col = (Pixel_t) floorf(decay * col);
    } else {
      col = PIXEL_MINVAL;
    }

    *dst++ = col;
  }
}


void
on_switch_on(Context_t *ctx)
{
  mode = MODE_RANDOM;
  decay = (float) pow(2, b_rand_double_range(log2(1), log2(31)));
  decay = decay / (decay + 1.f);
#ifdef DEBUG
  printf("[s] zblur1: col *= %.3f\n", decay);
#endif
}
