context: #region References
  using System;
  using System.Collections.Generic;
  using System.IO;
  using System.Runtime.InteropServices;
  #endregion
  
  namespace Ultima
  {
      public sealed class TileMatrix
      {
          private readonly HuedTile[][][][][] m_StaticTiles;
          private readonly Tile[][][] m_LandTiles;
          private bool[][] m_RemovedStaticBlock;
          private List<StaticTile>[][] m_StaticTiles_ToAdd;
  
          public static Tile[] InvalidLandBlock { get; private set; }
          public static HuedTile[][][] EmptyStaticBlock { get; private set; }
  
          private FileStream m_Map;
          private BinaryReader m_UOPReader;
          private FileStream m_Statics;
          private Entry3D[] m_StaticIndex;
  
          public Entry3D[] StaticIndex
          {
              get
              {
                  if (!StaticIndexInit)
                  {
                      InitStatics();
                  }
                  return m_StaticIndex;
              }
          }
  
          public bool StaticIndexInit;
  
          public TileMatrixPatch Patch { get; private set; }
  
          public int BlockWidth { get; private set; }
  
          public int BlockHeight { get; private set; }
  
          public int Width { get; private set; }
  
          public int Height { get; private set; }
  
          private readonly string mapPath;
          private readonly string indexPath;
          private readonly string staticsPath;
  
          public void CloseStreams()
          {
              if (m_Map != null)
              {
                  m_Map.Close();
              }
  
              if (m_UOPReader != null)
              {
                  m_UOPReader.Close();
              }
  
              if (m_Statics != null)
              {
                  m_Statics.Close();
              }
          }
  
          public TileMatrix(int fileIndex, int mapID, int width, int height, string path)
          {
              Width = width;
              Height = height;
              BlockWidth = width >> 3;
              BlockHeight = height >> 3;
  
              if (path == null)
              {
                  mapPath = Files.GetFilePath("map{0}.mul", fileIndex);
  
                  if (String.IsNullOrEmpty(mapPath) || !File.Exists(mapPath))
                  {
                      mapPath = Files.GetFilePath("map{0}LegacyMUL.uop", fileIndex);
                  }
  
                  if (mapPath != null && mapPath.EndsWith(".uop"))
                  {
                      IsUOPFormat = true;
                  }
              }
              else
              {
                  mapPath = Path.Combine(path, String.Format("map{0}.mul", fileIndex));
  
                  if (!File.Exists(mapPath))
                  {
                      mapPath = Path.Combine(path, String.Format("map{0}LegacyMUL.uop", fileIndex));
                  }
  
                  if (!File.Exists(mapPath))
                  {
                      mapPath = null;
                  }
                  else if (mapPath != null && mapPath.EndsWith(".uop"))
                  {
                      IsUOPFormat = true;
                  }
              }
  
              if (path == null)
              {
                  indexPath = Files.GetFilePath("staidx{0}.mul", fileIndex);
              }
              else
              {
                  indexPath = Path.Combine(path, String.Format("staidx{0}.mul", fileIndex));
                  if (!File.Exists(indexPath))
                  {
                      indexPath = null;
                  }
              }
  
              if (path == null)
              {
                  staticsPath = Files.GetFilePath("statics{0}.mul", fileIndex);
              }
              else
              {
                  staticsPath = Path.Combine(path, String.Format("statics{0}.mul", fileIndex));
                  if (!File.Exists(staticsPath))
                  {
                      staticsPath = null;
                  }
              }
  
              EmptyStaticBlock = new HuedTile[8][][];
  
              for (int i = 0; i < 8; ++i)
              {
                  EmptyStaticBlock[i] = new HuedTile[8][];
  
                  for (int j = 0; j < 8; ++j)
                  {
                      EmptyStaticBlock[i][j] = new HuedTile[0];
                  }
              }
  
              InvalidLandBlock = new Tile[196];
  
              m_LandTiles = new Tile[BlockWidth][][];
              m_StaticTiles = new HuedTile[BlockWidth][][][][];
  
              Patch = new TileMatrixPatch(this, mapID, path);
          }
  
          public void SetStaticBlock(int x, int y, HuedTile[][][] value)
          {
              if (x < 0 || y < 0 || x >= BlockWidth || y >= BlockHeight)
              {
                  return;
              }
  
              if (m_StaticTiles[x] == null)
              {
                  m_StaticTiles[x] = new HuedTile[BlockHeight][][][];
              }
  
              m_StaticTiles[x][y] = value;
          }
  
          public HuedTile[][][] GetStaticBlock(int x, int y)
          {
              return GetStaticBlock(x, y, true);
          }
  
          public HuedTile[][][] GetStaticBlock(int x, int y, bool patch)
          {
              if (x < 0 || y < 0 || x >= BlockWidth || y >= BlockHeight)
              {
                  return EmptyStaticBlock;
              }
  
              if (m_StaticTiles[x] == null)
              {
                  m_StaticTiles[x] = new HuedTile[BlockHeight][][][];
              }
  
              HuedTile[][][] tiles = m_StaticTiles[x][y];
  
              if (tiles == null)
              {
                  tiles = m_StaticTiles[x][y] = ReadStaticBlock(x, y);
              }
  
              if ((Map.UseDiff) && (patch))
              {
                  if (Patch.StaticBlocksCount > 0)
                  {
                      if (Patch.StaticBlocks[x] != null)
                      {
                          if (Patch.StaticBlocks[x][y] != null)
                          {
                              tiles = Patch.StaticBlocks[x][y];
                          }
                      }
                  }
              }
              return tiles;
          }
  
          public HuedTile[] GetStaticTiles(int x, int y, bool patch)
          {
              return GetStaticBlock(x >> 3, y >> 3, patch)[x & 0x7][y & 0x7];
          }
  
          public HuedTile[] GetStaticTiles(int x, int y)
          {
              return GetStaticBlock(x >> 3, y >> 3)[x & 0x7][y & 0x7];
          }
  
          public void SetLandBlock(int x, int y, Tile[] value)
          {
              if (x < 0 || y < 0 || x >= BlockWidth || y >= BlockHeight)
              {
                  return;
              }
  
              if (m_LandTiles[x] == null)
              {
                  m_LandTiles[x] = new Tile[BlockHeight][];
              }
  
              m_LandTiles[x][y] = value;
          }
  
          public Tile[] GetLandBlock(int x, int y)
          {
              return GetLandBlock(x, y, true);
          }
  
          public Tile[] GetLandBlock(int x, int y, bool patch)
          {
              if (x < 0 || y < 0 || x >= BlockWidth || y >= BlockHeight)
              {
                  return InvalidLandBlock;
              }
  
              if (m_LandTiles[x] == null)
              {
                  m_LandTiles[x] = new Tile[BlockHeight][];
              }
  
              Tile[] tiles = m_LandTiles[x][y];
  
              if (tiles == null)
              {
                  tiles = m_LandTiles[x][y] = ReadLandBlock(x, y);
              }
  
              if ((Map.UseDiff) && (patch))
              {
                  if (Patch.LandBlocksCount > 0)
                  {
                      if (Patch.LandBlocks[x] != null)
                      {
  
gt:                         if (Patch.LandBlocks[x][y] != null)