/*
 *  Copyright 1994-2022 Olivier Girondel
 *  Copyright 2019-2022 Tavasti
 *
 *  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/>.
 */

/* Colrot, Color Rotation

   basic idea of plugin: Show only part of the colors from webcam video,
   and scroll thru colors. Not visible colors are transparent,
   showing stuff happening under. Using lens mode.

   This plugin is 'normal', pretty agressive version of Colrot
*/

#include "context.h"
#include "tv.h"
#include "pthread_utils.h"


#define MASK_SIZE  15 /* what size of chunks colorspace is divided */
#define COLORCOUNT 5  /* how many colors are visible in each chunk */

uint32_t version = 0;
uint32_t options = BO_GFX | BO_LENS | BO_NOT_LENS | BO_WEBCAM | BO_SCHEMES;
char desc[] = "Show webcam scrolling colors";
char dname[] = "TV colrot";

enum LayerMode mode = LM_OVERLAY;

static Pixel_t min1= 0, max1 = COLORCOUNT;


void
run(Context_t *ctx)
{
  Pixel_t *src1, *start, *dst;

  dst = start = passive_buffer(ctx)->buffer;

  if (!xpthread_mutex_lock(&ctx->cam_mtx[ctx->cam])) {
    if (use_video) {
      src1 = ctx->video_save[0]->buffer;
    } else {
      src1 = ctx->cam_save[ctx->cam][0]->buffer;
    }

    for (; dst < start + BUFFSIZE * sizeof(Pixel_t); src1++, dst++) {
      if ( /* max1 is bigger than min, show values between them */
          ((max1 > min1) &&
           ((*src1 & MASK_SIZE) > min1) && ((*src1 & MASK_SIZE) < max1)) ||
          /* max is rotated over, show values below max or above min */
          ((max1 < min1) &&
           (((*src1 & MASK_SIZE)> min1) || ((*src1 & MASK_SIZE) < max1)))) {
        *dst = *src1;
      } else {
        *dst = 0;
      }
    }
    xpthread_mutex_unlock(&ctx->cam_mtx[ctx->cam]);
  }

  min1++;
  if (min1 > MASK_SIZE) {
    min1 = 0;
  }

  max1++;
  if (max1 > MASK_SIZE) {
    max1 = 0;
  }
}
