// eventIn.C

#include "nodeInterface.H"
#include "world.H"
#include "file.H"

namespace xrml {

inline void eventIn::init(eventIn* ref)
{
  init(ref->Id, fieldType(*ref), ref->do_process);
  timestamp = ref->timestamp;
}

interfaceMember* eventIn::clone(void)
{
  return new eventIn(*this);
}

inline void eventIn::process_forward(const fieldValue& value) const
{
  for (forward_link_list *f=forward_links; f; f=f->next) {
    interfaceMemberRef *forward = (interfaceMemberRef*)(*f);
    forward->ref()->process(forward->refnode, value);
  }
}

inline void eventIn::process_here(SFNode *thisnode, const fieldValue& value)
{
  if (!check_type(value))
    return;

  thisnode->timestamp = timestamp = thisnode->world->time;
  this->value = value;	  // only the pointer to the value and its type are copied.

  if (do_process) 	  // process the eventIn 
    do_process(thisnode, this->value);
}

void eventIn::process(SFNode *thisnode, const fieldValue& value)
{
  process_here(thisnode, value);
  process_forward(value);
}

ostream& eventIn::print(ostream& s)
{
  return print_Id_value(s << "eventIn     ");
}


////////////////////////////////////////////////////////////////////////
class eventInLink: public eventIn, public link {
public:
  PoolDecl(eventInLink, "eventInLink")

  eventInLink(void) {};

  inline eventInLink(SFNode *thisnode, eventIn *thisifm, SFNode *srcnode, eventIn *srcifm)
  {
    eventIn::init(thisifm);
    link::init(srcnode, srcifm, thisnode, thisifm);
  }

  virtual interfaceMember* clone(void)
  {
    return new eventInLink(*this); 
  }

  virtual void instantiate(class SFNode* thisnode, class Proto* enclosing_proto =0)
  {
    link::instantiate(enclosing_proto, thisnode, this);
  }

  virtual ostream& print(ostream& s) 
  {
    eventIn::print(s);
    link::print(s);
    return s
      << ' '
      << ref()->value
      << (ref()->timestamp > timestamp ? " (to be updated)" : " (up to date)");
  }
};

interfaceMember* eventIn::link_eventIn(SFNode* thisnode, SFNode* node, eventIn* ifm)
{
  return new eventInLink(thisnode, this, node, ifm);
}

PoolImpl(eventIn)
PoolImpl(eventInLink)

} // namespace xrml
