/* fieldValue.C */

#include "vrml.H"
#include "error.H"

char *fieldTypeName(const fieldType& type)
{
  return (type == tdummy ? "dummy" :

	 (type == tSFBool ? "SFBool" :
	  (type == tSFString ? "SFString" :
	   (type == tSFInt32 ? "SFInt32" :
	    (type == tSFFloat ? "SFFloat" :
	     (type == tSFTime ? "SFTime" :
	      (type == tSFVec2f ? "SFVec2f" :
	       (type == tSFVec3f ? "SFVec3f" :
		(type == tSFColor ? "SFColor" :
		 (type == tSFRotation ? "SFRotation" :
		  (type == tSFImage ? "SFImage" :
		   (type == tSFNode ? "SFNode" :

	   (type == tMFBool ? "MFBool" :
	    (type == tMFString ? "MFString" :
	     (type == tMFInt32 ? "MFInt32" :
	      (type == tMFFloat ? "MFFloat" :
	       (type == tMFTime ? "MFTime" :
		(type == tMFVec2f ? "MFVec2f" :
		 (type == tMFVec3f ? "MFVec3f" :
		  (type == tMFColor ? "MFColor" :
		   (type == tMFRotation ? "MFRotation" :
		    (type == tMFImage ? "MFImage" :
		     (type == tMFNode ? "MFNode" :

		      "invalid" )))))))))))))))))))))));
}

ostream& operator<<(ostream& s, fieldValueBase& v)
{
#ifdef NEVER
  if (v.anyValue == 0)  return s << "nil";

  switch (v.type) {
  case tSFBool:		return s << *v.sfboolValue; 
  case tSFString:	return s << *v.sfstringValue; 
  case tSFInt32:	return s << *v.sfint32Value; 
  case tSFFloat:	return s << *v.sffloatValue; 
  case tSFTime:		return s << *v.sftimeValue; 
  case tSFVec2f:	return s << *v.sfvec2fValue; 
  case tSFVec3f:	return s << *v.sfvec3fValue; 
  case tSFColor:	return s << *v.sfcolorValue; 
  case tSFRotation:	return s << *v.sfrotationValue; 
  case tSFImage:	return s << *v.sfimageValue; 
  case tSFNode:		return s << *v.sfnodeValue; 
  case tMFBool:		return s << *v.mfboolValue; 
  case tMFString:	return s << *v.mfstringValue; 
  case tMFInt32:	return s << *v.mfint32Value; 
  case tMFFloat:	return s << *v.mffloatValue; 
  case tMFTime:		return s << *v.mftimeValue; 
  case tMFVec2f:	return s << *v.mfvec2fValue; 
  case tMFVec3f:	return s << *v.mfvec3fValue; 
  case tMFColor:	return s << *v.mfcolorValue; 
  case tMFRotation:	return s << *v.mfrotationValue; 
  case tMFImage:	return s << *v.mfimageValue; 
  case tMFNode:		return s << *v.mfnodeValue; 
  default:		Fatal(-1, "operator<<(ostream&, fieldValueBase&)", "invalid type '%d'", v.type); return s << "BOEM!\n";
  }
#endif
  return s;
}

void fieldValue::do_duplicate(fieldValue& v)
{
  switch (type) {	// type == v.type, we checked that.
  case tSFBool:		sfboolValue = new SFBool(*v.sfboolValue); break;
  case tSFString:	sfstringValue = new SFString(*v.sfstringValue); break;
  case tSFInt32:	sfint32Value = new SFInt32(*v.sfint32Value); break;
  case tSFFloat:	sffloatValue = new SFFloat(*v.sffloatValue); break;
  case tSFTime:		sftimeValue = new SFTime(*v.sftimeValue); break;
  case tSFVec2f:	sfvec2fValue = new SFVec2f(*v.sfvec2fValue); break;
  case tSFVec3f:	sfvec3fValue = new SFVec3f(*v.sfvec3fValue); break;
  case tSFColor:	sfcolorValue = new SFColor(*v.sfcolorValue); break;
  case tSFRotation:	sfrotationValue = new SFRotation(*v.sfrotationValue); break;
  case tSFImage:	sfimageValue = new SFImage(*v.sfimageValue); break;
  case tSFNode:		sfnodeValue = new SFNode*(*v.sfnodeValue); break;
  case tMFBool:		mfboolValue = new MFBool(*v.mfboolValue); break;
  case tMFString:	mfstringValue = new MFString(*v.mfstringValue); break;
  case tMFInt32:	mfint32Value = new MFInt32(*v.mfint32Value); break;
  case tMFFloat:	mffloatValue = new MFFloat(*v.mffloatValue); break;
  case tMFTime:		mftimeValue = new MFTime(*v.mftimeValue); break;
  case tMFVec2f:	mfvec2fValue = new MFVec2f(*v.mfvec2fValue); break;
  case tMFVec3f:	mfvec3fValue = new MFVec3f(*v.mfvec3fValue); break;
  case tMFColor:	mfcolorValue = new MFColor(*v.mfcolorValue); break;
  case tMFRotation:	mfrotationValue = new MFRotation(*v.mfrotationValue); break;
  case tMFImage:	mfimageValue = new MFImage(*v.mfimageValue); break;
  case tMFNode:		mfnodeValue = new MFNode(*v.mfnodeValue); break;
  default:		Fatal(-1, "fieldValue::duplicate", "invalid type '%d'", type);
  }
}

