#include <Inventor/cve/SoMFComputer.h>

SO_MFIELD_SOURCE(SoMFComputer, SoComputer*, SoComputer*);


void SoMFComputer::initClass(void)
{
  SO_MFIELD_INIT_CLASS(SoMFComputer, SoMField);
}


void SoMFComputer::append(SoComputer *comp)
{
  set1Value(getNum(), comp);
}


void SoMFComputer::insert(SoComputer *comp, int idx)
{
  assert(idx >= 0 && idx <= getNum());
  insertSpace(idx, 1);
  set1Value(idx, comp);
}


SoComputer* SoMFComputer::get(int idx) const
{
  assert(idx >= 0 && idx < getNum());
  return operator[](idx);
}


int SoMFComputer::find(const SoComputer *comp) const
{
  const int c = getNum();
  const SoComputer **a = getValues(0);
  int i;
  for (i=0; i<c; i++)
    if (a[i] == comp)  return i;
  
  return -1;
}


void SoMFComputer::remove(int idx)
{
  assert(idx >= 0 && idx < getNum());
  deleteValues(idx, 1);
}


void SoMFComputer::remove(SoComputer *comp)
{
  int idx = find(comp);
  if (idx != -1)
    remove(idx);
}


void SoMFComputer::removeAll()
{
  setNum(0);
}


void SoMFComputer::replace(int idx, SoComputer *comp)
{
  assert(idx >= 0 && idx < getNum());
  SoComputer *old = get(idx);
  if (old != comp) {
    set1Value(idx, comp);
  }
}


void SoMFComputer::replace(SoComputer *oldcomp, SoComputer *newcomp)
{
  int idx = find(oldcomp);
  if (idx != -1)
    replace(idx, newcomp);
}


void SoMFComputer::insertSpace(int start, int num)
{
  SbBool notificationOld = this->enableNotify(FALSE);

  // make default action
  inherited::insertSpace(start, num);

  // set inserted items to NULL
  const SoComputer **a = getValues(0);
  int i,c = start+num;
  for (i=start; i<c; i++)
    a[i] = NULL;
  
  this->enableNotify(notificationOld);
  if (notificationOld)  this->valueChanged();
}


//
// FOLLOWING code is taken from COIN sources. Copyright by SIM.
//


// Import a single node.
SbBool
SoMFComputer::read1Value(SoInput * in, int index)
{
/*  SoSFNode sfnode;
  SbBool result = sfnode.readValue(in);
  if (result) this->set1Value(index, sfnode.getValue());
  return result;*/
  assert(0);
  return FALSE;
}

// Export a single node.
void
SoMFComputer::write1Value(SoOutput * out, int idx) const
{
  // NB: This code is common for SoMFNode, SoMFPath and SoMFEngine.
  // That's why we check for the base type before writing.

/*  SoBase * base = (SoBase*) this->values[idx];
  if (base) {
    if (base->isOfType(SoNode::getClassTypeId())) {
      ((SoNode*)base)->writeInstance(out);
    }
    else if (base->isOfType(SoPath::getClassTypeId())) {
      SoWriteAction wa(out);
      wa.continueToApply((SoPath*)base);
    }
    else if (base->isOfType(SoEngine::getClassTypeId())) {
      ((SoEngine*)base)->writeInstance(out);
    }
  }
  else {
    out->write("NULL");
  }*/
  assert(0);
}
