using System;
namespace NHSE.Core;
public sealed record MapMutator
{
public MapViewState View { get; init; } = new();
public required MapTileManager Manager { get; init; }
// Mutability State Tracking
public uint ItemLayerIndex => (uint)View.ItemLayerIndex;
public LayerFieldItem CurrentLayer => ItemLayerIndex == 0 ? Manager.FieldItems.Layer0 : Manager.FieldItems.Layer1;
public ILayerFieldItemFlag CurrentLayerFlags => ItemLayerIndex == 0 ? Manager.LayerItemFlag0 : Manager.LayerItemFlag1;
///
public int ModifyFieldItems(Func action, in bool wholeMap)
=> ModifyFieldItems(action, wholeMap, CurrentLayer);
///
public int ReplaceFieldItems(Item oldItem, Item newItem, in bool wholeMap)
=> ReplaceFieldItems(oldItem, newItem, wholeMap, CurrentLayer);
///
/// Modifies field items in the specified using the provided function.
///
/// Range selector (xmin, ymin, width, height) to use.
/// If true, the modification is applied across the entire map; otherwise, only within the current view.
/// The layer field item to perform the modification on.
/// The number of items modified.
public int ModifyFieldItems(Func action, in bool wholeMap, LayerFieldItem layerField)
{
int xMin, yMin, width, height;
if (wholeMap)
{
(xMin, yMin) = (0, 0);
var info = layerField.TileInfo;
(width, height) = info.DimTotal;
}
else
{
// Convert absolute to relative coordinates
(xMin, yMin) = Manager.ConfigItems.GetCoordinatesRelative(View.X, View.Y);
if (!Manager.ConfigItems.IsCoordinateValidRelative(xMin, yMin))
return 0;
var info = layerField.TileInfo;
(width, height) = info.DimAcre;
}
return action(xMin, yMin, width, height);
}
///
/// Replaces all instances of with in the specified .
///
/// Item to be replaced.
/// Item to replace with.
/// If true, the replacement is done across the entire map; otherwise, only within the current view.
/// The layer field item to perform the replacement on.
/// The number of items replaced.
private int ReplaceFieldItems(Item oldItem, Item newItem, bool wholeMap, LayerFieldItem layerField)
{
int xMin, yMin, width, height;
if (wholeMap)
{
(xMin, yMin) = (0, 0);
var info = layerField.TileInfo;
(width, height) = info.DimTotal;
}
else
{
// Convert absolute to relative coordinates
(xMin, yMin) = Manager.ConfigItems.GetCoordinatesRelative(View.X, View.Y);
if (!Manager.ConfigItems.IsCoordinateValidRelative(xMin, yMin))
return 0;
var info = layerField.TileInfo;
(width, height) = info.DimAcre;
}
return layerField.ReplaceAll(oldItem, newItem, xMin, yMin, width, height);
}
///
/// Creates a from the provided file.
///
/// The save file containing the data used to initialize the MapMutator. Cannot be null.
/// A MapMutator instance populated with data from the provided save file.
public static MapMutator FromSaveFile(MainSave sav)
=> new() { Manager = MapTileManagerUtil.FromSaveFile(sav) };
///
/// Creates a separate view-mutator with shared map objects.
///
public MapMutator CreateCopy() => this with
{
View = View with { },
};
}