//-------------------------------------------------------------------
//
//  This code is copyright 2001 by G5 Software.
//  Any unauthorized usage, either in part or in whole of this code
//  is strictly prohibited. Violators WILL be prosecuted to the
//  maximum extent allowed by law.
//
//-------------------------------------------------------------------

// *** Bases for AI specific behavior ***
//
// use SetBehaviorTask function to specify mission task for behavior
//

class CBaseAITask_BaseTask
{
  //
  // *** 'virtual' functions ***
  //
  // All functions do nothing by default. Overwrite if needed
  //


  //
  // start up initialization

  void Init() {}            // called by CVehicleBehavior after assign

  //
  // events

  void OnEnemyTargeted() {} // called when enemy targeted by a gun

  void OnNoEnemy() {}       // called when all enemy disapeared from radar

  void OnUpdate() {}        // called every game takt to synchronize

  void OnStopped() {}       // called when unit stop

  string OnGetDebugInfo()   // called when behavior renders debug information
  {                         // returned string will be appended to output text
    return "";
  }

  void OnOrderedEnemyKilled() // called when the enemy (specified by SetFireStyle_Enemy) was killed
  {
    SetFireStyle_Nearest();
  }

  void OnLeaderLost( string _LeaderID) {} // called when leader (specified by SetOrder_Follow or SetOrder_Formation) is lost
  
  void OnEnemyLost( string _EnemyID) {}   // called when enemy (specified by SetOrder_Attack) is lost
}

class CBaseAITask_Patrol extends CBaseAITask_BaseTask
{
  //
  //  ***  'pure virtual' functions
  //
  // the functions should be overwritten
  //

  // Overwrite this function to specify patrol trip
  // the function shoud return array of vectors

  array GetPatrolTrip()
  {
    return array(); // the default implementation returns empty array
  }


  //
  //  ***  'virtual' functions
  //
  // the functions can be overwritten to implement specific patrol logic
  //

  void ResetTripPointIndex()
  {
    m_TripPointIndex = 0;
  }

  boolean HasMoreTripPoints()
  {
    array Trip = GetPatrolTrip();

    return ( Trip.size() > 0);
  }

  void IncrementTripPointIndex()
  {
    // default implementation cycles trip points

    array Trip = GetPatrolTrip();

    m_TripPointIndex = m_TripPointIndex + 1;

    if ( m_TripPointIndex >= Trip.size())
      m_TripPointIndex = 0;
  }

  vector GetNowTripPoint()
  {
    array Trip = GetPatrolTrip();
    return ( Trip[m_TripPointIndex]);
  }

  float GetTripSpeed()
  {
    // default implementation returns vehicle maximum speed
    return MaxSpeed; // this property returns by script user
  }


  //
  //  ***  notification handlers
  //

  // called by Behavior on initialization

  void Init()
  {
    Notify_Init();

    StartPatrol();
  }

  void StartPatrol()
  {
    m_Active = true;

    // set start trip point
    ResetTripPointIndex();

    if ( HasMoreTripPoints())
    {
      // order to move to current trip point
      SetOrder_MoveTo(
        GetNowTripPoint(),
        GetTripSpeed());
    }
  }

  void ActivatePatrol()
  {
    if ( !m_Active && HasMoreTripPoints())
    {
      // order to move to current trip point
      SetOrder_MoveTo(
        GetNowTripPoint(),
        GetTripSpeed());
    }

    m_Active      = true;
    m_AttackState = false;
  }

  void DeactivatePatrol()
  {
    m_Active      = false;
    m_AttackState = false;

    SetOrder_StopNow();
  }

  // called by Behavior when movement stopped
  void OnStopped()
  {
    if ( m_Active && !m_AttackState)
    {
      // trip point reached. move to next one
      IncrementTripPointIndex();

      if ( HasMoreTripPoints())
      {
        // order to move to current trip point
        SetOrder_MoveTo(
          GetNowTripPoint(),
          GetTripSpeed());
      };
    }
  }


  void OnEnemyTargeted()
  {
    Notify_OnEnemyTargeted();

    if ( m_Active && !m_AttackState)
    {
      // enemy on radar. attack it
      m_AttackState = true;

      SetFireStyle_Enemy( GetTargetedEnemy());
      SetOrder_Attack(
        GetTargetedEnemy(),
        200.0,            // #TMP:#TODO
        300.0,            // #TMP:#TODO
        GetTripSpeed());  // #TMP:#TODO

      Notify_BeginAttack();
    };
  }

  void OnNoEnemy()
  {
    if ( m_Active && m_AttackState)
    {
      // no more enemy on radar. continue patrolling
      m_AttackState = false;

      if ( HasMoreTripPoints())
      {
        // order to move to current trip point
        SetFireStyle_Nearest();
        SetOrder_MoveTo(
          GetNowTripPoint(),
          GetTripSpeed());
      };

      Nofify_EndAttack();
    };
  };

  // #TMP: special functions

  void Notify_Init() {};
  void Notify_BeginAttack() {};
  void Notify_OnEnemyTargeted() {};
  void Nofify_EndAttack() {};


  //
  // *** 'private' data and operations
  //


  int      m_TripPointIndex = 0;
  boolean  m_AttackState    = false;
  boolean  m_Active         = true;
}

