/*  
    Crystal Shooter, a first person shooter game engine.
    Homepage: http://members.xoom.com/thieber/cs

    Copyright (C) 1999 Thomas Hieber (thieber@gmx.net)
 
    This program is free software; you can redistribute it and/or modify 
    it under the terms of the GNU General Public License as published by 
    the Free Software Foundation; either version 2 of the License, or 
    (at your option) any later version. 
 
    This program is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    GNU General Public License for more details. 
 
    You should have received a copy of the GNU General Public License 
    along with this program; if not, write to the Free Software 
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
*/

#include "sysdef.h"
#include "csgame/gstd.h"
#include "csgame/gobject.h"

geObject::geObject(geContainer* pContainer)
  : m_SpeedVector(0,0,0)
{   
  m_Speed                = 0.0f;
  m_DistanceLeftToTravel = 0.0f;

  m_pParent              = pContainer;

  if (m_pParent) //will be zero, if this is the world!
  {
    m_pWorld = m_pParent->GetWorld();
    m_pParent->AddObject(this);
  }
}

geObject::~geObject()
{
}

void geObject::SetPosition(csSector* pSector, csVector3 Pos)
{
  gePosition OldPos = m_Pos;
  m_Pos.MoveTo(pSector, Pos);
  OnMove(OldPos);
}

void geObject::SetPosition(gePosition Pos)
{
  SetPosition(Pos.GetSector(), Pos.GetPosition());
}

void geObject::StartMoveTo(csVector3 Destination, float speed)
{
  csVector3 Direction = Destination - m_Pos;
  StartMove(Direction, speed);
}

void geObject::StartMove(csVector3 Direction,   float speed)
{
  m_DistanceLeftToTravel = Direction.Norm();

  if (m_DistanceLeftToTravel > 0.0)
  {
    m_SpeedVector = Direction / m_DistanceLeftToTravel;
  }
  else
  {
    m_SpeedVector = csVector3(0,0,0);
  }

  //internally we will use units per Millisecond as speed measure, so we 
  //divide by 1000, because externally speed will be units per second.
  m_Speed = speed/1000.0; 
}

void geObject::StopMove()
{
  m_SpeedVector          = csVector3(0,0,0);
  m_Speed                = 0.0f;
  m_DistanceLeftToTravel = 0.0f;
}
  
bool geObject::IsOfType(DWORD Type)
{
  if (Type == Type_geObject) return true;
  return false;
}

bool geObject::Move(csVector3 Offset)
{
  return m_Pos.Move(Offset);
}

void geObject::PrepareFrame(long ElapsedTime, long /*CurrentTime*/)
{
  if (m_DistanceLeftToTravel > 0)
  {
    float      distance = m_Speed*ElapsedTime;
    gePosition OldPos   = m_Pos;

    if (!Move(m_SpeedVector*distance))
    {
      HandleWorldCollision();
    }
    else
    {
      OnMove(OldPos);
    }

    m_DistanceLeftToTravel -= distance;
    
    if (m_DistanceLeftToTravel <= 0.0)
    {
      StopMove();
    }
  }
}

void geObject::Destroy()
{
  ASSERT(m_pParent);
  m_pParent->FreeObject(this);
}

geContainer* geObject::GetParent()    
{
  return m_pParent;
}

geWorld* geObject::GetWorld()     
{
  return m_pParent->GetWorld();
}
