unit uHCEventHelpers;

// ALE 20130816 Various utility functions for manipulating Harpoon Events
{$IFDEF FPC}
{$mode objfpc}{$H+}
{$ENDIF}

interface

uses
  Classes, SysUtils,
  uHCTypeDefs, uHCDefines, uHCUtils, {$IFDEF FPC}fpjson{$ENDIF}{$IFDEF DCC}System.JSON{$ENDIF};

function HCEventType2String(EventType: ulong): String;
function HCEventTimeType2String(TimeType: ulong): String;
function HCEventToJSON(pGameTime: Long; pEvent: PHCHarpoonEvent): String;
function HCFindAirPatrolEvent(pHarpEventHead: PHCHarpoonEvent; pUnit: PHCUnit): PHCAirPatrolEvent;

implementation


function HCEventType2String(EventType: ulong): String;
begin
  case EventType of
     ATTACK_EVENT:    result := 'ATTACK_EVENT';
     ALT_SPEED_EVENT: result := 'ALT_SPEED_EVENT';
     READY_EVENT:     result := 'READY_EVENT';
     LAUNCH_EVENT:    result := 'LAUNCH_EVENT';
     SPLIT_EVENT:     result := 'SPLIT_EVENT';
     JOIN_EVENT:      result := 'JOIN_EVENT';
     SENSOR_EVENT:    result := 'SENSOR_EVENT';
     FORMATION_EVENT: result := 'FORMATION_EVENT';
     REPAIR_EVENT:    result := 'REPAIR_EVENT';
     RELOAD_EVENT:    result := 'RELOAD_EVENT';
     SINK_EVENT:      result := 'SINK_EVENT';
     BREAKDOWN_EVENT: result := 'BREAKDOWN_EVENT';
     SPECIAL_FORCES_EVENT:     result := 'SPECIAL_FORCES_EVENT';
     INTELLIGENCE_EVENT:     result := 'INTELLIGENCE_EVENT';
     MESSAGE_EVENT:     result := 'MESSAGE_EVENT';
     NUKE_FREE_EVENT:     result := 'NUKE_FREE_EVENT';
     FALSE_CONTACT_EVENT:     result := 'FALSE_CONTACT_EVENT';
     WEATHER_EVENT:     result := 'WEATHER_EVENT';
     SNORKEL_EVENT:     result := 'SNORKEL_EVENT';
     LANDING_EVENT:     result := 'LANDING_EVENT';
     ALT_PATH_EVENT:     result := 'ALT_PATH_EVENT';
     ENEMY_AI_EVENT:     result := 'ENEMY_AI_EVENT';
     DAMAGE_EVENT:     result := 'DAMAGE_EVENT';
     INTERMITTENT_EVENT:     result := 'INTERMITTENT_EVENT';
     AIR_ATTACK_EVENT:     result := 'AIR_ATTACK_EVENT';
     UNBEND_TAILS_EVENT:     result := 'UNBEND_TAILS_EVENT';
     UNUSED_EVENT:     result := 'UNUSED_EVENT';
     AIR_PATROL_EVENT:     result := 'AIR_PATROL_EVENT';
     INTERCEPT_EVENT:     result := 'INTERCEPT_EVENT';
     REPEAT_AIR_EVENT:     result := 'REPEAT_AIR_EVENT';
     ORDER_ATTACK_EVENT:     result := 'ORDER_ATTACK_EVENT';
     LAUNCHLAND_EVENT:     result := 'LAUNCHLAND_EVENT';
     VARIABLE_START_EVENT:     result := 'VARIABLE_START_EVENT';
     MISSILE_AVOID_EVENT:     result := 'MISSILE_AVOID_EVENT';
     ALT_COURSE_EVENT:     result := 'ALT_COURSE_EVENT';
     AIR_REFUEL_EVENT:     result := 'AIR_REFUEL_EVENT';
  else
    result := '';
  end;
end;

function HCEventTimeType2String(TimeType: ulong): String;
begin
  case TimeType of
    TimeNow: result := 'TimeNow';
    TimeDelta: result := 'TimeDelta';
    TimeAbs: result := 'TimeAbs';
  else
    result := '';
  end;
end;

function HCEventToJSON(pGameTime: Long; pEvent: PHCHarpoonEvent): String;
var
  lJSON: TJSONObject;
  lJSONStr: String;
  lGroupId: String;
begin
  lGroupId:='';
  if (pEvent^.ourGroup <> nil) then
  begin
    lGroupId:=PHCGroup(pEvent^.ourGroup)^.id;
  end;
  {$IFDEF FPC} // Lazarus/Free Pascal
  lJSON:=TJSONObject.Create(['uuid', pEvent^.uuid, 'GameTime', pGameTime, 'Group', lGroupId, 'Unit', pEvent^.unit_uuid,
   'Time', pEvent^.Time, 'Type', HCEventType2String(pEvent^.event_type),
   'TimeType', HCEventTimeType2String(pEvent^.time_type), 'PathEvent',
   pEvent^.in_scroll_flag]);

  lJSONStr:=lJSON.AsJSON;
  lJSON.Free;
  {$ENDIF}
  {$IFDEF DCC} // Delphi
  lJSON:=TJSONObject.Create();
  lJSON.AddPair('uuid', pEvent^.uuid);
  lJSON.AddPair('GameTime', TJSONNumber.Create(pGameTime));
  lJSON.AddPair('Group', lGroupId);
  lJSON.AddPair('Unit', (pEvent^.unit_uuid));
  lJSON.AddPair('Time', TJSONNumber.Create(pEvent^.Time));
  lJSON.AddPair('Type', HCEventType2String(pEvent^.event_type));
  lJSON.AddPair('TimeType', HCEventTimeType2String(pEvent^.time_type));
  lJSON.AddPair('PathEvent',
   TJSONNumber.Create(pEvent^.in_scroll_flag));

  lJSONStr:=lJSON.ToJSON;
  lJSON.Free;
  {$ENDIF}
  result:=lJSONStr;
end;

{*** Finds the first (if any) AIR_PATROL_EVENT associated to a unit and returns it ***}
function HCFindAirPatrolEvent(pHarpEventHead: PHCHarpoonEvent; pUnit: PHCUnit): PHCAirPatrolEvent;
var
  lE: PHCHarpoonEvent;
  lAPE: PHCAirPatrolEvent;
begin
  lAPE := nil;  // ALE 20220908 starting assumption is we don't find AIR_PATROL_EVENT for pUnit

  if (HCMTIsAir(pUnit^.utype)) then
  begin
    lE := pHarpEventHead;
    while lE <> nil do
    begin
      if (lE^.event_type = AIR_PATROL_EVENT) then
      begin
        if ((pUnit^.Group = lE^.ourGroup) AND (pUnit^.uuid = lE^.unit_uuid)) then
  	begin
          lAPE := PHCAirPatrolEvent(lE^.DataPtr);
          break;
        end;
      end;
      lE := PHCHarpoonEvent(lE^.next);
    end;
  end;
  result := lAPE;
end;

end.

