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 211)
+++ 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 211)
+++ 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 211)
+++ 	(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 211)
+++ 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.
Index: oup/current/OniUnPacker.bdsproj
===================================================================
--- oup/current/OniUnPacker.bdsproj	(revision 211)
+++ oup/current/OniUnPacker.bdsproj	(revision 212)
@@ -176,5 +176,6 @@
 			<Language Name="ProjectLang">$00000000</Language>
 			<Language Name="RootDir"></Language>
-		</Language>  <Excluded_Packages>
+		</Language>  
+    <Excluded_Packages>
       <Excluded_Packages Name="d:\programme\borland\bds\3.0\Bin\dbwebxprt.bpl">Borland Web Wizard Package</Excluded_Packages>
     </Excluded_Packages>
Index: oup/current/OniUnPacker.dpr
===================================================================
--- oup/current/OniUnPacker.dpr	(revision 211)
+++ oup/current/OniUnPacker.dpr	(revision 212)
@@ -34,5 +34,7 @@
   TXMP in 'FileClasses\TXMP.pas',
   MetaEditor in 'Tools\MetaEditor.pas' {Form_Meta},
-  _FileManager in 'FileClasses\_FileManager.pas';
+  _MetaManager in 'FileClasses\_MetaManager.pas',
+  _EmptyFile in 'FileClasses\_EmptyFile.pas',
+  TXAN in 'FileClasses\TXAN.pas';
 
 {$R *.res}
Index: oup/current/Tools/MetaEditor.dfm
===================================================================
--- oup/current/Tools/MetaEditor.dfm	(revision 211)
+++ oup/current/Tools/MetaEditor.dfm	(revision 212)
@@ -3,6 +3,6 @@
   Top = 0
   Caption = 'Form_Meta'
-  ClientHeight = 293
-  ClientWidth = 426
+  ClientHeight = 365
+  ClientWidth = 446
   Color = clBtnFace
   Font.Charset = DEFAULT_CHARSET
@@ -18,13 +18,20 @@
   OnCreate = FormCreate
   DesignSize = (
-    426
-    293)
+    446
+    365)
   PixelsPerInch = 96
   TextHeight = 13
+  object Label3: TLabel
+    Left = 3
+    Top = 6
+    Width = 61
+    Height = 13
+    Caption = 'Connection: '
+  end
   object VST: TVirtualStringTree
-    Left = 8
-    Top = 8
-    Width = 389
-    Height = 265
+    Left = 4
+    Top = 44
+    Width = 409
+    Height = 321
     Anchors = [akLeft, akTop, akRight, akBottom]
     AnimationDuration = 0
@@ -37,17 +44,49 @@
     Header.Options = [hoColumnResize, hoDrag, hoVisible]
     TabOrder = 0
+    TreeOptions.AutoOptions = [toAutoDropExpand, toAutoScrollOnExpand, toAutoDeleteMovedNodes]
     TreeOptions.MiscOptions = [toFullRepaintOnResize, toInitOnSave, toToggleOnDblClick, toWheelPanning]
-    TreeOptions.PaintOptions = [toShowDropmark, toShowRoot, toShowTreeLines, toThemeAware, toUseBlendedImages]
     OnGetText = VSTGetText
+    OnPaintText = VSTPaintText
+    OnInitChildren = VSTInitChildren
     Columns = <
       item
         Position = 0
         Width = 150
-        WideText = 'Main'
+        WideText = 'FName'
       end
       item
         Position = 1
+        WideText = 'FType'
+      end
+      item
+        Position = 2
+        WideText = 'FID'
+      end
+      item
+        Position = 3
         WideText = 'Data'
       end>
   end
+  object Button1: TButton
+    Left = 204
+    Top = 1
+    Width = 75
+    Height = 25
+    Anchors = [akTop, akRight]
+    Caption = 'Load'
+    Default = True
+    TabOrder = 1
+    OnClick = Button1Click
+  end
+  object combo_connection: TComboBox
+    Left = 64
+    Top = 3
+    Width = 134
+    Height = 21
+    Style = csDropDownList
+    Anchors = [akLeft, akTop, akRight]
+    DropDownCount = 12
+    ItemHeight = 13
+    TabOrder = 2
+  end
 end
