#ifndef EVARTYPE_H
#define EVARTYPE_H

#include "eutils.h"
#include "evarbase.h"

///////////////////////////////////////////////////////////////////////////////
//
//  Objects
//

#include <typeinfo>

#include "estr.h"

template <class T>
class evarType : public evarBase
{
 public:
  T* object;
  evarType(const evarType<T>& o): object(o.object) {this->cleanup=false;}
  evarType(): object(0x00) {cleanup=false;}
  evarType(T& val): object(&val) {cleanup=false;}
  evarType(T* val): object(val) {cleanup=false;}
  virtual ~evarType() {}
  
  inline const type_info& getTypeid() {return(typeid(T));}
  inline const type_info& getPTypeid() {return(typeid(T*));}
  inline bool isTypeid(const type_info& tid) { return(tid==typeid(T) || tid==typeid(T*) || tid==typeid(T&) || tid==typeid(const T&));}
  inline const char *getClass() {return(typeid(T).name());}
  inline evarBase *copy() { return(new evarType<T>(*this)); } 
};

template <>
class evarType<void> : public evarBase
{
 public:
  void* object;
  evarType(const evarType<void>& o) : object(o.object) { this->cleanup = false; }
  evarType() : object(0x00) { cleanup = false; }
  evarType(void* val) : object(val) { cleanup = false; }
  virtual ~evarType() {}

  inline const type_info& getTypeid() { return(typeid(void)); }
  inline const type_info& getPTypeid() { return(typeid(void*)); }
  inline bool isTypeid(const type_info& tid) { return(tid == typeid(void) || tid == typeid(void*)); }
  inline const char *getClass() { return(typeid(void).name()); }
  inline evarBase *copy() { return(new evarType<void>(*this)); }
};

template <class T>
class evarTypeClean : public evarType<T>
{
 public:
  evarTypeClean() {}
  evarTypeClean(T& val): evarType<T>(val) {}
  evarTypeClean(T* val): evarType<T>(val) { this->cleanup=true; }
  virtual ~evarTypeClean() { if (this->object && this->cleanup) delete this->object; }
};

#endif