void fieldValue::duplicate(fieldValue& v)
{
  if (!v.anyValue) {
    Fatal(-1, "fieldValue::duplicate", "nil source");
  }
  check(v.type);
  do_duplicate(v);
}

void fieldValue::instantiate(Proto *master)
{
  if (!anyValue) {
    Fatal(-1, "fieldValue::instantiate", "nil source");
  }
  switch (type) {
  case tSFNode:		sfnodeValue = new SFNode*(*sfnodeValue ? (*sfnodeValue)->instantiate(master) : 0); break;
  case tMFNode:		mfnodeValue = mfnodeValue->instantiate(master); break;
  default:
    do_duplicate(*this);
  }
}

void fieldValue::do_assign(fieldValue& v)
{
  if (!v.anyValue) {
    Fatal(-1, "fieldValue::do_assign", "nil source");
  }
  check(v.type);

  switch (type) {
  case tSFBool:		*sfboolValue = *v.sfboolValue; break;
  case tSFString:	*sfstringValue = *v.sfstringValue; break;
  case tSFInt32:	*sfint32Value = *v.sfint32Value; break;
  case tSFFloat:	*sffloatValue = *v.sffloatValue; break;
  case tSFTime:		*sftimeValue = *v.sftimeValue; break;
  case tSFVec2f:	*sfvec2fValue = *v.sfvec2fValue; break;
  case tSFVec3f:	*sfvec3fValue = *v.sfvec3fValue; break;
  case tSFColor:	*sfcolorValue = *v.sfcolorValue; break;
  case tSFRotation:	*sfrotationValue = *v.sfrotationValue; break;
  case tSFImage:	*sfimageValue = *v.sfimageValue; break;
  case tSFNode:		*sfnodeValue = *v.sfnodeValue; break;
  case tMFBool:		*mfboolValue = *v.mfboolValue; break;
  case tMFString:	*mfstringValue = *v.mfstringValue; break;
  case tMFInt32:	*mfint32Value = *v.mfint32Value; break;
  case tMFFloat:	*mffloatValue = *v.mffloatValue; break;
  case tMFTime:		*mftimeValue = *v.mftimeValue; break;
  case tMFVec2f:	*mfvec2fValue = *v.mfvec2fValue; break;
  case tMFVec3f:	*mfvec3fValue = *v.mfvec3fValue; break;
  case tMFColor:	*mfcolorValue = *v.mfcolorValue; break;
  case tMFRotation:	*mfrotationValue = *v.mfrotationValue; break;
  case tMFImage:	*mfimageValue = *v.mfimageValue; break;
  case tMFNode:		*mfnodeValue = *v.mfnodeValue; break;
  default:		Fatal(-1, "fieldValue::assign", "invalid type '%d'", type);
  }
}

void fieldValue::assign(fieldValue& v)
{
  if (!anyValue) {
    Fatal(-1, "fieldValue::assign", "nil destination");
  }
  do_assign(v);
}

void fieldValue::assign_or_duplicate_if_nil(fieldValue& v)
{
  if (!anyValue) 
    duplicate(v);
  else
    do_assign(v);
}

fieldValue default_fieldValue(fieldType type)
{
  fieldValue val(type);
  switch (type) {	// type == v.type, we checked that.
  case tSFBool:		val.sfboolValue = new SFBool; break;
  case tSFString:	val.sfstringValue = new SFString; break;
  case tSFInt32:	val.sfint32Value = new SFInt32; break;
  case tSFFloat:	val.sffloatValue = new SFFloat; break;
  case tSFTime:		val.sftimeValue = new SFTime; break;
  case tSFVec2f:	val.sfvec2fValue = new SFVec2f; break;
  case tSFVec3f:	val.sfvec3fValue = new SFVec3f; break;
  case tSFColor:	val.sfcolorValue = new SFColor; break;
  case tSFRotation:	val.sfrotationValue = new SFRotation; break;
  case tSFImage:	val.sfimageValue = new SFImage; break;
  case tSFNode:		val.sfnodeValue = new SFNode*; break;
  case tMFBool:		val.mfboolValue = new MFBool; break;
  case tMFString:	val.mfstringValue = new MFString; break;
  case tMFInt32:	val.mfint32Value = new MFInt32; break;
  case tMFFloat:	val.mffloatValue = new MFFloat; break;
  case tMFTime:		val.mftimeValue = new MFTime; break;
  case tMFVec2f:	val.mfvec2fValue = new MFVec2f; break;
  case tMFVec3f:	val.mfvec3fValue = new MFVec3f; break;
  case tMFColor:	val.mfcolorValue = new MFColor; break;
  case tMFRotation:	val.mfrotationValue = new MFRotation; break;
  case tMFImage:	val.mfimageValue = new MFImage; break;
  case tMFNode:		val.mfnodeValue = new MFNode; break;
  default:		Fatal(-1, "default_fieldValue", "invalid type '%d'", type);
  }
  return val;
}

