
/* LiViDO plugin example
 *
 * make it with:
 * $ gcc $CFLAGS -c plugin_example.c
 * $ ld -E -z now -shared plugin_example.o -o plugin_example.so
 *
 * Copyleft (C) 2004 
 *  Denis "jaromil" Rojo - http://rastasoft.org
 *  Silvano "kysucix" Galliani - http://kysucix.nexlab.it
 *
 * This source code is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Public License as published
 * by the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.
 *
 * This source code 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.
 * Please refer to the GNU Public License for more details.
 *
 * You should have received a copy of the GNU Public License along with
 * this source code; if not, write to:
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: plugin_example.c 63 2004-11-14 16:33:36Z jaromil $
 *
 */

/** @file plugin_example.c

    @brief LiViDO plugin implementation example

 */


#include <livido.h>

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>




//////////////////////////////////////////////////////////////
// DECLARE PUBLIC STRUCTURES OF PLUGIN

int plugin_example_palette[] = {
  LIVIDO_PALETTE_RGBAFLOAT,
  LIVIDO_PALETTE_RGB32,
  LIVIDO_PALETTE_END
};


livido_channel_template_t in_channel_template_input1 = {
  .name = "input1", //< name of the channel
  .flags = 0, ///< flags fot this channel
  .palettes = plugin_example_palette, ///< list of palettes supported by plugin
  .same_as = 0, ///< size and palettes must be the same as another channel
  .width = 0, ///< width 0 means the host can choose them arbitrarily
  .height = 0, ///< height 0 means the host can choose them arbitrarily
  .next = NULL
};

livido_channel_template_t out_channel_template_output1 = {
  .name = "output1", //< name of the channel
  .flags = (LIVIDO_CHANNEL_SAME_AS_SIZE | LIVIDO_CHANNEL_SAME_AS_PALETTE), ///< flags fot this channel
  .palettes = plugin_example_palette, ///< list of palettes supported by plugin
  .same_as = 1, ///< size and palettes must be the same as another channel
  .width = 0, ///< width 0 means the host can choose them arbitrarily
  .height = 0, ///< height 0 means the host can choose them arbitrarily
  .next = NULL
};


livido_parameter_template_t parameter_template_zahira = {
  .name = "zahira", // short name
  .description =
  "This is an example parameter\n"
  "this description is also multiline", // description of the parameter
  .format = "%f", // parameter rendering description
  .type = LIVIDO_PARAM_NUMBER, // the parameter type
  .flags = 0, // flags
  .def = "3.0", // default value
  .min = 1.0,  // minimum value
  .max = 18.0, // maximum value
  .hint = "gui_hint", // layout hints for the GUI renderer XXX
  .extra = NULL // void * is always our friend for future expantion
};

livido_instance_template_t effect_template_piksel = {
  .name = "piksel", // name of effect
  .author = "the livido team", // author of effect
  .description =
  "this should is the first example plugin for livido\n"
  "it was coded at the Piksel in the BEK, november 2004", // long text description
  .version = 1, // effect version
  .livido_api_version = 1, // version of the livido api used
  .flags = (LIVIDO_PROPERTY_CAN_DO_INPLACE | LIVIDO_PROPERTY_REALTIME), // effect properties  
  .hints = "(gui hints here)", ///< XXX hints about presenting of the plugin (GUI wise)
  .extra = NULL ///< extra data pointer reserved for future use (void *)
};



/* declare our init function */
int example_init(livido_instance_t *inst) {
  fprintf(stderr,"plugin example init called on instance %p\n",inst);

  inst->internal = NULL;
  /// @todo: check instance validity in plugin_example.c

  return 0; // success
}


int example_deinit(livido_instance_t *inst) {
  fprintf(stderr,"plugin example deinit called on instance %p\n",inst);

  if(inst->internal) free(inst->internal);

  return 0; // success
}


int example_process(livido_instance_t *effect, livido_frame_t *in, livido_frame_t *out) {
  float val;
  livido_parameter_t *param;

  fprintf(stderr,"plugin: process called on env=%p in=%p out=%p\n", effect, in, out);

  param = effect->in_parameters;
  
  fprintf(stderr,"plugin: parameter %s value: ", param->templ->name);

  /// use the following to mathematically evaluate parameter values:
  livido_get_parameter(param, &val);
  /// now the value is stored in the float val variable
  /// don't use directly param->value: it is a string!

  fprintf(stderr, param->templ->format, val);

  fprintf(stderr," (parsed from string \"%s\")\n", param->value);

  return LIVIDO_NO_ERROR;
}


livido_instance_template_t *livido_setup() {

  // concatenate input channel templates, pass the reference to our structs
  effect_template_piksel.in_channel_templates = &in_channel_template_input1;
  // with more input channels you can link further:
  // in_channel_template_input1.next = &in_channel_template_input2;
  in_channel_template_input1.next = NULL; // end list
  
  // concatenate output channel templates
  effect_template_piksel.out_channel_templates = &out_channel_template_output1;
  out_channel_template_output1.next = NULL; // end list
  
  // concatenate input parameter templates
  effect_template_piksel.in_parameter_templates = &parameter_template_zahira;
  parameter_template_zahira.next = NULL; // end list
  
  // concatenate output parameter templates
  effect_template_piksel.out_parameter_templates = NULL; // no output here
  
  // expose effect function pointers
  effect_template_piksel.init = example_init;
  effect_template_piksel.deinit = example_deinit;
  effect_template_piksel.process = example_process;

  // terminate template list: we have only one effect in this plugin
  effect_template_piksel.next = NULL;

  // return template list to the host
  return &effect_template_piksel;
}
