/*******************************************************************************
 * fractal.h
 *
 * This module contains all defines, typedefs, and prototypes for FRACTAL.CPP.
 *
 * ---------------------------------------------------------------------------
 * Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
 * Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd.
 *
 * POV-Ray is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * POV-Ray 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * ---------------------------------------------------------------------------
 * POV-Ray 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.
 * ---------------------------------------------------------------------------
 * $File: //depot/public/povray/3.x/source/backend/shape/fractal.h $
 * $Revision: #1 $
 * $Change: 6069 $
 * $DateTime: 2013/11/06 11:59:40 $
 * $Author: chrisc $
 *******************************************************************************/

#ifndef FRACTAL_H
#define FRACTAL_H

namespace pov
{

/*****************************************************************************
* Global preprocessor defines
******************************************************************************/

#define QUATERNION_TYPE    0
#define HYPERCOMPLEX_TYPE  1

/* Hcmplx function stypes must come first */
#define EXP_STYPE          0
#define LN_STYPE           1
#define SIN_STYPE          2
#define ASIN_STYPE         3
#define COS_STYPE          4
#define ACOS_STYPE         5
#define TAN_STYPE          6
#define ATAN_STYPE         7
#define SINH_STYPE         8
#define ASINH_STYPE        9
#define COSH_STYPE        10
#define ACOSH_STYPE       11
#define TANH_STYPE        12
#define ATANH_STYPE       13
#define PWR_STYPE         14

/* end function stypes */
#define SQR_STYPE         15
#define CUBE_STYPE        16
#define RECIPROCAL_STYPE  17

#define Iteration(V,F,IS) ( (*((F)->Iteration_Method))(V,F,IS) )
#define Normal_Calc(F,V,IS) ( (*((F)->Normal_Calc_Method))(V,(F)->Num_Iterations,F,IS) )
#define F_Bound(R,F,dm,dM) ( (*((F)->F_Bound_Method))(R,F,dm,dM) )
#define D_Iteration(V,F,I,D,IS) ( (*((F)->D_Iteration_Method))(V,F,I,D,IS) )
#define Complex_Function(t,s,F) ( (*((F)->Complex_Function_Method))(t,s,&(F)->exponent) )

/*****************************************************************************
* Global typedefs
******************************************************************************/

class Fractal;

typedef struct cmplx { DBL x,y; } CMPLX;
typedef void (*NORMAL_CALC_METHOD) (VECTOR, int, const Fractal *, DBL **);
typedef int (*ITERATION_METHOD) (const VECTOR, const Fractal *, DBL **);
typedef int (*D_ITERATION_METHOD) (const VECTOR, const Fractal *, const VECTOR&, DBL *, DBL **);
typedef int (*F_BOUND_METHOD) (const Ray &, const Fractal *, DBL *, DBL *);
typedef void (*COMPLEX_FUNCTION_METHOD) (CMPLX *, const CMPLX *, const CMPLX *);

class Fractal : public ObjectBase
{
	public:
		VECTOR Center;
		DBL Julia_Parm[4];
		DBL Slice[4];                 /* vector perpendicular to slice plane */
		DBL SliceDist;                /* distance from slice plane to origin */
		DBL Exit_Value;
		int Num_Iterations;           /* number of iterations */
		DBL Precision;                /* Precision value */
		int Inverted;
		int Algebra;                  /* Quaternion or Hypercomplex */
		int Sub_Type;
		CMPLX exponent;               /* exponent of power function */
		DBL Radius_Squared;           /* For F_Bound(), if needed */
		NORMAL_CALC_METHOD Normal_Calc_Method;
		ITERATION_METHOD Iteration_Method;
		D_ITERATION_METHOD D_Iteration_Method;
		F_BOUND_METHOD F_Bound_Method;
		COMPLEX_FUNCTION_METHOD Complex_Function_Method;

		Fractal();
		virtual ~Fractal();

		virtual ObjectPtr Copy();

		virtual bool All_Intersections(const Ray&, IStack&, TraceThreadData *);
		virtual bool Inside(const VECTOR, TraceThreadData *) const;
		virtual void Normal(VECTOR, Intersection *, TraceThreadData *) const;
		virtual void Translate(const VECTOR, const TRANSFORM *);
		virtual void Rotate(const VECTOR, const TRANSFORM *);
		virtual void Scale(const VECTOR, const TRANSFORM *);
		virtual void Transform(const TRANSFORM *);
		virtual void Invert();
		virtual void Compute_BBox();

		static void Free_Iteration_Stack(DBL **IStack);
		static void Allocate_Iteration_Stack(DBL **IStack, int Len);

		int SetUp_Fractal(void);
};

/*****************************************************************************
* Global variables
******************************************************************************/

}

#endif
