#include "SceneNode.h"

namespace BlueCore {

#define DEBUG_SCENEGRAPH

//------------------------------------------------------------------------------
SceneNode::SceneNode() :
  Named("unnamed SceneNode"), _Parent(0)
{
#ifdef DEBUG_SCENEGRAPH
  clog << "SceneNode 'Unnamed SceneNode' created." << endline;
#endif
}

//------------------------------------------------------------------------------
SceneNode::SceneNode(const std::string &name) :
  Named(name), _Parent(0)
{
#ifdef DEBUG_SCENEGRAPH
  clog << "SceneNode '" << name << "' created." << endline;
#endif
}

//------------------------------------------------------------------------------
SceneNode::~SceneNode()
{
  detachAll();

  #ifdef DEBUG_SCENEGRAPH
  clog << "SceneNode '" << getName() << "' deleted." << endline;
  #endif
}

//------------------------------------------------------------------------------
void SceneNode::attach(SceneNode *node)
{
  if (node == 0)
    return;

  _Children.push_back(node );

  node->_Parent = this;

  node->addReference();

#ifdef DEBUG_SCENEGRAPH
  clog << "SceneNode '" << node->getName() << "' attached to '" << this->getName() << "'" << endline;

#endif
}

//------------------------------------------------------------------------------
void SceneNode::detach(SceneNode *node)
{
  node->_Parent = 0;
  node->removeReference();

  _Children.remove(node );

#ifdef DEBUG_SCENEGRAPH
  clog << "SceneNode '" << node->getName() << "' detach from '" << this->getName() << "'" << endline;
#endif
}

//------------------------------------------------------------------------------
void SceneNode::detachAll()
{
  SceneNodeList::iterator i;

  for (i = _Children.begin(); i != _Children.end(); i++)
  {
    ( *i )->_Parent = 0;
    ( *i )->removeReference();
  }

  _Children.clear();
}

//------------------------------------------------------------------------------
SceneNode *SceneNode::getParent() const
{
  return _Parent;
}

//------------------------------------------------------------------------------
void SceneNode::detachFromParent()
{
  if (_Parent )
    _Parent->detach( this);
}

//------------------------------------------------------------------------------
const SceneNode::SceneNodeList& SceneNode::getChildren () const
{
  return _Children;
}

//------------------------------------------------------------------------------
void SceneNode::update(Scalar time)
{
  updateAbsoluteTransformation();

//  if (isActive() )
  {
    SceneNodeList::iterator i;

    for (i = _Children.begin(); i != _Children.end(); i++)
      ( *i )->update(time );
  }
}

//------------------------------------------------------------------------------
void SceneNode::render(RenderDevice *device, Camera *camera)
{
  if (isActive() )
  {
    SceneNodeList::iterator i;

    for (i = _Children.begin(); i != _Children.end(); i++)
    {
      ( *i )->render(device, camera);
    }
  }
}

//------------------------------------------------------------------------------
const Transformation& SceneNode::getRelativeTransformation()
{
  return _RelativeTransformation;
}

const Transformation& SceneNode::getAbsoluteTransformation()
{
  return _AbsoluteTransformation;
}

//------------------------------------------------------------------------------
void SceneNode::setRelativeTranslation(const Vector3 &translation)
{
  _RelativeTransformation.translation = translation;
}

//------------------------------------------------------------------------------
void SceneNode::setRelativeRotation (const Quaternion &rotation)
{
  _RelativeTransformation.rotation = rotation;
}

//------------------------------------------------------------------------------
void SceneNode::updateAbsoluteTransformation()
{
/*
  if (_Parent )
    _AbsoluteTranslation = _Parent->getAbsoluteTranslation()
        +_Parent->getAbsoluteRotation().inversed() * _RelativeTranslation;
  else
    _AbsoluteTranslation = _RelativeTranslation;
    */
}

} // namespace BlueCore