Index: oup/current/Tools/MetaEditor.pas
===================================================================
--- oup/current/Tools/MetaEditor.pas	(revision 211)
+++ oup/current/Tools/MetaEditor.pas	(revision 212)
@@ -3,16 +3,25 @@
 uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, VirtualTrees, _FileManager;
+  Dialogs, VirtualTrees, _MetaManager, StdCtrls;
 
 type
   TForm_Meta = class(TForm)
     VST: TVirtualStringTree;
+    Button1: TButton;
+    Label3: TLabel;
+    combo_connection: TComboBox;
     procedure FormClose(Sender: TObject; var Action: TCloseAction);
     procedure FormCreate(Sender: TObject);
     procedure VSTGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
       Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
+    procedure Button1Click(Sender: TObject);
+    procedure VSTInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode;
+      var ChildCount: Cardinal);
+    procedure VSTPaintText(Sender: TBaseVirtualTree;
+      const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
+      TextType: TVSTTextType);
   private
   public
-    FileManager: TFileManager;
+    MetaManager: TMetaManager;
   end;
 
@@ -22,5 +31,5 @@
 implementation
 uses
-  Data, _DataTypes, _FileTypes;
+  Data, _DataTypes, _FileTypes, ConnectionManager, TypeDefs, StrUtils;
 {$R *.dfm}
 
@@ -45,32 +54,105 @@
 
 
-procedure TForm_Meta.FormClose(Sender: TObject; var Action: TCloseAction);
-begin
-  FileManager.Free;
-  Action := caFree;
-end;
-
-
-procedure TForm_Meta.FormCreate(Sender: TObject);
-var
+procedure TForm_Meta.VSTInitChildren(Sender: TBaseVirtualTree;
+  Node: PVirtualNode; var ChildCount: Cardinal);
+var
+  data: PNodeData;
+  newdata: TNodeData;
+  newnode: PVirtualNode;
+  i: Integer;
+  id: Integer;
+begin
+  data := VST.GetNodeData(node);
+  for i := 0 to MetaManager.FileById[TFile(data.Field).FileID].ChildCount - 1 do
+  begin
+    id := MetaManager.FileById[TFile(data.Field).FileID].LinkByIndex[i].DestID;
+    MetaManager.InitFile(id);
+    newdata.Field := MetaManager.FileById[id];
+    newnode := AddVSTEntry(VST, Node, newdata);
+    if MetaManager.FileById[id].ChildCount > 0 then
+      VST.HasChildren[newnode] := True;
+  end;
+  ChildCount := MetaManager.FileById[TFile(data.Field).FileID].ChildCount;
+end;
+
+
+procedure TForm_Meta.Button1Click(Sender: TObject);
+var
+  name: String;
+  conid: Integer;
+
   a,b,c: Int64;
   i: Integer;
   data: TNodeData;
