/******************************************************************
  
  Module:  aidebugdraw.cpp
  
  Author: Borut Pfeifer
  
  Copyright 2005 Sony Online Entertainment.  All rights reserved.
  
*******************************************************************/

//-------------------------------------------------------- Includes
#include "aidebugdraw.h"
//---------------------------------------------- Class Declarations
//----------------------------------------- Functions Declarations
//------------------------------------ Member Functions Definitions
//------------------------------------ cLOSTable

#ifdef _AIDEBUGDRAW

#include <vector>
#include "..\registry.h"
#include "..\stats.h"
#include "SyRaster.h"
#include "SyCamera.h"

tGameObjectID cAIDebugDraw::smSelectedID = ID_NONE;
static std::vector<cAIDebugDraw::Line> sAIDebugLines; // internal to the file to avoid include <vector> in places

bool cAIDebugDraw::smbEnabled = false;

const SyColor32F cAIDebugDraw::RED       = SyColor32F(1.0f, 0.0f, 0.0f, 1.0f);
const SyColor32F cAIDebugDraw::GREEN     = SyColor32F(0.0f, 1.0f, 0.0f, 1.0f);
const SyColor32F cAIDebugDraw::BLUE      = SyColor32F(0.0f, 0.0f, 1.0f, 1.0f);
const SyColor32F cAIDebugDraw::CYAN      = SyColor32F(0.0f, 1.0f, 1.0f, 1.0f);
const SyColor32F cAIDebugDraw::MAGENTA   = SyColor32F(1.0f, 0.0f, 1.0f, 1.0f);
const SyColor32F cAIDebugDraw::YELLOW    = SyColor32F(1.0f, 1.0f, 0.0f, 1.0f);
const SyColor32F cAIDebugDraw::WHITE     = SyColor32F(1.0f, 1.0f, 1.0f, 1.0f);
const SyColor32F cAIDebugDraw::BLACK     = SyColor32F(0.0f, 0.0f, 0.0f, 1.0f);

void cAIDebugDraw::DrawLine(tGameObjectID npcID, const SyVect3& start, const SyVect3& end, SyColor32F color)
{
  if (!smbEnabled)
  {
    return;
  }

  Line l;
  l.start = start;
  l.end = end;
  l.color = color;
  l.npcID = npcID;
  sAIDebugLines.push_back(l);
}

void cAIDebugDraw::DrawBox(tGameObjectID npcID, const SyVect3& v0, const SyVect3& v1, const SyVect3& v2, const SyVect3& v3, SyColor32F color)
{
  if (!smbEnabled)
  {
    return;
  }

}

void cAIDebugDraw::Toggle()
{
  smbEnabled = !smbEnabled;
  smSelectedID = ID_NONE;
}

void cAIDebugDraw::SelectNextNPC(cGameObjectRegistry* pRegistry, SyCamera* pCam)
{
  if (!smbEnabled)
  {
    return;
  }

  cGameObject* pObj;
  SyFrustum frustum = pCam->GetFrustum();
  SyVect3 camLoc(pCam->GetLocation());
  tGameObjectID bestID = ID_NONE;
  float distSqr, bestDistSqr = 0.0f;
  float selectedDistSqr = 0.0f;


  if (smSelectedID != ID_NONE)
  {
    cGameObject* pCur = pRegistry->Fetch(smSelectedID);

    if (pCur)
    {
      selectedDistSqr = camLoc.DistanceSquared(pCur->GetLocation());
    }
  }

  for (int i=pRegistry->Begin(); i!=pRegistry->End(); i=pRegistry->Next(i))
  {
    pObj = (*pRegistry)(i);
    if (pObj != NULL && 
        pObj->GetType() == cGameObject::OBJ_NPC &&
        pObj->GetID() != smSelectedID && 
        frustum.Cull(pObj->GetLocation(), 1.0f) == 0 &&
        !pObj->GetStats()->IsDead())
    {      
      distSqr = pObj->GetLocation().DistanceSquared(camLoc) - selectedDistSqr;
      if (ID_NONE == bestID || distSqr < bestDistSqr)
      {
        bestID = pObj->GetID();
        bestDistSqr = distSqr;
      }
    }
  }

  if (bestID != ID_NONE)
  {
    smSelectedID = bestID;
  }
}

void cAIDebugDraw::SelectPrevNPC(cGameObjectRegistry* pRegistry, SyCamera* pCam)
{
  if (!smbEnabled)
  {
    return;
  }

  cGameObject* pObj;
  SyFrustum frustum = pCam->GetFrustum();
  SyVect3 camLoc(pCam->GetLocation());
  tGameObjectID bestID = ID_NONE;
  float distSqr, bestDistSqr = 0.0f;
  float selectedDistSqr = 0.0f;

  if (smSelectedID != ID_NONE)
  {
    cGameObject* pCur = pRegistry->Fetch(smSelectedID);

    if (pCur)
    {
      selectedDistSqr = camLoc.DistanceSquared(pCur->GetLocation());
    }
  }

  for (int i=pRegistry->Begin(); i!=pRegistry->End(); i=pRegistry->Next(i))
  {
    pObj = (*pRegistry)(i);
    if (pObj != NULL && 
        pObj->GetType() == cGameObject::OBJ_NPC &&
        pObj->GetID() != smSelectedID &&
        frustum.Cull(pObj->GetLocation(), 1.0f) == 0 &&
        !pObj->GetStats()->IsDead())
    {      
      distSqr = pObj->GetLocation().DistanceSquared(camLoc) - selectedDistSqr;
      if (ID_NONE == bestID || distSqr > bestDistSqr)
      {
        bestID = pObj->GetID();
        bestDistSqr = distSqr;
      }
    }
  }

  if (bestID != ID_NONE)
  {
    smSelectedID = bestID;
  }
}


void cAIDebugDraw::Render(SyRaster* pRasterDev, SyCamera* pCam)
{
  if (!smbEnabled)
  {
    return;
  }

  std::vector<Line>::iterator iLine = sAIDebugLines.begin();

  SyMatrix44 identityMat;
  identityMat.Identity();
  
  pRasterDev->SetWorld(identityMat);
  pRasterDev->SetSolidFillUIMaterial();
  SyVect3 normal( 0.0f, 0.0f, 0.0f );

  while (iLine != sAIDebugLines.end())
  {
    if (ID_NONE == iLine->npcID ||
        ID_NONE == smSelectedID ||
        iLine->npcID == smSelectedID)
    {
      pRasterDev->BeginLines();
      pRasterDev->Color( iLine->color );
      pRasterDev->Normal( normal );
      pRasterDev->Vertex( iLine->start );
      pRasterDev->Vertex( iLine->end );
      pRasterDev->EndLines();
    }

    ++iLine;
  }

  sAIDebugLines.clear();
}

#endif
// EOF
