/* Goom Project
 * Copyright (C) <2003> iOS-Software
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
#include <stdlib.h>

#include "v3d.h"
#include "surf3d.h"
#include "goom_tools.h"
#include "goom_config.h"
#include "goom_plugin_info.h"
#include "tentacle3d.h"

#define D 256.0f

#define nbgrid 6
#define definitionx 15
#define definitionz 45

typedef struct _TENTACLE_FX_DATA
{
  PluginParam enabled_bp;
  PluginParameters params;

  float cycle;
  grid3d *grille[nbgrid];
  float *vals;

#define NB_TENTACLE_COLORS 4
  int colors[NB_TENTACLE_COLORS];

  int col;
  int dstcol;
  float lig;
  float ligs;

  /* statics from pretty_move */
  float distt;
  float distt2;
  float rot;                    /* entre 0 et 2 * G_PI */
  int happens;
  int rotation;
  int lock;
} TentacleFXData;

static void tentacle_new (TentacleFXData * data);
static void tentacle_update (PluginInfo * goomInfo, Pixel * buf, Pixel * back,
    int W, int H, short[2][512], float, int drawit, TentacleFXData * data);
static void tentacle_free (TentacleFXData * data);

/* 
 * VisualFX wrapper for the tentacles
 */

static void
tentacle_fx_init (VisualFX * _this, PluginInfo * info)
{

  TentacleFXData *data = (TentacleFXData *) malloc (sizeof (TentacleFXData));

  secure_b_param (&data->enabled_bp, "Enabled", 1);
  plugin_parameters (&data->params, "3D Tentacles", 1);
  data->params.params[0] = &data->enabled_bp;

  data->cycle = 0.0f;
  data->col =
      (0x28 << (ROUGE * 8)) | (0x2c << (VERT * 8)) | (0x5f << (BLEU * 8));
  data->dstcol = 0;
  data->lig = 1.15f;
  data->ligs = 0.1f;

  data->distt = 10.0f;
  data->distt2 = 0.0f;
  data->rot = 0.0f;             /* entre 0 et 2 * G_PI */
  data->happens = 0;

  data->rotation = 0;
  data->lock = 0;
  data->colors[0] =
      (0x18 << (ROUGE * 8)) | (0x4c << (VERT * 8)) | (0x2f << (BLEU * 8));
  data->colors[1] =
      (0x48 << (ROUGE * 8)) | (0x2c << (VERT * 8)) | (0x6f << (BLEU * 8));
  data->colors[2] =
      (0x58 << (ROUGE * 8)) | (0x3c << (VERT * 8)) | (0x0f << (BLEU * 8));
  data->colors[3] =
      (0x87 << (ROUGE * 8)) | (0x55 << (VERT * 8)) | (0x74 << (BLEU * 8));
  tentacle_new (data);

  _this->params = &data->params;
  _this->fx_data = (void *) data;
}

static void
tentacle_fx_apply (VisualFX * _this, Pixel * src, Pixel * dest,
    PluginInfo * goomInfo)
{
  TentacleFXData *data = (TentacleFXData *) _this->fx_data;

  if (BVAL (data->enabled_bp)) {
    tentacle_update (goomInfo, dest, src, goomInfo->screen.width,
        goomInfo->screen.height, goomInfo->sound.samples,
        (float) goomInfo->sound.accelvar,
        goomInfo->curGState->drawTentacle, data);
  }
}

static void
tentacle_fx_free (VisualFX * _this)
{
  tentacle_free ((TentacleFXData *) _this->fx_data);
  free (_this->fx_data);
}

void
tentacle_fx_create (VisualFX * fx)
{
  fx->init = tentacle_fx_init;
  fx->apply = tentacle_fx_apply;
  fx->free = tentacle_fx_free;
  fx->fx_data = NULL;
  fx->params = NULL;
}

/* ----- */

static void
tentacle_free (TentacleFXData * data)
{
  int tmp;

  /* FREE GRID */
  for (tmp = 0; tmp < nbgrid; tmp++)
    grid3d_free (data->grille[tmp]);
  free (data->vals);

  goom_plugin_parameters_free (&data->params);
}

static void
tentacle_new (TentacleFXData * data)
{
  int tmp;

  v3d center = { 0, -17.0, 0 };
  data->vals = (float *) malloc ((definitionx + 20) * sizeof (float));

  for (tmp = 0; tmp < nbgrid; tmp++) {
    int x, z;

    z = 45 + rand () % 30;
    x = 85 + rand () % 5;
    center.z = z;
    data->grille[tmp] =
        grid3d_new (x, definitionx, z, definitionz + rand () % 10, center);
    center.y += 8;
  }
}

static inline unsigned char
lighten (unsigned char value, float power)
{
  int val = value;
  float t = (float) val * log10 (power) / 2.0;

  if (t > 0) {
    val = (int) t;              /* (32.0f * log (t)); */
    if (val > 255)
      val = 255;
    if (val < 0)
      val = 0;
    return val;
  } else {
    return 0;
  }
}

static void
lightencolor (int *col, float power)
{
  unsigned char *color;

  color = (unsigned char *) col;
  *color = lighten (*color, power);
  color++;
  *color = lighten (*color, power);
  color++;
  *color = lighten (*color, power);
  color++;
  *color = lighten (*color, power);
}

/* retourne x>>s , en testant le signe de x */
#define ShiftRight(_x,_s) ((_x<0) ? -(-_x>>_s) : (_x>>_s))

