//-------------------------------------------------------------------
//
//  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.
//
//-------------------------------------------------------------------

class CBreakRingAndConvoyMission extends
  CBaseMission, CBreakRingAndConvoyMissionObjectList, CBreakRingAndConvoyMission_Strings, CNavPointUser
{
  // *** mission constants

  final int CONVOY_UNIT_NUM      = 12; // number of units in soviet blocked convoy
  final int CONVOY_KILLED_FAILED = 12; // number of convoy unit to be killed for mission failed

  final array CONVOYGROUP_CLASSES   = array( "CSovietTank", "CSovietTank", "CSovietTank");
  final array CONVOYGROUP_AISCRIPTS = array( "CMission7_SovietAttack", "CMission7_SovietAttack", "CMission7_SovietAttack");
  final array CONVOYGROUP_NUM       = array( 4, 4, 4);


  // *** mission creation

  int GetAutoGeneratedUnitsQty()
  {
    return
      CONVOY_UNIT_NUM            // additional units generated automatically
    + 6                          // additional units generated automatically
    + 2 + 1 + 2 + 1 + 2 + 1 + 2  // additional units generated automatically
    + 3                          // additional units generated automatically
    + 6;                         // global components generated in constructor
  }

  void CBreakRingAndConvoyMission()
  {
    BaseMission_InitMission();

    BaseMission_UpdateLoadProgress();
    CreateComponent("DebugCamera", "GameObject", "CDebugCamera");
    SetComponentPosition("DebugCamera",
      matrix(
        1.0, 0.0, 0.0, 8500.0,
        0.0, 1.0, 0.0, 10300.0,
        0.0, 0.0, 1.0,  600.0,
        0.0, 0.0, 0.0,    1.0
      ));

    // CreateComponent(IDToRegister, ComponentID, ScriptName | FileName | "")
    BaseMission_UpdateLoadProgress();
    CreateComponent("Atmosphere", "Atmosphere", "CBreakRingAndConvoyMission_Atmosphere");

    BaseMission_UpdateLoadProgress();
    CreateComponent("Sky", "SkyObject", "CBreakRingAndConvoyMission_Sky");

    BaseMission_UpdateLoadProgress();
    CreateComponent("Terrain", "ProgressiveTerrainObject", "CBreakRingAndConvoyMission_Terrain");

    BaseMission_UpdateLoadProgress();
    CreateComponent("Forest", "Forest", "CBreakRingAndConvoyMission_Forest");

    BaseMission_UpdateLoadProgress();
    CreateComponent("AIController", "AIController", "CMission7_AIController");

    BaseMission_CreateObjects();


    // --- create Soviet army

    /*
    CreateUnitLine(
      "SovietTank_",
      "CSovietTank",
      "CMission7_SovietAttack",
      CONVOY_UNIT_NUM,
      9131.0, 10326.0,
      9834.0, 10330.0);
    */

    CreateUnitLineGroup(
      "SovietConvoy_",
      CONVOYGROUP_CLASSES,
      CONVOYGROUP_AISCRIPTS,
      CONVOYGROUP_NUM,
      CONVOY_UNIT_NUM,
      9131.0, 10326.0,
      9834.0, 10330.0);


    // --- create Nazi army

    // group A
    CreateUnitLine(
      "NaziTank_A_",
      "CGermanTank",
      "CMission7_NaziAttack",
      6,//10,
      GetNavPoint("NavPoint_Encirclement_A"),
      GetNavPoint("NavPoint_Encirclement_B"));

    // group B
    CreateUnitLine(
      "NaziTank_B_",
      "CGermanTank",
      "CMission7_NaziAttack",
      2,//3,
      GetNavPoint("NavPoint_Encirclement_B"),
      GetNavPoint("NavPoint_Encirclement_C"));

    // group C
    CreateUnitLine(
      "NaziTank_C_",
      "CGermanTank",
      "CMission7_NaziAttack",
      1,//3,
      GetNavPoint("NavPoint_Encirclement_C"),
      GetNavPoint("NavPoint_Encirclement_D"));

    // group D
    CreateUnitLine(
      "NaziTank_D_",
      "CGermanTank",
      "CMission7_NaziAttack",
      2,//3,
      GetNavPoint("NavPoint_Encirclement_D"),
      GetNavPoint("NavPoint_Encirclement_E"));

    // group E
    CreateUnitLine(
      "NaziTank_E_",
      "CGermanTank",
      "CMission7_NaziAttack",
      1,//3,
      GetNavPoint("NavPoint_Encirclement_E"),
      GetNavPoint("NavPoint_Encirclement_F"));

    // group F
    CreateUnitLine(
      "NaziTank_F_",
      "CGermanTank",
      "CMission7_NaziAttack",
      2,//3,
      GetNavPoint("NavPoint_Encirclement_F"),
      GetNavPoint("NavPoint_Encirclement_G"));

    // group G
    CreateUnitLine(
      "NaziTank_G_",
      "CGermanTank",
      "CMission7_NaziAttack",
      1,//3,
      GetNavPoint("NavPoint_Encirclement_G"),
      GetNavPoint("NavPoint_Encirclement_H"));

    // group H
    CreateUnitLine(
      "NaziTank_H_",
      "CGermanTank",
      "CMission7_NaziAttack",
      2,//6,
      GetNavPoint("NavPoint_Encirclement_H"),
      GetNavPoint("NavPoint_Encirclement_I"));

    // group I
    CreateUnitLine(
      "NaziTank_I_",
      "CGermanTank",
      "CMission7_NaziAttack",
      2,//3,
      GetNavPoint("NavPoint_Encirclement_I"),
      GetNavPoint("NavPoint_Encirclement_A"));
  }


  // *** routine functions

  void CreateUnitLine(
    string  _NamePrefix,
    string  _ObjectScript,
    string  _AIScript,
    int     _ObjectNum,
    float   _LineStartX,
    float   _LineStartY,
    float   _LineEndX,
    float   _LineEndY)
  {
    for ( int u = 0; u < _ObjectNum; u = u + 1)
    {
      float x = _LineStartX + (_LineEndX - _LineStartX) * u / _ObjectNum;
      float y = _LineStartY + (_LineEndY - _LineStartY) * u / _ObjectNum;

      BaseMission_UpdateLoadProgress();
      CreateComponent( _NamePrefix + u, "GameObject", _ObjectScript);

      SetComponentPosition(
        _NamePrefix + u,
        matrix(
          1.0, 0.0, 0.0, x,
          0.0, 1.0, 0.0, y,
          0.0, 0.0, 1.0, 0.0,
          0.0, 0.0, 0.0, 1.0));

      SetBehaviorTask( _NamePrefix + u, _AIScript);
    }
  }


  void CreateUnitLineGroup(
    string  _NamePrefix,
    array   _GroupObjectScript,
    array   _GroupAIScript,
    array   _GroupObjectNum,
    int     _ObjectNum,
    float   _LineStartX,
    float   _LineStartY,
    float   _LineEndX,
    float   _LineEndY)
  {
    int GroupIndex = 0;
    int InGroupIndex = 0;

    for ( int u = 0; u < _ObjectNum; u = u + 1)
    {
      float x = _LineStartX + (_LineEndX - _LineStartX) * u / _ObjectNum;
      float y = _LineStartY + (_LineEndY - _LineStartY) * u / _ObjectNum;

      BaseMission_UpdateLoadProgress();
      CreateComponent( _NamePrefix + u, "GameObject", _GroupObjectScript[GroupIndex]);

      SetComponentPosition(
        _NamePrefix + u,
        matrix(
          1.0, 0.0, 0.0, x,
          0.0, 1.0, 0.0, y,
          0.0, 0.0, 1.0, 0.0,
          0.0, 0.0, 0.0, 1.0));

      SetBehaviorTask( _NamePrefix + u, _GroupAIScript[GroupIndex]);

      InGroupIndex = InGroupIndex + 1;
      if ( InGroupIndex >= int(_GroupObjectNum[GroupIndex]))
      {
        GroupIndex = GroupIndex + 1;
        InGroupIndex = 0;
      };
    }
  }

  array m_MissionObjectivesStatuses =
          array(
            str_ObjectiveInProgress,
            str_ObjectiveInProgress
          );

  array m_BonusMissionObjectivesStatuses =
          array(
          );

  //
  //  Mission statistics

  string GetMissionStatistics()
  {
    return str_StatisticsTitle + NaziKilled;
  }

  //
  //  Mission navpoints

  array GetNavPoints()
  {
    array navpoints =
      array(
        GetNavPoint("NavPoint_Encirclement"),
        GetNavPoint("NavPoint_Pagubino")
//        vector(8600, 8170, 589),
//        vector(12200, 4706, 428.0)
      );
    return navpoints;
  }

  //
  //  Mission map skin file

  string GetMapSkinFileName()
  {
    return "Missions/Mission_7/Map.skin";
  }


  //
  //  Objective constants and variables
  //

  final int  KILL_GROUP_A_TO_BREACH = 5; // number of nazi units in group A that should be killed to start soviet breach
  final int  KILL_GROUP_O_TO_COMPLETE = 7; // number of nazi units in group O that should be killed to complete mission

  int  m_NaziGroup_A_Killed = 0;
  int  m_NaziGroup_O_Killed = 0;

  //
  //  Object destroyed event handler
  //

  //#TMP:
  int NaziKilled = 0;
  int SovietKilled = 0;
  boolean GroupA_Broken = false;

  void OnGameObjectDestroyed(string _id)
  {
    BaseMission_OnGameObjectDestroyed(_id);

    if ( (!GroupA_Broken) && Core_IsStringStartsWith(_id, "NaziTank_A_"))
    {
      m_NaziGroup_A_Killed = m_NaziGroup_A_Killed + 1;

      string message = str_BlockingTankDestrMsg_1 +
                       m_NaziGroup_A_Killed +
                       str_BlockingTankDestrMsg_2;

      Core_BroadcastEvent(
        "OnDisplayMessage",
        message,
        m_GoodNewsColor
      );

      if ( m_NaziGroup_A_Killed >= KILL_GROUP_A_TO_BREACH)
      {
        BaseMission_CompleteObjective(0);
        Core_BroadcastEvent( "OnGroupABroken");
        GroupA_Broken = true;
        Core_SendEventTo(
            "Helicopter",
            "ShowEventPoint",
            vector(9278.0, 10326.0, 370.0), //        - point to show
            80.0                           //        - distance from camera to point
        );
      }
    }

    if (Core_IsStringStartsWith(_id, "Nazi"))
    {
      NaziKilled = NaziKilled + 1;
    }

    if ( Core_IsStringStartsWith(_id, "Nazi_Ambush_O"))
    {
      m_NaziGroup_O_Killed = m_NaziGroup_O_Killed + 1;

      if ( m_NaziGroup_O_Killed >= KILL_GROUP_O_TO_COMPLETE)
      {
        BaseMission_CompleteObjective(1);
        Core_BroadcastEvent("OnConvoyContinue");
      }
    }

    if (Core_IsStringStartsWith(_id, "SovietConvoy_"))
    {
      SovietKilled = SovietKilled + 1;

      string message = str_ConvoyDestroyedMsg_1 +
                       (CONVOY_UNIT_NUM - SovietKilled) +
                       str_ConvoyDestroyedMsg_2;

      Core_BroadcastEvent(
        "OnDisplayMessage",
        message,
        m_BadNewsColor
      );
     Core_SendEventTo(
        "Helicopter",
        "ShowEventObject",
        _id,                       //     - id of object to show
        80.0                      //     - distance from camera to object
        );

      if ( SovietKilled >= CONVOY_KILLED_FAILED)
      {
        Core_BroadcastEvent(
          "OnDisplayMessage",
          str_MissionFailedMsg,
          m_BadNewsColor
        );

        BaseMission_DelayedQuit();
      }
    }
  }

  void OnMissionLoaded()
  {
    Core_SendEventTo("Helicopter", "OnInitiallyEnableTargetScreen", false);

    // Start mission music playing
    Core_SendEventTo(SOID_MusicController, "PlayMissionMusic", 7);
  }
}
