/*
 *  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 "context.h"
enum Direction { LEFTWARDS = 0, RIGHTWARDS, RANDOM, DIRECTION_NB } Mode_e;
const char *direction_list[DIRECTION_NB] = { "Leftwards", "Rightwards", "Random" };
#include "roller.h"


uint32_t version = 1;
uint32_t options = BO_ROLL | BO_VER | BO_LENS | BO_NOT_LENS;
char dname[] = "Roll Y";
char desc[] = "Rolls the screen horizontally";


void
set_parameters(const Context_t *ctx, const json_t *in_parameters)
{
  int speed_changed = 0, random_speed_changed = 0;

  set_speed_parameters(ctx, in_parameters, &speed_changed, &random_speed_changed);
  if (random_speed_changed && random_speed) {
    speed = get_random_speed();
    speed_changed = 1;
  }
  if (speed_changed || (plugin_parameter_parse_string_list_as_int_range(in_parameters, BPP_DIRECTION, DIRECTION_NB, direction_list, (int *)&direction) & PLUGIN_PARAMETER_CHANGED)) {
    roll_freq = speed;
    if ((direction == LEFTWARDS) || ((direction == RANDOM) && b_rand_boolean())) {
      roll_freq = -roll_freq;
    }
#ifdef DEBUG
    VERBOSE(printf("[i] %s:%s direction= %s, speed= %f, roll_freq= %f\n", __FILE__, __func__, direction_list[direction], speed, roll_freq));
#endif
  }
}


void
run(Context_t *ctx)
{
  const Buffer8_t *src = active_buffer(ctx);
  Buffer8_t *dst = passive_buffer(ctx);

  for (uint16_t i = 0; i < WIDTH; i++) {
    short  p  = i - HWIDTH;
    float phi = acosf((float)p / (float)(HWIDTH));
    short  b  = (short)((roll_theta + phi) / M_PI * (float)WIDTH);

    b %= (2 * WIDTH);

    if (b < 0) {
      b += (2 * WIDTH);
    }
    if (b > MAXX) {
      b = 2 * WIDTH - b - 1;
    }

    for (uint16_t j = 0; j < HEIGHT; j++) {
      set_pixel_nc(dst, i, j, get_pixel_nc(src, b, j));
    }
  }

  inc_theta();
}
