Index: oup/current/FileClasses/TXAN.pas
===================================================================
--- oup/current/FileClasses/TXAN.pas	(revision 212)
+++ oup/current/FileClasses/TXAN.pas	(revision 212)
@@ -0,0 +1,81 @@
+unit TXAN;
+
+interface
+
+uses
+  _FileTypes;
+
+type
+  TFile_TXAN = class(TFile)
+    protected
+      procedure InitDatLinks; override;
+      procedure InitDataFields; override;
+      procedure InitRawList; override;
+  end;
+
+implementation
+
+uses
+  ConnectionManager, Math, Classes, TypeDefs, _DataTypes;
+
+procedure TFile_TXAN.InitDataFields;
+var
+  tempi: Integer;
+  temps: String;
+  templist: TStringList;
+begin
+  FDataFields := TBlock.Create(Self, nil, 0, 'Base', '', nil);
+  templist := TStringList.Create;
+  with FDataFields do
+  begin
+    AddField(TFileID, $00, 'FileID', '', nil);
+
+    AddField(TLevelID, $04, 'LevelID', '', nil);
+
+    tempi := 12;
+    AddField(TUnused, $08, 'Unused data', '', @tempi);
+
+    tempi := 2;
+    AddField(TInt, $14, 'Loop speed', '', @tempi);
+
+    tempi := 2;
+    AddField(TInt, $16, 'Unknown', '', @tempi);
+
+    tempi := 2;
+    AddField(TInt, $18, 'Unknown', '', @tempi);
+
+    tempi := 2;
+    AddField(TUnused, $1A, 'Unused', '', @tempi);
+
+    with AddField(TArray, $1C, 'AnimTextures array', '', @tempi) do
+    begin
+      AddField(TLinkByID, $00, 'Texture', '', nil);
+    end;
+  end;
+  templist.Free;
+end;
+
+
+procedure TFile_TXAN.InitDatLinks;
+var
+  links: Integer;
+  i: Integer;
+begin
+  ConManager.Connection[FConnectionID].LoadDatFilePart(FFileID, $1C, SizeOf(links), @links);
+  SetLength(FDatLinks, links);
+  for i := 0 to links - 1 do
+  begin
+    FDatLinks[i].SrcOffset := $20 + $4 * i;
+    FDatLinks[i].DestID := GetDatLinkValue(FFileStream, FDatLinks[i].SrcOffset);
+    FDatLinks[i].PosDestExts := 'TXMP';
+  end;
+end;
+
+
+procedure TFile_TXAN.InitRawList;
+begin
+  SetLength(FRawParts, 0);
+end;
+
+end.
+
Index: oup/current/FileClasses/TXMP.pas
===================================================================
--- oup/current/FileClasses/TXMP.pas	(revision 210)
+++ oup/current/FileClasses/TXMP.pas	(revision 212)
@@ -27,5 +27,5 @@
   templist: TStringList;
 begin
-  FDataFields := TBlock.Create(Self, 0, 'Base', '', nil);
+  FDataFields := TBlock.Create(Self, nil, 0, 'Base', '', nil);
   templist := TStringList.Create;
   with FDataFields do
Index: oup/current/FileClasses/_DataTypes.pas
===================================================================
--- oup/current/FileClasses/_DataTypes.pas	(revision 210)
+++ oup/current/FileClasses/_DataTypes.pas	(revision 212)
@@ -14,9 +14,10 @@
       FDataLength: Integer;
       FParentFile: TObject;
+      FParentField: TDataField;
       FChanged: Boolean;
       function GetValueAsString: String; virtual; abstract;
     public
-      constructor Create(ParentFile: TObject; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer); virtual;
+      constructor Create(ParentFile: TObject; ParentField: TDataField;
+          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); virtual;
 
       procedure Update(Offset, Length: Integer); virtual; abstract;
@@ -40,6 +41,6 @@
     public
       // ExtraArgs: keine
