/* FILE: arrayscalarfield.h      -*-Mode: c++-*-
 *
 * Scalar field wrapper for Nb_Array3D<OC_REAL8m>.  This is not intended to
 * be used as a standalone field, but rather to be embedded inside
 * another field object, for implementation purposes.
 *    After construction, owner clients should call the InitArray method
 * to set up the array size and user-space to array mapping.  This
 * mapping positions each array element in the center of the
 * corresponding rectangular cell. Individual array values are then set
 * or read via the SetArrayElt and GetArrayElt members.  The *Value
 * members are the generic Oxs_ScalarField interface; the array elements
 * should be initialized before any use of the *Value members.
 *    NOTE: The Nb_Array3D class accesses arr(i,j,k) as arr[i][j][k].
 * Since Oxs assumes x is the long dimension, the Oxs_ArrayScalarField
 * interface reorders these so that, e.g., SetArrayElt(ix,iy,iz) maps
 * to arr(iz,iy,iz).
 */

#ifndef _OXS_ARRAYSCALARFIELD
#define _OXS_ARRAYSCALARFIELD

#include "nb.h"
#include "oc.h"

#include "director.h"
#include "scalarfield.h"
#include "threevector.h"
#include "util.h"

/* End includes */

class Oxs_ArrayScalarField:public Oxs_ScalarField {
private:
  ThreeVector scale,offset; // User space to index mapping
  OC_REAL8m default_value;
  enum Exterior_Handling {
    EXTERIOR_ERROR, EXTERIOR_BOUNDARY, EXTERIOR_DEFAULT
  } exterior;
  Nb_Array3D<OC_REAL8m> array;

public:
  virtual const char* ClassName() const; // ClassName() is
  /// automatically generated by the OXS_EXT_REGISTER macro.

  Oxs_ArrayScalarField
  (const char* name,     // Child instance id
   Oxs_Director* newdtr, // App director
   const char* argstr);  // MIF input block parameters

  virtual ~Oxs_ArrayScalarField() {}

  // Array interface
  void InitArray(OC_INDEX xdim,OC_INDEX ydim,OC_INDEX zdim,
                 const Oxs_Box& range);
  void SetArrayElt(OC_INDEX ix,OC_INDEX iy,OC_INDEX iz,OC_REAL8m val) {
    array(iz,iy,ix) = val;
  }
  OC_REAL8m GetArrayElt(OC_INDEX ix,OC_INDEX iy,OC_INDEX iz) {
    return array(iz,iy,ix);
  }

  // Scalar Field interface
  virtual OC_REAL8m Value(const ThreeVector& pt) const;
  virtual void FillMeshValue(const Oxs_Mesh* mesh,
			     Oxs_MeshValue<OC_REAL8m>& array) const;
  virtual void IncrMeshValue(const Oxs_Mesh* mesh,
			     Oxs_MeshValue<OC_REAL8m>& array) const;
  virtual void MultMeshValue(const Oxs_Mesh* mesh,
			     Oxs_MeshValue<OC_REAL8m>& array) const;


};


#endif // _OXS_ARRAYCALARFIELD
