/*
 *  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 "layer.h"


Layer_t *
Layer_new(Plugin_t *p)
{
  Layer_t *l;

  l = xcalloc(1, sizeof(Layer_t));
  l->plugin = p;
  l->mode = LM_NORMAL;

  return l;
}


void
Layer_delete(Layer_t *l)
{
  json_decref(l->plugin_parameters);
  xfree(l);
}


Layer_t *
Layer_copy(const Layer_t *from)
{
  Layer_t *l = Layer_new(from->plugin);

  l->mode = from->mode;
  l->plugin_parameters = json_deep_copy(from->plugin_parameters);

  return l;
}


enum LayerMode
LayerMode_from_string(const char *mode) {
  if (is_equal(mode, "none")) {
    return LM_NONE;
  } else if (is_equal(mode, "normal")) {
    return LM_NORMAL;
  } else if (is_equal(mode, "overlay")) {
    return LM_OVERLAY;
  } else if (is_equal(mode, "and")) {
    return LM_AND;
  } else if (is_equal(mode, "or")) {
    return LM_OR;
  } else if (is_equal(mode, "xor")) {
    return LM_XOR;
  } else if (is_equal(mode, "average")) {
    return LM_AVERAGE;
  } else if (is_equal(mode, "interleave")) {
    return LM_INTERLEAVE;
  } else if (is_equal(mode, "random")) {
    return LM_RANDOM;
  } else if (is_equal(mode, "bandpass")) {
    return LM_BANDPASS;
  } else {
    printf("[!] Failed to parse mode '%s', setting to NORMAL\n", mode);

    return LM_NORMAL;
  }
}


const char *
LayerMode_to_string(const enum LayerMode mode)
{
  switch (mode) {
    case LM_NONE:
      return "none";
      break;

    case LM_NORMAL:
      return "normal";
      break;

    case LM_OVERLAY:
      return "overlay";
      break;

    case LM_AND:
      return "and";
      break;

    case LM_OR:
      return "or";
      break;

    case LM_XOR:
      return "xor";
      break;

    case LM_AVERAGE:
      return "average";
      break;

    case LM_RANDOM:
      return "random";
      break;

    case LM_INTERLEAVE:
      return "interleave";
      break;

  case LM_BANDPASS:
    return "bandpass";
      break;

    default:
      xerror("LayerMode_to_string: unknown mode= %d\n", mode);
      break;
  }

  return NULL; /* not reached */
}


const char *
LayerMode_to_OSD_string(const enum LayerMode mode)
{
  if (!(mode < NB_LAYER_MODES)) {
    xerror("%s: Invalid layer mode %d\n", __func__, mode);

    return NULL;
  } else {
    return &"---\0NOR\0OVL\0AND\0OR \0XOR\0AVG\0ILV\0RND\0"[4 * mode * sizeof(char)];
  }
}


json_t *
layer_modes(void)
{
  json_t *array = json_array();

  for (enum LayerMode mode = LM_NORMAL; mode < LM_NONE; ++mode) {
    json_array_append_new(array, json_string(LayerMode_to_string(mode)));
  }

  return array;
}