-begin
+  node: PVirtualNode;
+begin
+  if combo_connection.ItemIndex >= 0 then
+  begin
+    name := combo_connection.Items.Strings[combo_connection.ItemIndex];
+    conid := StrToInt(MidStr(name, Pos('[', name) + 1, Pos(']', name) - Pos('[', name)  - 1));
+
+    QueryPerformanceFrequency(c);
+    QueryPerformanceCounter(a);
+    MetaManager := TMetaManager.Create(conid);
+    QueryPerformanceCounter(b);
+    ShowMessage('Loading Done - ' + FloatToStr((b-a)/c) + 's');
+
+    VST.Clear;
+    VST.BeginUpdate;
+    for i := 0 to MetaManager.FileCount - 1 do
+    begin
+      if Assigned(MetaManager.FileById[i]) then
+      begin
+        data.Field := MetaManager.FileById[i];
+        node := AddVSTEntry(VST, nil, data);
+        if MetaManager.FileById[i].ChildCount > 0 then
+          VST.HasChildren[node] := True;
+      end;
+    end;
+    VST.EndUpdate;
+  end;
+end;
+
+procedure TForm_Meta.FormClose(Sender: TObject; var Action: TCloseAction);
+begin
+  MetaManager.Free;
+  Action := caFree;
+end;
+
+
+procedure TForm_Meta.FormCreate(Sender: TObject);
+var
+  i: Integer;
+
+  fn, datatype, boxstring: String;
+  level: Integer;
+begin
+  combo_connection.ItemIndex := -1;
+  combo_connection.Items.Clear;
+  if ConManager.Count > 0 then
+  begin
+    for i := 0 to ConManager.Count - 1 do
+    begin
+      level := ConManager.ConnectionByIndex[i].LevelNumber;
+      fn := ExtractFileName(ConManager.ConnectionByIndex[i].FileName);
+      if ConManager.ConnectionByIndex[i].Backend = DB_ONI then
+        datatype := 'ONI-.dat: '
+      else if ConManager.ConnectionByIndex[i].Backend = DB_ADB then
+        datatype := 'OUP-DB: '
+      else
+        datatype := 'Unknown: ';
+      boxstring := datatype + fn + ' (Level: ' + IntToStr(level) + ') [' + IntToStr(ConManager.ConnectionByIndex[i].ConnectionID) + ']';
+      combo_connection.Items.Add(boxstring);
+    end;
+    if combo_connection.ItemIndex = -1 then
+    begin
+      combo_connection.ItemIndex := 0;
+    end;
+  end;
+
+
   VST.NodeDataSize := SizeOf(TNodeData);
   VST.Font.Charset := AppSettings.CharSet;
   VST.Clear;
-
-  QueryPerformanceFrequency(c);
-  QueryPerformanceCounter(a);
-  FileManager := TFileManager.Create(1);
-  QueryPerformanceCounter(b);
-  ShowMessage('Loading Done - ' + FloatToStr((b-a)/c) + 's');
-
-  for i := 0 to FileManager.FileCount - 1 do
-  begin
-    data.Field := FileManager.FileById[i];
-    AddVSTEntry(VST, nil, data);
-  end;
 end;
 
@@ -87,28 +169,44 @@
   begin
     case Column of
-      0: begin
-        if Data.Field is TFile then
-        begin
-          CellText := TFile(Data.Field).FileName;
-        end;
-      end;
-{      0:
-        CellText := Data.Caption;
+      0:
+        begin
+          if Data.Field is TFile then
+          begin
+            CellText := TFile(Data.Field).FileName;
+            if CellText = '' then
+              CellText := 'Unnamed';
+          end;
+        end;
       1:
-        if Data.DataType > 0 then
-          CellText := '0x' + IntToHex(Data.Offset, 8)
-        else if Data.Offset > 0 then
-          CellText := '0x' + IntToHex(Data.Offset, 8);
+        begin
+          if Data.Field is TFile then
+            CellText := TFile(Data.Field).FileExt;
+        end;
       2:
-        if Data.DataType > 0 then
-          CellText := GetDataType(Data.DataType);
-      3:
-        if Data.DataType > 0 then
-          CellText := Data.Value //GetValue(data.DataType, data.Offset)
-        else if Length(Data.Value) > 0 then
-          CellText := IntToStr(StrToInt(Data.Value)) + ' Bytes';
-      4:
-        CellText := Data.Description;
-}    end;
+        begin
+          if Data.Field is TFile then
+            CellText := IntToStr(TFile(Data.Field).FileID);
+        end;
+    end;
+  end;
+end;
+
+procedure TForm_Meta.VSTPaintText(Sender: TBaseVirtualTree;
+  const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
+  TextType: TVSTTextType);
+var
+  Data: PNodeData;
+begin
+  Data     := Sender.GetNodeData(Node);
+  if TextType = ttNormal then
+  begin
+    case Column of
+      0:
+        begin
+          if Data.Field is TFile then
+            if Length(TFile(Data.Field).FileName) = 0 then
+              TargetCanvas.Font.Color := $000060;
+        end;
+    end;
   end;
 end;
