// nodeCatalog.C: catalog of builtin XRML node types

// Instructions for adding a new node to the catalog of
// builtin nodes: 
// 1) include the header file for the nodes class
// 2) add 'new <nodeclassname>,' to the SFNode* nodeCatalog[]
//    arrays below, before the sentinel '0'.

#include <string.h>
#include "error.H"
#include "xrml.H"
#include "nodeCatalog.H"
#include "version.H"

// standard VRML'97 nodes
#include "Anchor.H"
#include "Appearance.H"
#include "AudioClip.H"
#include "Background.H"
#include "Billboard.H"
#include "Box.H"
#include "Collision.H"
#include "Color.H"
#include "ColorInterpolator.H"
#include "Cone.H"
#include "Coordinate.H"
#include "CoordinateInterpolator.H"
#include "Cylinder.H"
#include "CylinderSensor.H"
#include "DirectionalLight.H"
#include "ElevationGrid.H"
#include "Extrusion.H"
#include "Fog.H"
#include "FontStyle.H"
#include "Group.H"
#include "ImageTexture.H"
#include "IndexedFaceSet.H"
#include "IndexedLineSet.H"
#include "Inline.H"
#include "LOD.H"
#include "Material.H"
#include "MovieTexture.H"
#include "NavigationInfo.H"
#include "Normal.H"
#include "NormalInterpolator.H"
#include "OrientationInterpolator.H"
#include "PixelTexture.H"
#include "PlaneSensor.H"
#include "PointLight.H"
#include "PointSet.H"
#include "PositionInterpolator.H"
#include "ProximitySensor.H"
#include "ScalarInterpolator.H"
#include "Script.H"
#include "Shape.H"
#include "Sound.H"
#include "Sphere.H"
#include "SphereSensor.H"
#include "SpotLight.H"
#include "Switch.H"
#include "Text.H"
#include "TextureCoordinate.H"
#include "TextureTransform.H"
#include "TimeSensor.H"
#include "TouchSensor.H"
#include "Transform.H"
#include "Viewpoint.H"
#include "VisibilitySensor.H"
#include "WorldInfo.H"

#ifdef PhBRML
// extensions for physically based rendering
#include "PhBAppearance.H"
#include "PhBAtmosphere.H"
#include "PhBTexturedBackground.H"
#include "PhBProceduralBackground.H"
#include "PhBHomogeneousBackground.H"
#include "PhBBackgroundLight.H"
#include "PhBHomogeneousSurface.H"
#include "PhBHeterogeneousSurface.H"
#include "PhBTexturedSurface.H"
#include "PhB3DTexturedSurface.H"
#include "PhBInterpolatedSurface.H"
#include "PhBEDF.H"
#include "PhBDiffuseEmitter.H"
#include "PhBPhongEmitter.H"
#include "PhBSampledIsotropicEmitter.H"
#include "PhBTextureEmitter.H"
#include "PhBProceduralEmitter.H"
#include "PhBSimpleBSDF.H"
#include "PhBFresnelBSDF.H"
#include "PhBDiffuseReflector.H"
#include "PhBPerfectSpecularReflector.H"
#include "PhBPhongReflector.H"
#include "PhBWardReflector.H"
#include "PhBSchlickReflector.H"
#include "PhBLafortuneReflector.H"
#include "PhBAshikminReflector.H"
#include "PhBNeumannReflector.H"
#include "PhBDiffuseRefractor.H"
#include "PhBPerfectSpecularRefractor.H"
#include "PhBPhongRefractor.H"
#include "PhBProceduralScatterer.H"
#include "PhBHomogeneousMedium.H"
#include "PhBTexturedMedium.H"
#include "PhBInterpolatedMedium.H"
#include "PhBPhF.H"
#include "PhBIsotropicPhaseFunction.H"
#include "PhBProceduralPhaseFunction.H"
#include "PhBLxySpectrum.H"
#include "PhBXYZSpectrum.H"
#include "PhBMonochromaticSpectrum.H"
#include "PhBBlackBodySpectrum.H"
#include "PhBSampledSpectrum.H"
#include "PhBTabulatedSpectrum.H"
#include "PhBProceduralSpectrum.H"
#include "PhBMixedSpectrum.H"
#include "PhBInterpolatedSpectrum.H"
#include "PhBSurfaceDistortion.H"
#include "PhBVolumeDistortion.H"
#include "PhBProceduralTexture.H"
#include "PhBImageTexture.H"
#include "PhB3DTextureTransform.H"
#include "PhBProcedural3DTexture.H"
#include "PhBProceduralTextureProjection.H"
#include "PhBSphereTextureProjection.H"
#include "PhBBoxTextureProjection.H"
#include "PhBCylinderTextureProjection.H"
#include "PhBConeTextureProjection.H"
#include "PhBRGBSpectrum.H"
#include "PhBTextureEmitter.H"
#include "PhBMonitorCalibration.H"
#include "PhBLandscapePhotoBackground.H"
#include "PhBNoiseTexture.H"
#include "PhB3DCheckerTexture.H"
#include "PhB3DSpiralTexture.H"
#include "PhB3DNoiseTexture.H"
#include "PhBBumpMap.H"
#include "PhBNormalMap.H"
#include "PhBBrushMap.H"
#include "PhBShadingFrameDistortion.H"
#include "PhBToggleTexture.H"
#include "PhBPixelTexture.H"
#include "PhBHenyeyGreensteinPhaseFunction.H"
#include "PhBSchlickPhaseFunction.H"
#include "PhBTextureFilter.H"
#include "PhBBilinearInterpolation.H"
#endif /*PhBRML*/

