/// 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 X3DFIELD_H
#define X3DFIELD_H

#include "SFString.h"
#include <typeinfo>

namespace X3DTK {

class X3DField
{
  friend bool operator== (const X3DField &f1, const X3DField &f2);
  friend bool operator!= (const X3DField &f1, const X3DField &f2);

public:
  X3DField(const std::type_info &type, unsigned char *data);
  inline const std::type_info &getType() const {return _type;};
  inline unsigned char *data() const {return _data;};

private:  
  const std::type_info &_type;
  unsigned char *_data;

public:
  static const X3DField null;  
};

inline bool operator== (const X3DField &f1, const X3DField &f2)
{
  return ((f1._type == f2._type) && (f1._data == f2._data));
}

inline bool operator!= (const X3DField &f1, const X3DField &f2)
{
  return ((f1._type != f2._type) || (f1._data != f2._data));
}

class X3DFieldLoader
{
public:
  virtual ~X3DFieldLoader() {}
  virtual void load(X3DField &field, const SFString &value) = 0;
};

template<class V>
class FieldLoader : public X3DFieldLoader
{
public:
  void load(X3DField &field, const SFString &value);
};


class X3DFieldWriter
{
public:
  virtual ~X3DFieldWriter() {}
  virtual SFString write(const X3DField &field) = 0;
  virtual void writeToFile(SFString &output, const SFString &name, const X3DField &field, const SFString &init) = 0;
};

template<class V>
class FieldWriter : public X3DFieldWriter
{
public:
  SFString write(const X3DField &field);
  void writeToFile(SFString &output, const SFString &name, const X3DField &field, const SFString &init);
  void write(SFString &output, const V &value);
};


template<>
class FieldLoader<bool> : public X3DFieldLoader
{
public:
  void load(X3DField &field, const SFString &value);
};

template<>
class FieldLoader<int> : public X3DFieldLoader
{
public:
  void load(X3DField &field, const SFString &value);
};

template<>
class FieldLoader<float> : public X3DFieldLoader
{
public:
  void load(X3DField &field, const SFString &value);
};

template<>
class FieldWriter<bool> : public X3DFieldWriter
{
public:
  SFString write(const X3DField &field);
  void writeToFile(SFString &output, const SFString &name, const X3DField &field, const SFString &init);
  void write(SFString &output, const bool &value);
};

template<>
class FieldWriter<int> : public X3DFieldWriter
{
public:
  SFString write(const X3DField &field);
  void writeToFile(SFString &output, const SFString &name, const X3DField &field, const SFString &init);
  void write(SFString &output, const int &value);
};

template<>
class FieldWriter<float> : public X3DFieldWriter
{
public:
  SFString write(const X3DField &field);
  void writeToFile(SFString &output, const SFString &name, const X3DField &field, const SFString &init);
  void write(SFString &output, const float &value);
};

}

#include "X3DField.inl"

#endif
