unit DatLinks;
interface
uses TypeDefs, DataAccess;

type
  THandler = function(Connection: TDataAccess; FileID: Integer): TDatLinkList;
  TDatLinkHandler = record
    Ext:     String[4];
    Handler: THandler;
  end;
  TDatLinkHandlers = array of TDatLinkHandler;

  TDatLinks = class
    private
      FDatLinkHandlers: TDatLinkHandlers;
    public
      property RawListHandlers: TDatLinkHandlers read FDatLinkHandlers;
      procedure InsertDatLinkHandler(ext: String; handler: THandler);
      function GetDatLinks(ConnectionID, FileID: Integer): TDatLinkList;
      function GetDatLink(ConnectionID, FileID, DatOffset: Integer): TDatLink;
  end;


var
  DatLinksManager: TDatLinks;


implementation
uses
  ConnectionManager, Classes, SysUtils;



function AISA(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1E, 2, @packages);
  SetLength(Result, packages * 2);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i*2 + 0].SrcOffset := $20 + i * 352 + $28;
      Result[i*2 + 0].DestID := -1;
      Result[i*2 + 0].PosDestExts := 'ONCC';

      Result[i*2 + 1].SrcOffset := $20 + i * 352 + $150;
      Result[i*2 + 1].DestID := -1;
      Result[i*2 + 1].PosDestExts := 'ONWC';
    end;
  end;
end;


function AKEV(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..16] of String[4] =
      ('PNTA', 'PLEA', 'TXCA', 'AGQG', 'AGQR', 'AGQC', 'AGDB', 'TXMA', 'AKVA',
      'AKBA', 'IDXA', 'IDXA', 'AKBP', 'ABNA', 'AKOT', 'AKAA', 'AKDA');
var
  i: Integer;
begin
  SetLength(Result, 17);
  for i := 0 to 16 do
  begin
    Result[i].SrcOffset := $8 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function AKOT(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..4] of String[4] =
      ('OTIT', 'OTLF', 'QTNA', 'IDXA', 'IDXA');
var
  i: Integer;
