unit MainForm;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ComCtrls, ExtCtrls, uHCTypeDefs, uHCAnnexDefs, uHCAnnexHelpers, uActUnitReportGlobals;

type

  { TfrmMain }

  TfrmMain = class(TForm)
    Button1: TButton;
    lblAUMUUID: TLabel;
    lblAUMGroupId: TLabel;
    lblHEEventCount: TLabel;
    lblAUMHeading: TLabel;
    lblAUMAltitude: TLabel;
    lblAUMUnitId: TLabel;
    lblAUMName: TLabel;
    tshActUnitMain: TTabSheet;
    memDLLInit: TMemo;
    tshDLLInit: TTabSheet;
    PageControl1: TPageControl;
    tshHE: TTabSheet;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
    // ALE 20130812 Big bad pointers that hold most of the game data
    PStartGroup: PHCGroup;
    PHarpEventHead: PHCHarpoonEvent;
    PSonobuoyRegionHead: PHCSonobuoyRegion;
    PAllDeadUnitsPtr: PHCDeadListItem;
    PWeatherGroups: PHCGroup;
    PVictoryConditionsList: PHCVictoryConditions;
    // ALE 20130812 transient pointers
    PSelectedUnit: PHCUnit;
    // ALE 20130812 misc globals
    //blnInvestigatingStructs: Boolean;
    // ALE 20130908 pointers to functions exported by the GE
    HCdllCheckLatLonDepth: THCdllCheckLatLonDepth;
    HCannex_id_to_disk_id: THCannex_id_to_disk_id;

    procedure UpdateActUnitReport();
    procedure UpdateUnitReport(pPUnit: PHCUnit);
    procedure UpdateHarpoonEvents();
    function GetUnitClassName(AnnexId: ID): String;
  end;

var
  frmMain: TfrmMain;

implementation

uses uHCDefines;

{$R *.lfm}

{ TfrmMain }

procedure TfrmMain.Button1Click(Sender: TObject);
begin
  if ((PStartGroup <> nil) AND (PStartGroup^.Units <> nil)) then
  begin
    UpdateUnitReport(PStartGroup^.Units);
    ShowMessage('updated')
  end;
end;

procedure TfrmMain.UpdateActUnitReport;
begin
  UpdateUnitReport(PActUnit);
end;

procedure TfrmMain.UpdateUnitReport(pPUnit: PHCUnit);
var
  PHarpEvent: PHCHarpoonEvent;
  cEventCourse: NativeInt;
  cEventAltitude: NativeInt;
  sClassName: String;
begin
  if (pPUnit <> nil) then
  begin
    Byte(PDLLBusy^) := CTRUE; // ALE 20130816 don't process other events in GE

    if ((AnnexData <> nil) AND (pPUnit <> nil)) then
    begin
      if (PHarpEventHead <> nil) then
      begin
        // ALE 20160408 Count up course events
        // ALE 20160408 Count up altitude events
        cEventCourse := 0;
        cEventAltitude := 0;
        PHarpEvent := PHarpEventHead;
        while (PHarpEvent <> nil) do
        begin
          if (PHarpEvent^.event_type = ALT_COURSE_EVENT) then
          begin
            if (PHCGroup(PHarpEvent^.ourGroup)^.id = pPUnit^.Group^.id) then
              Inc(cEventCourse);
          end;
          if (PHarpEvent^.event_type = ALT_ALTITUDE_EVENT) then
          begin
            if (PHCGroup(PHarpEvent^.ourGroup)^.id = pPUnit^.Group^.id) then
               Inc(cEventAltitude);
          end;

          PHarpEvent := PHarpEvent^.next;
        end;
      end;
      sClassName:=GetUnitClassName(pPUnit^.Annex);
      lblAUMGroupId.Caption:='Group: ' + pPUnit^.Group^.id;
      lblAUMUnitId.Caption:='Unit: ' + IntToStr(pPUnit^.id);
      lblAUMName.Caption:='Name: ' + pPUnit^.name;
      if (sClassName <> '') then
        lblAUMName.Caption := lblAUMName.Caption + ' (' + sClassName + ')';
      lblAUMHeading.Caption:='Heading (deg): ' + IntToStr(pPUnit^.course)
       + ' (' + IntToStr(cEventCourse) + ' ALT_COURSE events)';
      lblAUMAltitude.Caption:='Altitude (m): '
       + Format('%0.0N', [pPUnit^.Altitude/1.0])
       + ' (' + IntToStr(cEventAltitude) + ' ALT_ALTITUDE events)';
      lblAUMUUID.Caption := 'UUID: ' + pPUnit^.UUID;

    end
    else
    begin
      lblAUMGroupId.Caption:='';
      lblAUMUnitId.Caption:='';
      lblAUMName.Caption:='';
      lblAUMHeading.Caption:='';
      lblAUMAltitude.Caption:='';
    end;

    Byte(PDLLBusy^) := CFALSE;
  end;
end;

procedure TfrmMain.UpdateHarpoonEvents;
var
  PHarpEvent: PHCHarpoonEvent;
  cEventCount: NativeInt;
begin
  Byte(PDLLBusy^) := CTRUE; // ALE 20130816 don't process other events in GE

  if (PHarpEventHead <> nil) then
  begin
    // ALE 20160412 Count up all events
      cEventCount := 0;
      PHarpEvent := PHarpEventHead;
      while (PHarpEvent <> nil) do
      begin
        Inc(cEventCount);

        PHarpEvent := PHarpEvent^.next;
      end;
    lblHEEventCount.Caption:='Total Harpoon Events: '
     + Format('%0.0N', [cEventCount/1.0]);
  end
  else
  begin
    lblHEEventCount.Caption:='';
  end;

  Byte(PDLLBusy^) := CFALSE;
end;

function TfrmMain.GetUnitClassName(AnnexId: ID): String;
var
  PHCAnnexA1: PHCAnnexA1_disk;
  PHCAnnexA2: PHCAnnexA2_disk;
  PHCAnnexB1: PHCAnnexB1_disk;
  PHCAnnexP1: PHCAnnexP1_disk;
begin
  case (HCAnnexHelper.HCAnnexShift(AnnexId)) of
    SHIP_FLAG:
    begin
      PHCAnnexA1 := HCAnnexHelper.HCGetAnnexA1(AnnexId);
      GetUnitClassName := PHCAnnexA1^.ClassName;
    end;
    SUB_FLAG:
    begin
      PHCAnnexA2 := HCAnnexHelper.HCGetAnnexA2(AnnexId);
      GetUnitClassName := PHCAnnexA2^.ClassName;
    end;
    PLANE_FLAG:
    begin
      PHCAnnexB1 := HCAnnexHelper.HCGetAnnexB1(AnnexId);
      GetUnitClassName := PHCAnnexB1^.ClassName;
    end;
    BASE_FLAG:
    begin
      PHCAnnexP1 := HCAnnexHelper.HCGetAnnexP1(AnnexId);
      GetUnitClassName := PHCAnnexP1^.Name;
    end;
    else
      GetUnitClassName := '';
  end;

end;

{ TfrmMain }


end.
