/****************************************************************************
 *                  fvector.cpp
 *
 *  Author: Wlodzimierz ABX Skiba (abx@abx.art.pl)
 *
 * from Persistence of Vision(tm) Ray Tracer version 3.6.
 * Copyright 1991-2003 Persistence of Vision Team
 * Copyright 2003-2004 Persistence of Vision Raytracer Pty. Ltd.
 *---------------------------------------------------------------------------
 * NOTICE: This source code file is provided so that users may experiment
 * with enhancements to POV-Ray and to port the software to platforms other
 * than those supported by the POV-Ray developers. There are strict rules
 * regarding how you are permitted to use this file. These rules are contained
 * in the distribution and derivative versions licenses which should have been
 * provided with this file.
 *
 * These licences may be found online, linked from the end-user license
 * agreement that is located at http://www.povray.org/povlegal.html
 *---------------------------------------------------------------------------
 * This program is based on the popular DKB raytracer version 2.12.
 * DKBTrace was originally written by David K. Buck.
 * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
 *---------------------------------------------------------------------------
 *
 *===========================================================================
 * This file is part of MegaPOV, a modified and unofficial version of POV-Ray
 * For more information on MegaPOV visit our website:
 * http://megapov.inetart.net/
 *===========================================================================
 *
 * $RCSfile: fvector.cpp,v $
 * $Revision: 1.7 $
 * $Author: chris $
 *
 *****************************************************************************/


#include "frame.h"

#ifdef ALTERNATIVE_VECTOR_FUNCTION
#include <algorithm>

#include "pov_mem.h"
#include "pigment.h"
#include "fnpovfpu.h"
#include "fvector.h"
BEGIN_POV_NAMESPACE

VECTOR_FUNCTION *Create_Vector_Function()
{
  VECTOR_FUNCTION *New;

  New = (VECTOR_FUNCTION *)POV_MALLOC(sizeof(VECTOR_FUNCTION), "vector function");
  New->InputDimension = 0;
  New->OutputDimension = 0;
  New->IsPigment = true;
  New->Data.Pigment = NULL;

  return New;
}

void Destroy_Vector_Function(VECTOR_FUNCTION *Vector_Function)
{
  if(!Vector_Function)
    return;

  if(Vector_Function->IsPigment)
  {
    if (Vector_Function->Data.Pigment)
      Destroy_Pigment( Vector_Function->Data.Pigment );
  }
  else
  {
    int i=0;
    while (i < Vector_Function->OutputDimension)
    {
      Destroy_Function( Vector_Function->Data.Function[i] );
      i++;
    }
  }
  POV_FREE(Vector_Function);
}

VECTOR_FUNCTION *Copy_Vector_Function(VECTOR_FUNCTION *Old)
{
  if (!Old)
    return NULL;

  VECTOR_FUNCTION *New = Create_Vector_Function();

  New->InputDimension = Old->InputDimension;
  New->OutputDimension = Old->OutputDimension;

  New->IsPigment = Old->IsPigment;

  if ( New->IsPigment )
  {
    New->Data.Pigment = Copy_Pigment( Old->Data.Pigment );
  }
  else
  {
    int i=0;
    while (i < New->OutputDimension)
    {
      New->Data.Function[i] = Copy_Function( Old->Data.Function[i] );
      i++;
    }
  }

  return New;
}

void Compute_Vector_Function(VECTOR_FUNCTION *Vector_Function,DBL In[], DBL Out[])
{
  if(Vector_Function==NULL)
    return;

  VECTOR Input;

  for(int i=0;i<3;i++)
    Input[i]=(i<Vector_Function->InputDimension)?In[i]:0.0;

  for(int i=0;i<Vector_Function->OutputDimension;i++)
    Out[i]=0.0;

  if ( Vector_Function->IsPigment )
  {
    if(Vector_Function->Data.Pigment)
    {
      COLOUR Output_Colour;
      if(Compute_Pigment (Output_Colour, Vector_Function->Data.Pigment, Input, NULL))
      {
        for(int i=0;i<min(Vector_Function->OutputDimension,5);i++)
          Out[i] = Output_Colour[i];
      }
    }
  }
  else
    for(int i=0; i < Vector_Function->OutputDimension; i++)
    {
      POVFPU_SetLocal(X, Input[X]);
      POVFPU_SetLocal(Y, Input[Y]);
      POVFPU_SetLocal(Z, Input[Z]);
      Out[i] = POVFPU_Run(*Vector_Function->Data.Function[i]);
    }
}
END_POV_NAMESPACE

#endif