begin
  SetLength(Result, 5);
  for i := 0 to 4 do
  begin
    Result[i].SrcOffset := $8 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function CBPI(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  i: Integer;
begin
  SetLength(Result, 57);
  for i := 0 to 56 do
  begin
    Result[i].SrcOffset := $8 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := 'Impt';
  end;
end;


function CBPM(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  i: Integer;
begin
  SetLength(Result, 19);
  for i := 0 to 18 do
  begin
    Result[i].SrcOffset := $8 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := 'Mtrl';
  end;
end;


function CONS(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..1] of String[4] =
      ('OFGA', 'M3GM');
var
  i: Integer;
begin
  SetLength(Result, 2);
  for i := 0 to 1 do
  begin
    Result[i].SrcOffset := $24 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function CRSA(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*1100 + $A0;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'ONCC';
    end;
  end;
end;


function DOOR(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..2] of String[4] =
      ('OFGA', 'OFGA', 'OBAN');
var
  i: Integer;
begin
  SetLength(Result, 3);
  for i := 0 to 2 do
  begin
    Result[i].SrcOffset := $8 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function DPge(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..0] of String[4] =
      ('IGPG');
var
  i: Integer;
begin
  SetLength(Result, 1);
  for i := 0 to 0 do
  begin
    Result[i].SrcOffset := $40 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function FILM(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..1] of String[4] =
      ('TRAM', 'TRAM');
var
  i: Integer;
begin
  SetLength(Result, 2);
  for i := 0 to 1 do
  begin
    Result[i].SrcOffset := $28 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function FXLR(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..1] of String[4] =
      ('TXMP', 'M3GM');
var
  i: Integer;
begin
  SetLength(Result, 2);
  for i := 0 to 1 do
  begin
    Result[i].SrcOffset := $0C + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function GMAN(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'M3GM';
    end;
  end;
end;


function HPge(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..0] of String[4] =
      ('IGPG');
var
  i: Integer;
begin
  SetLength(Result, 1);
  for i := 0 to 0 do
  begin
    Result[i].SrcOffset := $0C + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function IGHH(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..1] of String[4] =
      ('TXMP', 'TXMP');
var
  i: Integer;
begin
  SetLength(Result, 2);
  for i := 0 to 1 do
  begin
    Result[i].SrcOffset := $24 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function IGPA(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'IGPG';
    end;
  end;
end;


function IGPG(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..3] of String[4] =
      ('TSFF', '*', 'IGSA', 'IGSA');
var
  i: Integer;
begin
  SetLength(Result, 4);
  Result[0].SrcOffset := $8;
  Result[0].DestID := -1;
  Result[0].PosDestExts := types[0];

  for i := 1 to 3 do
  begin
    Result[i].SrcOffset := $14 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function IGSA(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'IGSt';
    end;
  end;
end;


function IGSt(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..0] of String[4] =
      ('TSFF');
var
  i: Integer;
begin
  SetLength(Result, 1);
  for i := 0 to 0 do
  begin
    Result[i].SrcOffset := $8 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function Impt(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..0] of String[4] =
      ('Impt');
var
  i: Integer;
begin
  SetLength(Result, 1);
  for i := 0 to 0 do
  begin
    Result[i].SrcOffset := $10 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function IPge(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..0] of String[4] =
      ('IGPG');
var
  i: Integer;
begin
  SetLength(Result, 1);
  for i := 0 to 0 do
  begin
    Result[i].SrcOffset := $0C + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function KeyI(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  i: Integer;
begin
  SetLength(Result, 10);
  for i := 0 to 9 do
  begin
    Result[i].SrcOffset := $08 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := 'TXMP';
  end;
end;


function M3GA(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'M3GM';
    end;
  end;
end;


function M3GM(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..6] of String[4] =
      ('PNTA', 'VCRA', 'VCRA', 'TXCA', 'IDXA', 'IDXA', 'TXMP');
var
  i: Integer;
begin
  SetLength(Result, 8);
  for i := 0 to 6 do
  begin
    Result[i].SrcOffset := $0C + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function Mtrl(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..0] of String[4] =
      ('Mtrl');
var
  i: Integer;
begin
  SetLength(Result, 1);
  for i := 0 to 0 do
  begin
    Result[i].SrcOffset := $10 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function OBDC(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1E, 2, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*$18 + 4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'OBAN';
    end;
  end;
end;


function OBOA(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1E, 2, @packages);
  SetLength(Result, packages * 3);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i*3 + 0].SrcOffset := $20 + i*240 + 0;
      Result[i*3 + 0].DestID := -1;
      Result[i*3 + 0].PosDestExts := 'M3GA';

      Result[i*3 + 1].SrcOffset := $20 + i*240 + 4;
      Result[i*3 + 1].DestID := -1;
      Result[i*3 + 1].PosDestExts := 'OBAN';

      Result[i*3 + 2].SrcOffset := $20 + i*240 + 8;
      Result[i*3 + 2].DestID := -1;
      Result[i*3 + 2].PosDestExts := 'ENVP';
    end;
  end;
end;


function OFGA(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages * 2 + 1);

  Result[0].SrcOffset := $18;
  Result[0].DestID := -1;
  Result[0].PosDestExts := 'ENVP';
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[1 + i*2 + 0].SrcOffset := $20 + i*12 + 4;
      Result[1 + i*2 + 0].DestID := -1;
      Result[1 + i*2 + 0].PosDestExts := 'M3GM';

      Result[1 + i*2 + 1].SrcOffset := $20 + i*12 + 8;
      Result[1 + i*2 + 1].DestID := -1;
      Result[1 + i*2 + 1].PosDestExts := 'OBLS';
    end;
  end;
end;


function ONCC(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  i: Integer;
begin
  SetLength(Result, 10);
  i := 0;
  Result[i].SrcOffset := $28;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'TXMP';
  Inc(i);
  Result[i].SrcOffset := $434;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'ONCV';
  Inc(i);
  Result[i].SrcOffset := $438;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'ONCP';
  Inc(i);
  Result[i].SrcOffset := $43C;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'ONIA';
  Inc(i);
  Result[i].SrcOffset := $C3C;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'TRBS';
  Inc(i);
  Result[i].SrcOffset := $C40;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'TRMA';
  Inc(i);
  Result[i].SrcOffset := $C44;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'CBPM';
  Inc(i);
  Result[i].SrcOffset := $C48;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'CBPI';
  Inc(i);
  Result[i].SrcOffset := $C88;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'TRAC';
  Inc(i);
  Result[i].SrcOffset := $C8C;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'TRSC';
end;


function ONCV(Connection: TDataAccess; FileID: Integer): TDatLinkList;
begin
  SetLength(Result, 1);
  Result[0].SrcOffset := $8;
  Result[0].DestID := -1;
  Result[0].PosDestExts := 'ONCV';
end;


function ONLV(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..12] of String[4] =
      ('AKEV', 'OBOA', 'ONMA', 'ONFA', 'ONTA', 'ONSK', 'AISA', 'AITR',
       'ONSA', 'OBDC', 'ONOA', 'ENVP', 'CRSA');
var
  i: Integer;
begin
  SetLength(Result, 13);
  for i := 0 to 5 do
  begin
    Result[i].SrcOffset := $48 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
  for i := 0 to 5 do
  begin
    Result[i+6].SrcOffset := $64 + i*4;
    Result[i+6].DestID := -1;
    Result[i+6].PosDestExts := types[i+6];
  end;
  Result[12].SrcOffset := $300;
  Result[12].DestID := -1;
  Result[12].PosDestExts := types[12];
end;


function ONOA(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*8 + 4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'IDXA';
    end;
  end;
end;


function ONSK(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  i: Integer;
begin
  SetLength(Result, 20);
  for i := 0 to 19 do
  begin
    Result[i].SrcOffset := $08 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := 'TXMP';
  end;
end;


function ONVL(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'ONCV';
    end;
  end;
end;


function ONWC(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  i: Integer;
begin
  SetLength(Result, 9);
  i := 0;
  Result[i].SrcOffset := $28;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'TXMP';
  Inc(i);
  Result[i].SrcOffset := $34;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'TXMP';
  Inc(i);
  Result[i].SrcOffset := $40;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'TXMP';
  Inc(i);
  Result[i].SrcOffset := $54;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'TXMP';
  Inc(i);
  Result[i].SrcOffset := $58;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'TXMP';
  Inc(i);
  Result[i].SrcOffset := $5C;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'TXMP';
  Inc(i);
  Result[i].SrcOffset := $60;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'M3GM';
  Inc(i);
  Result[i].SrcOffset := $6FC;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'TXMP';
  Inc(i);
  Result[i].SrcOffset := $700;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'TXMP';
end;


function OPge(Connection: TDataAccess; FileID: Integer): TDatLinkList;
begin
  SetLength(Result, 1);
  Result[0].SrcOffset := $0C;
  Result[0].DestID := -1;
  Result[0].PosDestExts := 'IGPA';
end;


function PSpc(Connection: TDataAccess; FileID: Integer): TDatLinkList;
begin
  SetLength(Result, 1);
  Result[0].SrcOffset := $50;
  Result[0].DestID := -1;
  Result[0].PosDestExts := 'TXMP';
end;


function PSpL(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*8 + 4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'PSpc';
    end;
  end;
end;


function PSUI(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  i: Integer;
begin
  SetLength(Result, 44);
  for i := 0 to 43 do
  begin
    Result[i].SrcOffset := $08 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := 'PSpc';
  end;
end;


function StNA(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1E, 2, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'TStr';
    end;
  end;
end;


function TMRA(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := '*';
    end;
  end;
end;


function TRAC(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1E, 2, @packages);
  SetLength(Result, packages + 1);
  Result[0].SrcOffset := $18;
  Result[0].DestID := -1;
  Result[0].PosDestExts := 'TRAC';
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i+1].SrcOffset := $20 + i*12 + 8;
      Result[i+1].DestID := -1;
      Result[i+1].PosDestExts := 'TRAM';
    end;
  end;
end;


function TRAM(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  i: Integer;
begin
  SetLength(Result, 2);
  for i := 0 to 1 do
  begin
    Result[i].SrcOffset := $40 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := 'TRAM';
  end;
end;


function TRAS(Connection: TDataAccess; FileID: Integer): TDatLinkList;
begin
  SetLength(Result, 1);
  Result[0].SrcOffset := $08;
  Result[0].DestID := -1;
  Result[0].PosDestExts := 'TRAM';
end;


function TRBS(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  i: Integer;
begin
  SetLength(Result, 5);
  for i := 0 to 4 do
  begin
    Result[i].SrcOffset := $08 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := 'TRCM';
  end;
end;


function TRCM(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..2] of String[4] =
      ('TRGA', 'TRTA', 'TRIA');
var
  i: Integer;
begin
  SetLength(Result, 3);
  for i := 0 to 2 do
  begin
    Result[i].SrcOffset := $5C + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
end;


function TRGA(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1E, 2, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'M3GM';
    end;
  end;
end;


function TRGE(Connection: TDataAccess; FileID: Integer): TDatLinkList;
begin
  SetLength(Result, 1);
  Result[0].SrcOffset := $20;
  Result[0].DestID := -1;
  Result[0].PosDestExts := 'M3GM';
end;


function TRIG(Connection: TDataAccess; FileID: Integer): TDatLinkList;
const
  types: array[0..3] of String[4] =
      ('M3GM', 'OBLS', 'TRGE', 'OBAN');
var
  i: Integer;
begin
  SetLength(Result, 4);
  for i := 0 to 1 do
  begin
    Result[i].SrcOffset := $18 + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := types[i];
  end;
  for i := 0 to 1 do
  begin
    Result[i+2].SrcOffset := $24 + i*4;
    Result[i+2].DestID := -1;
    Result[i+2].PosDestExts := types[i+2];
  end;
end;


function TRMA(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1E, 2, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'TXMP';
    end;
  end;
end;


function TRSC(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1E, 2, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'TRAS';
    end;
  end;
end;


function TSFF(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages + 1);

  Result[0].SrcOffset := $18;
  Result[0].DestID := -1;
  Result[0].PosDestExts := 'TSFL';
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i+1].SrcOffset := $20 + i*4;
      Result[i+1].DestID := -1;
      Result[i+1].PosDestExts := 'TSFT';
    end;
  end;
end;


function TSFT(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  i: Integer;
begin
  SetLength(Result, 256);
  for i := 0 to 255 do
  begin
    Result[i].SrcOffset := $1C + i*4;
    Result[i].DestID := -1;
    Result[i].PosDestExts := 'TSGA';
  end;
end;


function TURR(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  i: Integer;
begin
  SetLength(Result, 4);
  i := 0;
  Result[i].SrcOffset := $60;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'M3GM';
  Inc(i);
  Result[i].SrcOffset := $64;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'OBLS';
  Inc(i);
  Result[i].SrcOffset := $6C;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'M3GM';
  Inc(i);
  Result[i].SrcOffset := $74;
  Result[i].DestID := -1;
  Result[i].PosDestExts := 'M3GM';
end;


function TXAN(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'TXMP';
    end;
  end;
end;


function TXMA(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'TXMP';
    end;
  end;
end;


function TXMB(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'TXMP';
    end;
  end;
end;


function TXMP(Connection: TDataAccess; FileID: Integer): TDatLinkList;
begin
  SetLength(Result, 2);
  Result[0].SrcOffset := $94;
  Result[0].DestID := -1;
  Result[0].PosDestExts := 'TXAN';
  Result[1].SrcOffset := $98;
  Result[1].DestID := -1;
  Result[1].PosDestExts := 'TXMP';
end;


function TxtC(Connection: TDataAccess; FileID: Integer): TDatLinkList;
begin
  SetLength(Result, 1);
  Result[0].SrcOffset := $08;
  Result[0].DestID := -1;
  Result[0].PosDestExts := 'IGPA';
end;


function WMCL(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*8 + 4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'PSpc';
    end;
  end;
end;


function WMDD(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $11C, 4, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $120 + i*292 + $114;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'TSFF';
    end;
  end;
end;


function WMMB(Connection: TDataAccess; FileID: Integer): TDatLinkList;
var
  packages: Integer;
  i: Integer;
begin
  packages := 0;
  Connection.LoadDatFilePart(fileid, $1C, 4, @packages);
  SetLength(Result, packages);
  if packages > 0 then
  begin
    for i := 0 to packages - 1 do
    begin
      Result[i].SrcOffset := $20 + i*4;
      Result[i].DestID := -1;
      Result[i].PosDestExts := 'WMM_';
    end;
  end;
end;


function WPge(Connection: TDataAccess; FileID: Integer): TDatLinkList;
begin
  SetLength(Result, 2);
  Result[0].SrcOffset := $08;
  Result[0].DestID := -1;
  Result[0].PosDestExts := 'ONWC';
  Result[1].SrcOffset := $0C;
  Result[1].DestID := -1;
  Result[1].PosDestExts := 'IGPG';
end;







function TDatLinks.GetDatLink(ConnectionID, FileID, DatOffset: Integer): TDatLink;
var
  i: Integer;
  DatLinks: TDatLinkList;
begin
  DatLinks           := GetDatLinks(ConnectionID, FileID);
  Result.SrcOffset   := -1;
  Result.DestID      := -1;
  Result.PosDestExts := '';
  if Length(DatLinks) > 0 then
  begin
    for i := 0 to High(DatLinks) do
    begin
      if DatLinks[i].SrcOffset = DatOffset then
      begin
        Result.SrcOffset := DatOffset;
        Result.DestID := DatLinks[i].DestID;
        Result.PosDestExts := DatLinks[i].PosDestExts;
        Break;
      end;
    end;
  end;
end;


function TDatLinks.GetDatLinks(ConnectionID, FileID: Integer): TDatLinkList;
var
  i: Integer;
  fileinfo: TFileInfo;
begin
  SetLength(Result, 0);
  fileinfo := ConManager.Connection[ConnectionID].GetFileInfo(FileID);
  for i := 0 to High(FDatLinkHandlers) do
    if UpperCase(FDatLinkHandlers[i].Ext) = UpperCase(fileinfo.extension) then
    begin
      Result := FDatLinkHandlers[i].Handler(ConManager.Connection[ConnectionID], FileID);
      Break;
    end;
end;

procedure TDatLinks.InsertDatLinkHandler(ext: String; handler: THandler);
begin
  SetLength(FDatLinkHandlers, Length(FDatLinkHandlers) + 1);
  FDatLinkHandlers[High(FDatLinkHandlers)].Ext := ext;
  FDatLinkHandlers[High(FDatLinkHandlers)].handler := handler;
end;




initialization
  DatLinksManager := TDatLinks.Create;
  DatLinksManager.InsertDatLinkHandler('AISA', AISA);
  DatLinksManager.InsertDatLinkHandler('AKEV', AKEV);
  DatLinksManager.InsertDatLinkHandler('AKOT', AKOT);
  DatLinksManager.InsertDatLinkHandler('CBPI', CBPI);
  DatLinksManager.InsertDatLinkHandler('CBPM', CBPM);
  DatLinksManager.InsertDatLinkHandler('CONS', CONS);
  DatLinksManager.InsertDatLinkHandler('CRSA', CRSA);
  DatLinksManager.InsertDatLinkHandler('DOOR', DOOR);
  DatLinksManager.InsertDatLinkHandler('DPge', DPge);
  DatLinksManager.InsertDatLinkHandler('FILM', FILM);
  DatLinksManager.InsertDatLinkHandler('FXLR', FXLR);
  DatLinksManager.InsertDatLinkHandler('GMAN', GMAN);
  DatLinksManager.InsertDatLinkHandler('HPge', HPge);
  DatLinksManager.InsertDatLinkHandler('IGHH', IGHH);
  DatLinksManager.InsertDatLinkHandler('IGPA', IGPA);
  DatLinksManager.InsertDatLinkHandler('IGPG', IGPG);
  DatLinksManager.InsertDatLinkHandler('IGSA', IGSA);
  DatLinksManager.InsertDatLinkHandler('IGSt', IGSt);
  DatLinksManager.InsertDatLinkHandler('Impt', Impt);
  DatLinksManager.InsertDatLinkHandler('IPge', IPge);
  DatLinksManager.InsertDatLinkHandler('KeyI', KeyI);
  DatLinksManager.InsertDatLinkHandler('M3GA', M3GA);
  DatLinksManager.InsertDatLinkHandler('M3GM', M3GM);
  DatLinksManager.InsertDatLinkHandler('Mtrl', Mtrl);
  DatLinksManager.InsertDatLinkHandler('OBDC', OBDC);
  DatLinksManager.InsertDatLinkHandler('OBOA', OBOA);
  DatLinksManager.InsertDatLinkHandler('OFGA', OFGA);
  DatLinksManager.InsertDatLinkHandler('ONCC', ONCC);
  DatLinksManager.InsertDatLinkHandler('ONCV', ONCV);
  DatLinksManager.InsertDatLinkHandler('ONLV', ONLV);
  DatLinksManager.InsertDatLinkHandler('ONOA', ONOA);
  DatLinksManager.InsertDatLinkHandler('ONSK', ONSK);
  DatLinksManager.InsertDatLinkHandler('ONVL', ONVL);
  DatLinksManager.InsertDatLinkHandler('ONWC', ONWC);
  DatLinksManager.InsertDatLinkHandler('OPge', OPge);
  DatLinksManager.InsertDatLinkHandler('PSpc', PSpc);
  DatLinksManager.InsertDatLinkHandler('PSpL', PSpL);
  DatLinksManager.InsertDatLinkHandler('PSUI', PSUI);
  DatLinksManager.InsertDatLinkHandler('StNA', StNA);
  DatLinksManager.InsertDatLinkHandler('TMRA', TMRA);
  DatLinksManager.InsertDatLinkHandler('TRAC', TRAC);
  DatLinksManager.InsertDatLinkHandler('TRAM', TRAM);
  DatLinksManager.InsertDatLinkHandler('TRAS', TRAS);
  DatLinksManager.InsertDatLinkHandler('TRBS', TRBS);
  DatLinksManager.InsertDatLinkHandler('TRCM', TRCM);
  DatLinksManager.InsertDatLinkHandler('TRGA', TRGA);
  DatLinksManager.InsertDatLinkHandler('TRGE', TRGE);
  DatLinksManager.InsertDatLinkHandler('TRIG', TRIG);
  DatLinksManager.InsertDatLinkHandler('TRMA', TRMA);
  DatLinksManager.InsertDatLinkHandler('TRSC', TRSC);
  DatLinksManager.InsertDatLinkHandler('TSFF', TSFF);
  DatLinksManager.InsertDatLinkHandler('TSFT', TSFT);
  DatLinksManager.InsertDatLinkHandler('TURR', TURR);
  DatLinksManager.InsertDatLinkHandler('TXAN', TXAN);
  DatLinksManager.InsertDatLinkHandler('TXMA', TXMA);
  DatLinksManager.InsertDatLinkHandler('TXMB', TXMB);
  DatLinksManager.InsertDatLinkHandler('TXMP', TXMP);
  DatLinksManager.InsertDatLinkHandler('TxtC', TxtC);
  DatLinksManager.InsertDatLinkHandler('WMCL', WMCL);
  DatLinksManager.InsertDatLinkHandler('WMDD', WMDD);
  DatLinksManager.InsertDatLinkHandler('WMMB', WMMB);
  DatLinksManager.InsertDatLinkHandler('WPge', WPge);
end.