namespace xrml {

void node_catalog::init_default(void)
{
  SFNode *nodeCatalog[] = {
  new Anchor,
  new Appearance,
  new AudioClip,
  new Background,
  new Billboard,
  new Box,
  new Collision,
  new Color,
  new ColorInterpolator,
  new Cone,
  new Coordinate,
  new CoordinateInterpolator,
  new Cylinder,
  new CylinderSensor,
  new DirectionalLight,
  new ElevationGrid,
  new Extrusion,
  new Fog,
  new FontStyle,
  new Group,
  new ImageTexture,
  new IndexedFaceSet,
  new IndexedLineSet,
  new Inline,
  new LOD,
  new Material,
  new MovieTexture,
  new NavigationInfo,
  new Normal,
  new NormalInterpolator,
  new OrientationInterpolator,
  new PixelTexture,
  new PlaneSensor,
  new PointLight,
  new PointSet,
  new PositionInterpolator,
  new ProximitySensor,
  new ScalarInterpolator,
  new Script,
  new Shape,
  new Sound,
  new Sphere,
  new SphereSensor,
  new SpotLight,
  new Switch,
  new Text,
  new TextureCoordinate,
  new TextureTransform,
  new TimeSensor,
  new TouchSensor,
  new Transform,
  new Viewpoint,
  new VisibilitySensor,
  new WorldInfo,

#ifdef PhBRML
  new PhBAppearance,
  new PhBAtmosphere,
  new PhBTexturedBackground,
  new PhBHomogeneousBackground,
  new PhBBackgroundLight,
  new PhBProceduralBackground,
  new PhBHomogeneousSurface,
  new PhBHeterogeneousSurface,
  new PhBTexturedSurface,
  new PhB3DTexturedSurface,
  new PhBInterpolatedSurface,
  new PhBEDF,
  new PhBDiffuseEmitter,
  new PhBPhongEmitter,
  new PhBSampledIsotropicEmitter,
  new PhBTextureEmitter,
  new PhBProceduralEmitter,
  new PhBSimpleBSDF,
  new PhBFresnelBSDF,
  new PhBDiffuseReflector,
  new PhBPerfectSpecularReflector,
  new PhBPhongReflector,
  new PhBWardReflector,
  new PhBSchlickReflector,
  new PhBLafortuneReflector,
  new PhBAshikminReflector,
  new PhBNeumannReflector,
  new PhBDiffuseRefractor,
  new PhBPerfectSpecularRefractor,
  new PhBPhongRefractor,
  new PhBProceduralScatterer,
  new PhBHomogeneousMedium,
  new PhBTexturedMedium,
  new PhBInterpolatedMedium,
  new PhBPhF,
  new PhBIsotropicPhaseFunction,
  new PhBProceduralPhaseFunction,
  new PhBLxySpectrum,
  new PhBXYZSpectrum,
  new PhBMonochromaticSpectrum,
  new PhBBlackBodySpectrum,
  new PhBSampledSpectrum,
  new PhBTabulatedSpectrum,
  new PhBProceduralSpectrum,
  new PhBMixedSpectrum,
  new PhBInterpolatedSpectrum,
  //  new PhBSurfaceDistortion,
  new PhBVolumeDistortion,
  new PhBProceduralTexture,
  new PhBImageTexture,
  new PhBProcedural3DTexture,
  new PhB3DTextureTransform,
  new PhBProceduralTextureProjection,
  new PhBSphereTextureProjection,
  new PhBBoxTextureProjection,
  new PhBCylinderTextureProjection,
  new PhBConeTextureProjection,
  new PhBRGBSpectrum,
  new PhBTextureEmitter,
  new PhBMonitorCalibration,
  new PhBLandscapePhotoBackground,
  new PhBNoiseTexture,
  new PhB3DCheckerTexture,
  new PhB3DSpiralTexture,
  new PhB3DNoiseTexture,
  new PhBBumpMap,
  new PhBNormalMap,
  new PhBBrushMap,
  new PhBShadingFrameDistortion,
  new PhBToggleTexture,
  new PhBHenyeyGreensteinPhaseFunction,
  new PhBSchlickPhaseFunction,
  new PhBPixelTexture,
  new PhBTextureFilter,
  new PhBBilinearInterpolation,
#endif /*PhBRML*/

  0		// sentinel
  };

  // count the number of entries
  int nrentries = 0;
  while (nodeCatalog[nrentries])
    nrentries++;
  catalog = MFNode(1);
  catalog.append(nrentries, nodeCatalog);
}

void node_catalog::init(SFNode **cat)
{
  if (!cat) {
    init_default();
  } else {
    // count the number of entries
    int nrentries = 0;
    while (cat[nrentries])
      nrentries++;
    catalog = MFNode(1);
    catalog.append(nrentries, cat);
  }
}

SFNode* node_catalog::lookup(const char *typeId)
{
  for (int i=0; i<catalog.size; i++)
    if (catalog[i] && strcmp(typeId, catalog[i]->typeId) == 0)
      return catalog[i];
  return 0;
}

void node_catalog::check(void)
{
  for (int i=0; i<catalog.size; i++) {
    if (!catalog[i]->is_leaf_class()) {
      Error("node_catalog::check", "Node catalog node %s is not a leaf node class - deleting", catalog[i]->typeId, i);
      catalog[i] = 0;
    }
    else if (catalog[i]->major_version() != MAJOR_VERSION || catalog[i]->minor_version() != MINOR_VERSION)
      Warning("node_catalog::check", "Node catalog node %s has wrong version", catalog[i]->typeId);
  }
}

node_catalog *builtin_nodes = 0;

} // namespace xrml
