unit _MetaManager;
interface

uses _FileTypes, TXAN, TXMP, _EmptyFile;

type
  TFileType = class of TFile;
  TFileDesc = record
    ext: String;
    ftype: TFileType;
  end;

const
  FileDescs: array[0..1] of TFileDesc = (
    (ext: 'TXAN'; ftype: TFile_TXAN),
    (ext: 'TXMP'; ftype: TFile_TXMP)
  );

type
  TMetaManager = class
    protected
      FFiles: array of TFile;
      FConnectionID: Integer;
      function GetFileCount: Integer;
      function GetFileById(Id: Integer): TFile;
    private
      procedure InitRootFiles;
    public
      constructor Create(ConnectionID: Integer);
      procedure InitFile(id: Integer);
      procedure InitFileFields(id: Integer);

      property FileCount: Integer read GetFileCount;
      property FileById[Id: Integer]: TFile read GetFileById;
  end;

implementation

uses
  Classes, ConnectionManager, Access_OniArchive, TypeDefs, Dialogs, SysUtils, StrUtils;

{ TFileManager }

constructor TMetaManager.Create(ConnectionID: Integer);
begin
  FConnectionID := ConnectionID;
  InitRootFiles;
end;

function TMetaManager.GetFileById(Id: Integer): TFile;
begin
  Result := FFiles[Id];
end;

function TMetaManager.GetFileCount: Integer;
begin
  Result := Length(FFiles);
end;

procedure TMetaManager.InitFile(id: Integer);
var
  typei: Integer;
  finfo: TFileInfo;
begin
  if id < ConManager.Connection[FConnectionID].GetFileCount then
  begin
    if not Assigned(FFiles[id]) then
    begin
      finfo := ConManager.Connection[FConnectionID].GetFileInfo(id);
      if finfo.Size > 0 then
      begin
        for typei := 0 to High(FileDescs) do
        begin
          if FileDescs[typei].ext = finfo.Extension then
          begin
            FFiles[id] := TFileType(FileDescs[typei].ftype).Create(FConnectionID, id);
            Break;
          end;
        end;
        if typei > High(FileDescs) then
          FFiles[id] := TFile_Empty.Create(FConnectionID, id);
      end else
        FFiles[id] := TFile_Empty.Create(FConnectionID, id);
      Exit;
    end;
  end;
end;

procedure TMetaManager.InitFileFields(id: Integer);
begin
  if id < ConManager.Connection[FConnectionID].GetFileCount then
  begin
    if not Assigned(FFiles[id]) then
    begin
      InitFile(id);
      if not (FFiles[id] is TFile_Empty) then
        FFiles[id].InitDataFields;
    end;
  end;
end;

procedure TMetaManager.InitRootFiles;
var
  files: TStrings;
  i: Integer;
  typei: Integer;
  fid: Integer;
  finfo: TFileInfo;
begin
  if ConManager.Connection[FConnectionID] is TAccess_OniArchive then
    TAccess_OniArchive(ConManager.Connection[FConnectionID]).UnloadWhenUnused := False;
  files := TStringList.Create;
  files := ConManager.Connection[FConnectionID].GetFilesList('', '', False, ST_IDAsc);
  SetLength(FFiles, ConManager.Connection[FConnectionID].GetFileCount);
  for i := 0 to High(FFiles) do
    FFiles[i] := nil;
  if files.Count > 0 then
  begin
    for i := 0 to files.Count - 1 do
    begin
      fid := StrToInt(MidStr(files.Strings[i], 1, 5));
      finfo := ConManager.Connection[FConnectionID].GetFileInfo(fid);
      if Length(finfo.Name) > 0 then
      begin
        if finfo.Size > 0 then
        begin
          for typei := 0 to High(FileDescs) do
          begin
            if FileDescs[typei].ext = finfo.Extension then
            begin
              FFiles[fid] := TFileType(FileDescs[typei].ftype).Create(FConnectionID, fid);
              Break;
            end;
          end;
        end
        else
          FFiles[fid] := TFile_Empty.Create(FConnectionID, fid);
      end;
    end;
  end;
  files.Free;
  if ConManager.Connection[FConnectionID] is TAccess_OniArchive then
    TAccess_OniArchive(ConManager.Connection[FConnectionID]).UnloadWhenUnused := True;
end;

end.