-      constructor Create(ParentFile: TObject; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentField: TDataField;
+          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
       procedure Update(Offset, Length: Integer); override;
       property FieldByOffset[Offset: Integer]: TDataField read GetFieldByOffset;
@@ -47,6 +48,6 @@
       property FieldCount: Integer read GetFieldCount;
 
-      procedure AddField(fieldtype: TFieldType; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer);
+      function AddField(fieldtype: TFieldType; Offset: Integer;
+          Name, Description: String; ExtraArgs: Pointer): TDataField;
   end;
 
@@ -58,6 +59,6 @@
     public
       // ExtraArgs: Pointer auf Integer: Bytes of TInt
-      constructor Create(ParentFile: TObject; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentField: TDataField;
+          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
       procedure Update(Offset, Length: Integer); override;
   end;
@@ -71,6 +72,6 @@
     public
       // ExtraArgs: Pointer auf TStringList
-      constructor Create(ParentFile: TObject; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentField: TDataField;
+          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
       procedure Update(Offset, Length: Integer); override;
   end;
@@ -83,6 +84,6 @@
     public
       // ExtraArgs: keine
-      constructor Create(ParentFile: TObject; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentField: TDataField;
+          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
       procedure Update(Offset, Length: Integer); override;
   end;
@@ -95,6 +96,6 @@
     public
       // ExtraArgs: keine
-      constructor Create(ParentFile: TObject; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentField: TDataField;
+          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
       procedure Update(Offset, Length: Integer); override;
   end;
@@ -108,6 +109,6 @@
     public
       // ExtraArgs: Pointer auf String: Possible Exts
-      constructor Create(ParentFile: TObject; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentField: TDataField;
+          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
       procedure Update(Offset, Length: Integer); override;
   end;
@@ -120,6 +121,6 @@
     public
       // ExtraArgs: Pointer auf Integer: Length
-      constructor Create(ParentFile: TObject; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentField: TDataField;
+          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
       procedure Update(Offset, Length: Integer); override;
   end;
@@ -134,6 +135,6 @@
     public
       // ExtraArgs: Pointer auf 2 Integer: Length+Count (packed record...)
-      constructor Create(ParentFile: TObject; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentField: TDataField;
+          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
       procedure Update(Offset, Length: Integer); override;
       property FieldByOffset[Offset: Integer]: TDataField read GetFieldByOffset;
@@ -141,6 +142,6 @@
       property FieldCount: Integer read GetFieldCount;
 
-      procedure AddField(fieldtype: TFieldType; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer);
+      function AddField(fieldtype: TFieldType; Offset: Integer;
+          Name, Description: String; ExtraArgs: Pointer): TDataField;
   end;
 
@@ -152,6 +153,6 @@
     public
       // ExtraArgs: keine
-      constructor Create(ParentFile: TObject; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentField: TDataField;
+          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
       procedure Update(Offset, Length: Integer); override;
   end;
@@ -163,6 +164,6 @@
     public
       // ExtraArgs: Pointer auf Integer: Length
-      constructor Create(ParentFile: TObject; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer); override;
+      constructor Create(ParentFile: TObject; ParentField: TDataField;
+          Offset: Integer; Name, Description: String; ExtraArgs: Pointer); override;
       procedure Update(Offset, Length: Integer); override;
   end;
@@ -181,11 +182,12 @@
 { TDataType }
 
-constructor TDataField.Create(ParentFile: TObject; Offset: Integer;
-    Name, Description: String; ExtraArgs: Pointer);
+constructor TDataField.Create(ParentFile: TObject; ParentField: TDataField;
+    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
 begin
   FOffset := Offset;
   FName := Name;
   FDescription := Description;
-  FParentFile := ParentFile; 
+  FParentFile := ParentFile;
+  FParentField := ParentField;
 end;
 
@@ -194,11 +196,11 @@
 { TString }
 
-constructor TString.Create(ParentFile: TObject; Offset: Integer;
-    Name, Description: String; ExtraArgs: Pointer);
+constructor TString.Create(ParentFile: TObject; ParentField: TDataField;
+    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
 var
   fstream: TMemoryStream;
   i: Integer;
 begin
-  inherited Create(ParentFile, Offset, Name, Description, ExtraArgs);
+  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
   FDataLength := Integer(ExtraArgs^);
   fstream := TFile(ParentFile).FileStream;
@@ -228,10 +230,10 @@
 { TInt }
 
-constructor TInt.Create(ParentFile: TObject; Offset: Integer;
-    Name, Description: String; ExtraArgs: Pointer);
-var
-  fstream: TMemoryStream;
-begin
-  inherited Create(ParentFile, Offset, Name, Description, ExtraArgs);
+constructor TInt.Create(ParentFile: TObject; ParentField: TDataField;
+    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
+var
+  fstream: TMemoryStream;
+begin
+  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
   FDataLength := Integer(ExtraArgs^);
   FInt := 0;
@@ -255,14 +257,14 @@
 { TArray }
 
-procedure TArray.AddField(fieldtype: TFieldType; Offset: Integer;
-          Name, Description: String; ExtraArgs: Pointer);
-begin
-  Exit;
-end;
-
-constructor TArray.Create(ParentFile: TObject; Offset: Integer;
-    Name, Description: String; ExtraArgs: Pointer);
-begin
-  inherited Create(ParentFile, Offset, Name, Description, ExtraArgs);
+function TArray.AddField(fieldtype: TFieldType; Offset: Integer;
+    Name, Description: String; ExtraArgs: Pointer): TDataField;
+begin
+  Exit;
+end;
+
+constructor TArray.Create(ParentFile: TObject; ParentField: TDataField;
+    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
+begin
+  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
 end;
 
@@ -305,6 +307,6 @@
 { TBlock }
 
-procedure TBlock.AddField(fieldtype: TFieldType; Offset: Integer; Name,
-  Description: String; ExtraArgs: Pointer);
+function TBlock.AddField(fieldtype: TFieldType; Offset: Integer; Name,
+    Description: String; ExtraArgs: Pointer): TDataField;
 var
   i: Integer;
@@ -323,11 +325,12 @@
   SetLength(FDataFields, Length(FDataFields) + 1);
   FDataFields[High(FDataFields)] := TFieldType(fieldtype).Create(
-      FParentFile, Offset, Name, Description, ExtraArgs);
-end;
-
-constructor TBlock.Create(ParentFile: TObject; Offset: Integer;
-    Name, Description: String; ExtraArgs: Pointer);
-begin
-  inherited Create(ParentFile, Offset, Name, Description, ExtraArgs);
+      FParentFile, Self, Offset, Name, Description, ExtraArgs);
+  Result := FDataFields[High(FDataFields)];
+end;
+
+constructor TBlock.Create(ParentFile: TObject; ParentField: TDataField;
+    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
+begin
+  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
 end;
 
@@ -356,10 +359,10 @@
 { TLevelID }
 
-constructor TLevelID.Create(ParentFile: TObject; Offset: Integer;
-    Name, Description: String; ExtraArgs: Pointer);
-var
-  fstream: TMemoryStream;
-begin
-  inherited Create(ParentFile, Offset, Name, Description, ExtraArgs);
+constructor TLevelID.Create(ParentFile: TObject; ParentField: TDataField;
+    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
+var
+  fstream: TMemoryStream;
+begin
+  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
   FDataLength := 4;
   fstream := TFile(ParentFile).FileStream;
@@ -383,10 +386,10 @@
 { TFileID }
 
-constructor TFileID.Create(ParentFile: TObject; Offset: Integer;
-    Name, Description: String; ExtraArgs: Pointer);
-var
-  fstream: TMemoryStream;
-begin
-  inherited Create(ParentFile, Offset, Name, Description, ExtraArgs);
+constructor TFileID.Create(ParentFile: TObject; ParentField: TDataField;
+    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
+var
+  fstream: TMemoryStream;
+begin
+  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
   FDataLength := 4;
   fstream := TFile(ParentFile).FileStream;
@@ -413,10 +416,10 @@
 { TLinkByID }
 
-constructor TLinkByID.Create(ParentFile: TObject; Offset: Integer; Name,
-  Description: String; ExtraArgs: Pointer);
-var
-  fstream: TMemoryStream;
-begin
-  inherited Create(ParentFile, Offset, Name, Description, ExtraArgs);
+constructor TLinkByID.Create(ParentFile: TObject; ParentField: TDataField;
+    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
+var
+  fstream: TMemoryStream;
+begin
+  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
   FDataLength := 4;
   FPosExts := String(ExtraArgs^);
@@ -444,10 +447,10 @@
 { TRawLink }
 
-constructor TRawLink.Create(ParentFile: TObject; Offset: Integer; Name,
-  Description: String; ExtraArgs: Pointer);
-var
-  fstream: TMemoryStream;
-begin
-  inherited Create(ParentFile, Offset, Name, Description, ExtraArgs);
+constructor TRawLink.Create(ParentFile: TObject; ParentField: TDataField;
+    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
+var
+  fstream: TMemoryStream;
+begin
+  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
   FDataLength := 4;
   fstream := TFile(ParentFile).FileStream;
@@ -470,8 +473,8 @@
 { TUnused }
 
-constructor TUnused.Create(ParentFile: TObject; Offset: Integer; Name,
-  Description: String; ExtraArgs: Pointer);
-begin
-  inherited Create(ParentFile, Offset, Name, Description, ExtraArgs);
+constructor TUnused.Create(ParentFile: TObject; ParentField: TDataField;
+    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
+begin
+  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
   FDataLength := Integer(ExtraArgs^);
 end;
@@ -491,10 +494,10 @@
 { TBitSet }
 
-constructor TBitSet.Create(ParentFile: TObject; Offset: Integer; Name,
-  Description: String; ExtraArgs: Pointer);
-var
-  fstream: TMemoryStream;
-begin
-  inherited Create(ParentFile, Offset, Name, Description, ExtraArgs);
+constructor TBitSet.Create(ParentFile: TObject; ParentField: TDataField;
+    Offset: Integer; Name, Description: String; ExtraArgs: Pointer);
+var
+  fstream: TMemoryStream;
+begin
+  inherited Create(ParentFile, ParentField, Offset, Name, Description, ExtraArgs);
   FNames := TStringList.Create;
   FNames.AddStrings(TStringList(ExtraArgs^));
Index: oup/current/FileClasses/_EmptyFile.pas
===================================================================
--- oup/current/FileClasses/_EmptyFile.pas	(revision 212)
+++ oup/current/FileClasses/_EmptyFile.pas	(revision 212)
@@ -0,0 +1,39 @@
+unit _EmptyFile;
+
+interface
+
+uses
+  _FileTypes;
+
+type
+  TFile_Empty = class(TFile)
+    protected
+      procedure InitDatLinks; override;
+      procedure InitDataFields; override;
+      procedure InitRawList; override;
+  end;
+
+implementation
+
+uses
+  ConnectionManager, Math, Classes, TypeDefs, _DataTypes;
+
+procedure TFile_Empty.InitDataFields;
+begin
+  FDataFields := TBlock.Create(Self, nil, 0, 'Base', '', nil);
+end;
+
+
+procedure TFile_Empty.InitDatLinks;
+begin
+  SetLength(FDatLinks, 0);
+end;
+
+
+procedure TFile_Empty.InitRawList;
+begin
+  SetLength(FRawParts, 0);
+end;
+
+end.
+
Index: oup/current/FileClasses/_FileManager.pas
===================================================================
--- oup/current/FileClasses/_FileManager.pas	(revision 210)
+++ 	(revision )
@@ -1,81 +1,0 @@
-unit _FileManager;
-interface
-
-uses _FileTypes, TXMP;
-
-type
-  TFileType = class of TFile;
-  TFileDesc = record
-    ext: String;
-    ftype: TFileType;
-  end;
-
-const
-  FileDescs: array[0..0] of TFileDesc = (
-    (ext: 'TXMP'; ftype: TFile_TXMP)
-  );
-
-type
-  TFileManager = class
-    protected
-      FFiles: array of TFile;
-      FConnectionID: Integer;
-      function GetFileCount: Integer;
-      function GetFileById(Id: Integer): TFile;
-    public
-      constructor Create(ConnectionID: 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 TFileManager.Create(ConnectionID: Integer);
-var
-  files: TStrings;
-  i: Integer;
-  typei: Integer;
-  fid: Integer;
-begin
-  FConnectionID := ConnectionID;
-  if ConManager.Connection[ConnectionID] is TAccess_OniArchive then
-    TAccess_OniArchive(ConManager.Connection[ConnectionID]).UnloadWhenUnused := False;
-  files := TStringList.Create;
-  files := ConManager.Connection[ConnectionID].GetFilesList('', '', False, ST_IDAsc);
-  if files.Count > 0 then
-  begin
-    for i := 0 to files.Count - 1 do
-    begin
-      for typei := 0 to High(FileDescs) do
-      begin
-        if Pos('.' + FileDescs[typei].ext, files.Strings[i]) = Length(files.Strings[i]) - 4 then
-        begin
-          SetLength(FFiles, Length(FFiles) + 1);
-          fid := StrToInt(MidStr(files.Strings[i], 1, 5));
-          FFiles[High(FFiles)] := TFileType(FileDescs[typei].ftype).Create(FConnectionID, fid);
-        end;
-      end;
-    end;
-  end;
-  files.Free;
-  if ConManager.Connection[ConnectionID] is TAccess_OniArchive then
-    TAccess_OniArchive(ConManager.Connection[ConnectionID]).UnloadWhenUnused := True;
-end;
-
-function TFileManager.GetFileById(Id: Integer): TFile;
-begin
-  Result := FFiles[Id];
-end;
-
-function TFileManager.GetFileCount: Integer;
-begin
-  Result := Length(FFiles);
-end;
-
-end.
Index: oup/current/FileClasses/_FileTypes.pas
===================================================================
--- oup/current/FileClasses/_FileTypes.pas	(revision 210)
+++ oup/current/FileClasses/_FileTypes.pas	(revision 212)
@@ -17,4 +17,7 @@
       FFileStream: TMemoryStream;
 
+      FCached: Boolean;
+      FChanged: Boolean;
+
       FDatLinks: TDatLinkList;
       FDataFields: TBlock;
@@ -31,4 +34,5 @@
       function GetRawPartByOffset(Offset: Integer): TRawDataInfo;
       function GetRawPartByIndex(ID: Integer): TRawDataInfo;
+      function GetChildCount: Integer;
     public
       constructor Create(ConnectionID, FileID: Integer); virtual;
@@ -42,4 +46,8 @@
       property ConnectionID: Integer read FConnectionID;
 
+      property Cached: Boolean read FCached;
+      property Changed: Boolean read FChanged write FChanged;
+
+      property ChildCount: Integer read GetChildCount;
       property LinkByOffset[Offset: Integer]: TDatLink read GetDatLinkByOffset;
       property LinkByIndex[ID: Integer]: TDatLink read GetDatLinkByIndex;
@@ -63,5 +71,5 @@
 
 uses
-  DatLinks, RawList, ConnectionManager, Dialogs;
+  DatLinks, RawList, ConnectionManager, Dialogs, _EmptyFile;
 
 { TFileType }
@@ -79,6 +87,12 @@
   FFileSize := fileinfo.Size;
 
-  FFileStream := TMemoryStream.Create;
-  ConManager.Connection[ConnectionID].LoadDatFile(FileID, TStream(FFileStream));
+  FCached := False;
+  FChanged := False;
+
+  if not (Self is TFile_Empty) then
+  begin
+    FFileStream := TMemoryStream.Create;
+    ConManager.Connection[ConnectionID].LoadDatFile(FileID, TStream(FFileStream));
+  end;
 
   InitDatLinks();
@@ -86,5 +100,6 @@
   InitRawList();
 
-  FFileStream.Free;
+  if not (Self is TFile_Empty) then
+    FFileStream.Free;
   FFileStream := nil;
 end;
@@ -97,7 +112,21 @@
 
 function TFile.GetDatLinkByIndex(ID: Integer): TDatLink;
-begin
-  if ID < Length(FDatLinks) then
-    Result := FDatLinks[ID]
+var
+  i: Integer;
+  valids: Integer;
+begin
+  if ID < GetChildCount then
+  begin
+    valids := 0;
+    i := 0;
+    repeat
+      if FDatLinks[i].DestID >= 0 then
+      begin
+        Inc(valids);
+      end;
+      Inc(i);
+    until valids > ID;
+    Result := FDatLinks[i - 1];
+  end
   else
     with Result do
@@ -140,4 +169,18 @@
 end;
 
+
+function TFile.GetChildCount: Integer;
+var
+  i: Integer;
+begin
+  Result := Length(FDatLinks);
+  if Result > 0 then
+  begin
+    Result := 0;
+    for i := 0 to High(FDatLinks) do
+      if FDatLinks[i].DestID >= 0 then
+        Inc(Result);
+  end;
+end;
 
 function TFile.GetRawPartByIndex(ID: Integer): TRawDataInfo;
Index: oup/current/FileClasses/_MetaManager.pas
===================================================================
--- oup/current/FileClasses/_MetaManager.pas	(revision 212)
+++ oup/current/FileClasses/_MetaManager.pas	(revision 212)
@@ -0,0 +1,133 @@
+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);
+
+      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
+//  i: Integer;
+  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.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.
