//////////////////////////////////////////////////////////////////////////////
//
//  Author      : Josh Grant
//  Date        : October 16th, 2001
//  File        : ScalarArithmitic.h
//  Description : Header file defining the ScalarArithmitic class
//
//////////////////////////////////////////////////////////////////////////////

#ifndef _SCALAR_ARITHMITIC_
#define _SCALAR_ARITHMITIC_

#include <Inventor/engines/SoSubEngine.h>
#include <Inventor/engines/SoCalculator.h>
#include <Inventor/fields/SoSFVec3f.h>
#include <Inventor/fields/SoMFFloat.h>
#include <Inventor/fields/SoSFString.h>
#include <Inventor/fields/SoSFFloat.h>

#include "SFScalarField.h"

//////////////////////////////////////////////////////////////////////////////
//
//  Class: ScalarArithmitic
//
//  A subclass of SoEngine used to compute a 3D scalar field of type
//  SFScalarField.  The inputs are the dimensions and bounds of the scalar
//  field including an expression used to describe the scalar field.  The
//  values at each point in the 3D space are calculated using the
//  SoCalculator engine.  The x,y,z coordinates of each point are set as the
//  input of the calculator, as well as the expression field of this class.
//  Then the output is the resulting scalar field.
//
//////////////////////////////////////////////////////////////////////////////

class ScalarArithmitic : public SoEngine {

  // Required by Inventor to subclass the SoEngine class
  SO_ENGINE_HEADER(ScalarArithmitic);

public:
  // Input fields
  SoSFFloat      xDim, yDim, zDim;
  SoSFVec3f      minBounds;
  SoSFVec3f      maxBounds;
  SoSFString     expression;

  // Output field
  SoEngineOutput scalarField; // (SFScalarField)

  // Inventor method
  static void    initClass         ();

                 ScalarArithmitic  ();

protected:
  // called each time an input has been modified or reconnected
  virtual void   inputChanged      (SoField *whichInput);

private:
                 ~ScalarArithmitic ();

  // called whenever an output is referenced.
  virtual void   evaluate          ();

  // reset the sizes of the calculator inputs and the output
  void           setSizes          ();
  // reset the calculator inputs
  void           setInput          ();
  // parse the string.  Change all x->a, y->b, z->c
  void           parseString       ();

  // pointer to the calculator doing all the work.
  SoCalculator  *calc;
  SoMFFloat      scalar;
  int            dims[3];

  SbBool         reparse, resetInput;
};

#endif /* _SCALAR_ARITHMITIC_ */
