/// This file is part of the X3DToolKit library
/// Copyright (C) 2002-2004  Yannick Le Goc (legoc@imag.fr)

/// http://artis.imag.fr/Members/Yannick.Legoc/X3D/

/// This library is free software; you can redistribute it and/or
/// modify it under the terms of the GNU Lesser General Public
/// License as published by the Free Software Foundation; either
/// version 2.1 of the License, or (at your option) any later version.

/// This library 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
/// Lesser General Public License for more details.

/// You should have received a copy of the GNU Lesser General Public
/// License along with this library; if not, write to the Free Software
/// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#ifndef X3DTK_RECORDER_H
#define X3DTK_RECORDER_H

#include "BaseRecorder.h"
#include "EnterFunction.h"
#include "WalkOnFunction.h"
#include "LeaveFunction.h"
#include "CreationFunction.h"
#include "NodeFactory.h"
#include "SFSceneGraph.h"
#include "X3DAttributeRecorder.h"
#include "X3DNodeCloner.h"
#include "X3DSFNodeRecorder.h"
#include "X3DMFNodeRecorder.h"

#include <utility>

namespace X3DTK {

class X3DAbstractNode;

struct StringType
{
  SFString type;
  SFString component;
  SFString sceneGraph;
  SFString encodedName;
};

struct TypeName
{
  SFString name;
  SFString component;
  SFString sceneGraph;
  X3DNodeCloner *cloner;
};

/*! \brief Class declared in <b><X3DTK/kernel.h></b> defining a recorder for 
 *  members of X3DTK::X3DComponentVisitor and X3DTK::X3DAbstractNode. 
 *  
 * For the recording of callbacks, it extracts the necessary informations relative 
 * to the type of the node processed by the recorded function. The functions must be 
 * static. For the attributes of the X3DTK::X3DAbstractNode, a same kind of syntax is 
 * used.
 *
 * \ingroup base
 */
 
template<class T, class V = nil>
class Recorder : public BaseRecorder
{
public:
  /// Records an enter function for an X3DTK::X3DComponentVisitor.
  static std::pair<StringType, EnterFunction *> getEnterFunction(void (*ptrF)(T *));
  /// Records a walkOn function for an X3DTK::X3DComponentVisitor.
  static std::pair<StringType, WalkOnFunction *> getWalkOnFunction(bool (*ptrF)(T *, SFNode));
  /// Records a leave function for an X3DTK::X3DComponentVisitor.
  static std::pair<StringType, LeaveFunction *> getLeaveFunction(void (*ptrF)(T *));
  /// Records a creation function for an X3DTK::X3DComponentVisitor.  
  static std::pair<StringType, CreationFunction *> getCreationFunction();
  /// Records a new node.
  static TypeName getTypeName(const SFString &name, const SFString &component = SFString(""), const SFString &sceneGraph = SFString(""));
  /// Records an attribute for an X3DTK::X3DAbstractNode.  
  static AttributeRecorder<T, V> getAttribute(const SFString &name, V T:: *member, const V &init);
  /// Records a single field node for an X3DTK::X3DAbstractNode.  
  static SFNodeRecorder<T, V> getSFNode(const SFString &name, V *T:: *node);
  /// Records a multiple field node for an X3DTK::X3DAbstractNode.  
  static MFNodeRecorder<T, V> getMFNode(const SFString &name, MFNode T:: *nodes);
};

}

#include "Recorder.inl"

#endif