static int
evolutecolor (unsigned int src, unsigned int dest,
    unsigned int mask, unsigned int incr)
{

  int color = src & (~mask);

  src &= mask;
  dest &= mask;

  if ((src != mask)
      && (src < dest))
    src += incr;

  if (src > dest)
    src -= incr;
  return (src & mask) | color;
}

static void
pretty_move (PluginInfo * goomInfo, float cycle, float *dist, float *dist2,
    float *rotangle, TentacleFXData * fx_data)
{

  float tmp;

  /* many magic numbers here... I don't really like that. */
  if (fx_data->happens)
    fx_data->happens -= 1;
  else if (fx_data->lock == 0) {
    fx_data->happens =
        goom_irand (goomInfo->gRandom,
        200) ? 0 : 100 + goom_irand (goomInfo->gRandom, 60);
    fx_data->lock = fx_data->happens * 3 / 2;
  } else
    fx_data->lock--;

  tmp = fx_data->happens ? 8.0f : 0;
  *dist2 = fx_data->distt2 = (tmp + 15.0f * fx_data->distt2) / 16.0f;

  tmp = 30 + D - 90.0f * (1.0f + sin (cycle * 19 / 20));
  if (fx_data->happens)
    tmp *= 0.6f;

  *dist = fx_data->distt = (tmp + 3.0f * fx_data->distt) / 4.0f;

  if (!fx_data->happens) {
    tmp = G_PI * sin (cycle) / 32 + 3 * G_PI / 2;
  } else {
    fx_data->rotation =
        goom_irand (goomInfo->gRandom,
        500) ? fx_data->rotation : goom_irand (goomInfo->gRandom, 2);
    if (fx_data->rotation)
      cycle *= 2.0f * G_PI;
    else
      cycle *= -1.0f * G_PI;
    tmp = cycle - (G_PI * 2.0) * floor (cycle / (G_PI * 2.0));
  }

  if (abs (tmp - fx_data->rot) > abs (tmp - (fx_data->rot + 2.0 * G_PI))) {
    fx_data->rot = (tmp + 15.0f * (fx_data->rot + 2 * G_PI)) / 16.0f;
    if (fx_data->rot > 2.0 * G_PI)
      fx_data->rot -= 2.0 * G_PI;
    *rotangle = fx_data->rot;
  } else if (abs (tmp - fx_data->rot) > abs (tmp - (fx_data->rot - 2.0 * G_PI))) {
    fx_data->rot = (tmp + 15.0f * (fx_data->rot - 2.0 * G_PI)) / 16.0f;
    if (fx_data->rot < 0.0f)
      fx_data->rot += 2.0 * G_PI;
    *rotangle = fx_data->rot;
  } else
    *rotangle = fx_data->rot = (tmp + 15.0f * fx_data->rot) / 16.0f;
}

static void
tentacle_update (PluginInfo * goomInfo, Pixel * buf, Pixel * back, int W, int H,
    short data[2][512], float rapport, int drawit, TentacleFXData * fx_data)
{

  int tmp;
  int tmp2;

  int color;
  int colorlow;

  float dist, dist2, rotangle;

  if ((!drawit) && (fx_data->ligs > 0.0f))
    fx_data->ligs = -fx_data->ligs;

  fx_data->lig += fx_data->ligs;

  if (fx_data->lig > 1.01f) {
    if ((fx_data->lig > 10.0f) | (fx_data->lig < 1.1f))
      fx_data->ligs = -fx_data->ligs;

    if ((fx_data->lig < 6.3f) && (goom_irand (goomInfo->gRandom, 30) == 0))
      fx_data->dstcol = goom_irand (goomInfo->gRandom, NB_TENTACLE_COLORS);

    fx_data->col =
        evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff,
        0x01);
    fx_data->col =
        evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff00,
        0x0100);
    fx_data->col =
        evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol], 0xff0000,
        0x010000);
    fx_data->col =
        evolutecolor (fx_data->col, fx_data->colors[fx_data->dstcol],
        0xff000000, 0x01000000);

    color = fx_data->col;
    colorlow = fx_data->col;

    lightencolor (&color, fx_data->lig * 2.0f + 2.0f);
    lightencolor (&colorlow, (fx_data->lig / 3.0f) + 0.67f);

    rapport = 1.0f + 2.0f * (rapport - 1.0f);
    rapport *= 1.2f;
    if (rapport > 1.12f)
      rapport = 1.12f;

    pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data);

    for (tmp = 0; tmp < nbgrid; tmp++) {
      for (tmp2 = 0; tmp2 < definitionx; tmp2++) {
        float val =
            (float) (ShiftRight (data[0][goom_irand (goomInfo->gRandom, 511)],
                10)) * rapport;

        fx_data->vals[tmp2] = val;
      }

      grid3d_update (fx_data->grille[tmp], rotangle, fx_data->vals, dist2);
    }
    fx_data->cycle += 0.01f;
    for (tmp = 0; tmp < nbgrid; tmp++)
      grid3d_draw (goomInfo, fx_data->grille[tmp], color, colorlow, dist, buf,
          back, W, H);
  } else {
    fx_data->lig = 1.05f;
    if (fx_data->ligs < 0.0f)
      fx_data->ligs = -fx_data->ligs;
    pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data);
    fx_data->cycle += 0.1f;
    if (fx_data->cycle > 1000)
      fx_data->cycle = 0;
  }
}
