private unsafe static Area ConvertUnsafeToSafe(AreaUnsafe *uArea)
        {
            Area area = new Area();

            area.x        = uArea->x;
            area.y        = uArea->y;
            area.tileInfo = new int[uArea->width, uArea->height];
            for (int i = 0; i < uArea->width; i++)
            {
                for (int j = 0; j < uArea->height; j++)
                {
                    area.tileInfo[i, j] = uArea->tileInfo[i][j];
                }
            }


            area.areas = new Area[uArea->areasCount];

            for (int i = 0; i < uArea->areasCount; i++)
            {
                area.areas[i] = ConvertUnsafeToSafe((uArea->areas[i]));
            }


            return(area);
        }
        public unsafe static Area CreateLineMapArea(int width, int height, int x = 0, int y = 0, int extraLines = 10, int branchQuantity = 100, int branchLength = 300)
        {
            AreaUnsafe *areaUnsafe = CreateUnsafeLineMapArea(width, height, x, y, extraLines, branchQuantity, branchLength);
            Area        area       = ConvertUnsafeToSafe(areaUnsafe);

            DestroyAreaUnsafe(areaUnsafe);
            return(area);
        }
        public unsafe static Area CreateSimpleDungeonArea(int width, int height, int x = 0, int y = 0, int tries = 1000, int extraCorridors = 0, int minWidth = 1, int maxWidth = 100, int minHeight = 1, int maxHeight = 100)
        {
            AreaUnsafe *areaUnsafe = CreateUnsafeSimpleDungeonArea(width, height, x, y, tries, extraCorridors, minWidth, maxWidth, minHeight, maxHeight);
            Area        area       = ConvertUnsafeToSafe(areaUnsafe);

            DestroyAreaUnsafe(areaUnsafe);
            return(area);
        }
        public unsafe static Area CreateBSPDungeonArea(int width, int height, int x = 0, int y = 0, int minRooms = 10, int maxRooms = 100, int minWidth = 1, int minHeight = 1)
        {
            AreaUnsafe *areaUnsafe = CreateUnsafeBSPDungeonArea(width, height, x, y, minRooms, maxRooms, minWidth, minHeight);
            Area        area       = ConvertUnsafeToSafe(areaUnsafe);

            DestroyAreaUnsafe(areaUnsafe);
            return(area);
        }
        public unsafe static Area CreateDrunkardWalkArea(int width, int height, int x = 0, int y = 0, int iterations = 10000)
        {
            AreaUnsafe *areaUnsafe = CreateUnsafeDrunkardArea(width, height, x, y, iterations);
            Area        area       = ConvertUnsafeToSafe(areaUnsafe);

            DestroyAreaUnsafe(areaUnsafe);
            return(area);
        }
        public unsafe static Area CreateRandomNoiseArea(int width, int height, int x, int y)
        {
            AreaUnsafe *areaUnsafe = CreateUnsafeRandomArea(width, height, x, y);
            Area        area       = ConvertUnsafeToSafe(areaUnsafe);

            DestroyAreaUnsafe(areaUnsafe);
            return(area);
        }
        public unsafe static Area GenerateSimpleDungeonInArea(Area area, int tries = 1000, int extraCorridors = 0, int minWidth = 1, int maxWidth = 100, int minHeight = 1, int maxHeight = 100)
        {
            AreaUnsafe *unsafeArea = ConvertSafeToUnsafe(area);

            GenerateSimpleDungeonAreaUnsafe(unsafeArea, tries, extraCorridors, minWidth, maxWidth, minHeight, maxHeight);
            Area areaReturn = ConvertUnsafeToSafe(unsafeArea);

            DestroyAreaUnsafe(unsafeArea);
            return(areaReturn);
        }
        public unsafe static Area GenerateBSPDungeonInArea(Area area, int minRooms = 10, int maxRooms = 100, int minWidth = 1, int minHeight = 1)
        {
            AreaUnsafe *unsafeArea = ConvertSafeToUnsafe(area);

            GenerateBSPDungeonAreaUnsafe(unsafeArea, minRooms, maxRooms, minWidth, minHeight);
            Area areaReturn = ConvertUnsafeToSafe(unsafeArea);

            DestroyAreaUnsafe(unsafeArea);
            return(areaReturn);
        }
        public unsafe static Area GenerateDrunkardWalkInArea(Area area)
        {
            AreaUnsafe *unsafeArea = ConvertSafeToUnsafe(area);

            GenerateDrunkardWalkAreaUnsafe(unsafeArea);
            Area areaReturn = ConvertUnsafeToSafe(unsafeArea);

            DestroyAreaUnsafe(unsafeArea);
            return(areaReturn);
        }
        public unsafe static Area GenerateRandomNoiseInArea(Area area)
        {
            AreaUnsafe *unsafeArea = ConvertSafeToUnsafe(area);

            GenerateRandomAreaInUnsafe(unsafeArea);
            Area areaReturn = ConvertUnsafeToSafe(unsafeArea);

            DestroyAreaUnsafe(unsafeArea);
            return(areaReturn);
        }
        public unsafe static Area GenerateLineMapInArea(Area area, int extraLines = 10, int branchQuantity = 100, int branchLength = 300)
        {
            AreaUnsafe *unsafeArea = ConvertSafeToUnsafe(area);

            GenerateLineMapAreaUnsafe(unsafeArea, extraLines, branchQuantity, branchLength);
            Area areaReturn = ConvertUnsafeToSafe(unsafeArea);

            DestroyAreaUnsafe(unsafeArea);
            return(areaReturn);
        }
        public unsafe static Area CreateCellularAutomataArea(int width, int height, CellularProbability[] probs, int x = 0, int y = 0, int iterations = 3, int numberOfTiles = 2)
        {
            for (int i = 0; i < probs.Length; i++)
            {
                AddCellularProbability(probs[i]);
            }
            AreaUnsafe *areaUnsafe = CreateUnsafeCellularAutomataArea(width, height, x, y, iterations, numberOfTiles);
            Area        area       = ConvertUnsafeToSafe(areaUnsafe);

            DestroyAreaUnsafe(areaUnsafe);
            return(area);
        }
        private unsafe static AreaUnsafe *ConvertSafeToUnsafe(Area area) //TODO, need a constructor that initialices some empty children areas.
        {
            AreaUnsafe *uArea = CreateUnsafeArea(area.tileInfo.GetLength(0), area.tileInfo.GetLength(1), area.x, area.y);

            for (int i = 0; i < uArea->width; i++)
            {
                for (int j = 0; j < uArea->height; j++)
                {
                    uArea->tileInfo[i][j] = area.tileInfo[i, j];
                }
            }
            return(uArea);
        }
        public unsafe static Area GenerateCellularAutomataInArea(Area area, CellularProbability[] probs, int iterations = 3, int numberOfTiles = 2)
        {
            for (int i = 0; i < probs.Length; i++)
            {
                AddCellularProbability(probs[i]);
            }
            AreaUnsafe *unsafeArea = ConvertSafeToUnsafe(area);

            GenerateCellularAutomataAreaUnsafe(unsafeArea, iterations, numberOfTiles);
            Area areaReturn = ConvertUnsafeToSafe(unsafeArea);

            DestroyAreaUnsafe(unsafeArea);
            return(areaReturn);
        }
        public unsafe static Area CreateArea(int width, int height, int x, int y)
        {
            AreaUnsafe *uArea = CreateUnsafeArea(width, height, x, y);

            return(ConvertUnsafeToSafe(uArea));
        }
 private unsafe static extern void GenerateCellularAutomataAreaUnsafe(AreaUnsafe *area, int iterations = 3, int numberOfTiles = 2);
 private unsafe static extern void GenerateLineMapAreaUnsafe(AreaUnsafe *area, int extraLines = 10, int branchQuantity = 100, int branchLength = 300);
 private unsafe static extern void GenerateSimpleDungeonAreaUnsafe(AreaUnsafe *area, int tries = 1000, int extraCorridors = 0, int minWidth = 1, int maxWidth = 100, int minHeight = 1, int maxHeight = 100);
 private unsafe static extern void GenerateBSPDungeonAreaUnsafe(AreaUnsafe *area, int minRooms, int maxRooms, int minWidth, int minHeight);
 private unsafe static extern void GenerateDrunkardWalkAreaUnsafe(AreaUnsafe *area, int iterations = 10000);
 private unsafe static extern void GenerateRandomAreaInUnsafe(AreaUnsafe *area);
 private unsafe static extern void DestroyAreaUnsafe(AreaUnsafe *area);