/* Autor: Leandro Bernsmuller
Define nova direcao de deslocamento para objeto. */



#include <windows.h>
#include <windowsx.h>
#include <ddraw.h>
#include <d3drmwin.h>
#include "..\..\princip\defs.h"
#include "..\..\cenario\cenario.h"
#include "..\..\cenario\cenfis.h"
#include "acao.h"
#include "..\dados\dados.h"
#include "..\dados\dadosfis.h"
#include "..\agente.h"
#include "mudadir.h"



/* construtor
**********************************************************/
CMudaDirecao::CMudaDirecao ()
{
   m_dwTipoAcao = ID_ACAO_MUDA_DIRECAO;

   m_fPasso = 0;
   m_fDX = m_fDY = m_fDZ = 0;
}



/* Acao.
pDado1 - flags informando se colidiu com limites do cenario
         (ver cenfis.cpp, mDetectaColisaoComBordas)
pDado2 - nao usado
return TRUE - certo / FALSE - erro
**********************************************************/
BOOL CMudaDirecao::mAtiva ( PTRVAL pDado1, PTRVAL pDado2 )
{
   CDadosFisicos
      *poDados = (CDadosFisicos*) m_poMeuAgente->m_poDados;

   // define nova direcao
   if ( m_fPasso == 0 ) {

      // Define nova direcao, conforme a quantidade de energia que possua pode:
      // parar ou mudar a direcao.
      // Verifica se tem pouca energia -> para
      if ( poDados->m_fFome < TX_BOM_MOVER ) {

         // direcao de deslocamento atual
         m_poMeuAgente->m_poCenario->mPegaDirecaoDeslocamentoObjeto ( poDados->m_dwGrupo, poDados->m_dwNdxObjeto, m_fDX, m_fDY, m_fDZ );

         // valor da direcao nunca pode ser zero (problemas ao girar)
         m_fDX = ( m_fDX >= 0 ) ? 0.0001 : -0.0001;
         m_fDY = 0;
      }
      else {

         // se tem mais energia, se move para uma nova direcao

         // define coordenadas do agente
         int
            // nova direcao (escolhe um numero entre -50 e +50)
            nDX = rand () % 100 - 50,
            nDY = rand () % 100 - 50;

         // normaliza valor da direcao de deslocamento (entre -1 e +1 )
         m_fDX = (float) nDX / 50,
         m_fDY = (float) nDY / 50;
      }
      
      m_fDZ = 0;

      // verifica os flags de colisao com o cenario
      if ( ( ( pDado1 & 1 ) && m_fDY > 0 ) ||   // borda superior
           ( ( pDado1 & 2 ) && m_fDY < 0 ) )    // borda inferior
         m_fDY = - m_fDY;
      if ( ( ( pDado1 & 4 ) && m_fDX < 0 ) ||   // borda esquerda
           ( ( pDado1 & 8 ) && m_fDX > 0 ) )    // borda direita
         m_fDX = - m_fDX;
         
      // verifica se deve fazer animacao de rotacao do objeto, ou nao
      // para isso veriica se mudor o lado para o qual o objeto vai
      // (esquerda->direita ou direita->esquerda)

      // direcao de deslocamento atual
      float
         fX, fY, fZ;
      m_poMeuAgente->m_poCenario->mPegaDirecaoDeslocamentoObjeto ( poDados->m_dwGrupo, poDados->m_dwNdxObjeto, fX, fY, fZ );

      // testa lado para onde objeto vai
      if ( ( fX >= 0 && m_fDX >= 0 ) ||   // se vai para direita ou
           ( fX <  0 && m_fDX <  0 ) )    // se vai para esquerda

         // pula parte da rotacao - vai direto para mudanca de direcao         
         m_fPasso = 2.0;

      else {

         // se trocou lado, entao deve fazer animacao (que eh a rotacao)
         // para objeto durante rotacao
         // valor da direcao nunca pode ser zero (problemas ao girar)
         fX = ( fX >= 0 ) ? 0.0001 : -0.0001;
         //m_poMeuAgente->m_poCenario->CCenario::mMudaDirecaoDeslocamentoObjeto ( poDados->m_dwGrupo, poDados->m_dwNdxObjeto, fX, 0.0, 0.0 );
         
         // impede alteracoes de direcao devido a epoca de reproducao
         // desabilita reproducao
         //m_poMeuAgente->mPreparaSubstituirPos ( NDX_EVENTO_ATIVIDADE_3, ID_ACAO_NULA, ID_ACAO_NULA );
      }
   }

   // faz a animacao de rotacao
   if ( m_fPasso < 1.0 )
      m_poMeuAgente->m_poCenario->mRotacionaObjeto ( poDados->m_dwGrupo, poDados->m_dwNdxObjeto, 0.0, 1.0, 0.0, 3.14159265359 / 3 );

   // prepara para substituir estah acao
   if ( m_fPasso >= 1.0 ) {

      // atualiza direcao
      m_poMeuAgente->m_poCenario->CCenario::mMudaDirecaoDeslocamentoObjeto ( poDados->m_dwGrupo, poDados->m_dwNdxObjeto, m_fDX, m_fDY, m_fDZ );

      // informa quando foi a mudanca de direcao
      poDados->m_dwTempoUltimaDir = ::GetTickCount ();
      
      // rehabilita reproducao
      //m_poMeuAgente->mSubstituiAcao ( NDX_EVENTO_ATIVIDADE_3, ID_ACAO_PREPARA_REPRODUZ, ID_ACAO_PREPARA_REPRODUZ );

      // substitui estah acao por outra
      m_poMeuAgente->mPreparaSubstituirPos ( m_dwNdxMeuEvento, m_dwTipoSubs, m_dwTipoSubs );

      m_fPasso = 0;
   }
   else
      m_fPasso += 0.3335;
                          // resumo - para alterar o numero de passos:
                          // no "m_fPasso +=" calcular (1/numero_passos)
                          // e no mRotacionaObjeto (acima)
                          //   Pi / numero_passos

   return TRUE;
}
