/*  
    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 "csgame/gstd.h"
#include "sentry.h"

/* This class will encapsulate a special monster: the sentry. That monster is 
   a free model made by model by Guard|aN (cheng318@vol.net) that was modified 
   by The Serpent Lord (Seth Galbraith) (sgalbrai@linknet.kitsap.lib.wa.us) 
   see sentry.txt for details

   The sentry knows the following animation phases:
   	ACTION 'base'  (1  frame)  'base'
	ACTION 'death' (6  frames) 'death1'-'death6'
	ACTION 'pain'  (5  frames) 'pain1' -'pain5'
	ACTION 'stand' (12 frames) 'stand1'-'stand12'
	ACTION 'rock'  (6  frames) 'rock1' -'rock6'
	ACTION 'nail'  (2  frames) 'nail1' -'nail2'
	ACTION 'run'   (6  frames) 'run1'  -'run6'
	ACTION 'walk'  (12 frames) 'walk1' -'walk12'

  This class is supposed to both control the animation phases and the
  behaviour of this monster.
*/

static geSentry::Phase PatrolPhases[] = 
{geSentry::PH_Walk, 
 geSentry::PH_Look, 
 geSentry::PH_Walk,  
 geSentry::PH_Look, 
 geSentry::PH_Walk,  
 geSentry::PH_Repeat};

/*
static geSentry::Phase AttackPhases[] = 
{geSentry::PH_Walk, 
 geSentry::PH_Look, 
 geSentry::PH_Shoot, 
 geSentry::PH_Look, 
 geSentry::PH_Shoot, 
 geSentry::PH_Repeat};

static geSentry::Phase FleePhases[]   = 
{geSentry::PH_Run,  
 geSentry::PH_Look, 
 geSentry::PH_Run,   
 geSentry::PH_Run,  
 geSentry::PH_Repeat};
*/
static geSentry::Phase DeathPhases[]  = 
{geSentry::PH_Die,  
 geSentry::PH_End};


geSentry::geSentry(geContainer* pContainer)
 : inherited(pContainer)
{
  m_Phases       = PatrolPhases;
  m_PhaseCounter = 0;
  m_Phaseloop    = 1;
  m_Direction    = 0.0f;
}

geSentry::~geSentry()
{
}

void geSentry::Create(gePosition Pos)
{
  inherited::Create(Pos, "sentry");
  m_Health = 20;
}

void geSentry::Hit(int Damage, gePhysicalObject* pHitObject)
{
  inherited::Hit(Damage, pHitObject);
  if (IsAlive())
  {
    m_pSprite->SetAction("pain", false);
  }
}

void geSentry::Die(gePhysicalObject* pLastHitObject)
{
  inherited::Die(pLastHitObject);
  //m_pSprite->SetAction("death", false);
  m_PhaseCounter = 0;
  m_Phases       = DeathPhases;
  OnFinishedAnimation(m_pSprite);
}

csVector3 geSentry::GetRandomMoveDirection()
{
  m_Direction = ((float)rand()/(float)RAND_MAX)*2000.0f;

  float sd = sin(m_Direction);
  float cd = cos(m_Direction);

  csMatrix3 m(sd,0,-cd, 0,1,0, cd,0,sd);

  m_pSprite->GetCsSprite()->SetTransform (m);
  return csVector3(sin(m_Direction), 0, cos(m_Direction));
}

void geSentry::OnFinishedAnimation(geSprite3D* /*pSprite*/)
{
  if (m_Phases[m_PhaseCounter] == PH_End)    return;
  if (m_Phases[m_PhaseCounter] == PH_Repeat) m_PhaseCounter = 0;

  if (--m_Phaseloop > 0) return;

  Phase NextPhase = m_Phases[m_PhaseCounter];
  m_PhaseCounter++;
  m_Phaseloop = 1;

  switch (NextPhase)
  {
    case PH_Walk:
      m_pSprite->SetAction("walk", true);
      StartMove(GetRandomMoveDirection()*20.0f, 1.4f);
      m_Phaseloop = 3;
      break;
    case PH_Run:
      m_pSprite->SetAction("run", false);
      StopMove();
      break;
    case PH_Look:
      m_pSprite->SetAction("stand", false);
      StopMove();
      break;
    case PH_Shoot:
      m_pSprite->SetAction("rock", false);
      StopMove();
      break;
    case PH_Die:
      m_pSprite->SetAction("death", false);
      StopMove();
      break;
    default:
      break;
  }
}

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

/*  bool collision = false;

  if (m_pSprite)
  {
    gePhysicalObject* pOther = NULL;
    gePosition NewPosition = m_Pos;

    collision = m_pSprite->FindFirstCollision(Offset, NewPosition, pOther);

    SetPosition(NewPosition);
  
    if (collision)
    {
      m_pSprite->OnCollision(pOther);
    }
  }

  return !collision;*/
}

void geSentry::HandleWorldCollision()
{
  StartMove(GetRandomMoveDirection()*20.0f, 1.4f);
}
