import typing, abc
from TransformsAI.Animo.Objects.Items import ObjectInfo
from TransformsAI.Animo.Numerics import Vector3Int, Vector2Int
from System import Guid, IEquatable_1, InvalidOperationException, Exception, Random, Func_1, Predicate_1, Func_3
from TransformsAI.Animo.Objects import TypeIds, Character, Resolution
from TransformsAI.Animo.Simulation.Intents import Intent
from System.Collections.Generic import List_1, IEnumerable_1, Dictionary_2
from System.Collections import IDictionary
from System.Reflection import MethodBase
from TransformsAI.Animo.Simulation.Events import SimulationEvent
from TransformsAI.Animo.Simulation import EndCondition

class GridObject(abc.ABC):
    Info : ObjectInfo
    @property
    def CanBeOnGrid(self) -> bool: ...
    @property
    def Direction(self) -> Vector3Int: ...
    @property
    def Grid(self) -> VoxelGrid: ...
    @Grid.setter
    def Grid(self, value: VoxelGrid) -> VoxelGrid: ...
    @property
    def InstanceId(self) -> Guid: ...
    @InstanceId.setter
    def InstanceId(self, value: Guid) -> Guid: ...
    @property
    def IsDestroyed(self) -> bool: ...
    @IsDestroyed.setter
    def IsDestroyed(self, value: bool) -> bool: ...
    @property
    def IsOnGrid(self) -> bool: ...
    @property
    def Position(self) -> Vector3Int: ...
    @property
    def Transform(self) -> GridTransform: ...
    @property
    def TransformOnGrid(self) -> typing.Optional[GridTransform]: ...
    @TransformOnGrid.setter
    def TransformOnGrid(self, value: typing.Optional[GridTransform]) -> typing.Optional[GridTransform]: ...
    @property
    def TypeId(self) -> TypeIds: ...
    @property
    def VariantId(self) -> int: ...
    @VariantId.setter
    def VariantId(self, value: int) -> int: ...
    def CalculateIntent(self) -> Intent: ...
    def CanChangeGroundPosition(self, oldGroundPosition: typing.Optional[Vector3Int], newGroundPosition: typing.Optional[Vector3Int], occupiers: List_1[GridObject], maxHeight: int) -> bool: ...
    def Destroy(self) -> None: ...
    def ExecuteIntent(self, intent: Intent, toRecalculate: List_1[GridObject]) -> None: ...
    def HandleConflict(self, conflicts: IEnumerable_1[Intent], intent: Intent, toRecalculate: List_1[GridObject]) -> None: ...
    def OnBurn(self, source: GridObject, causer: Character) -> bool: ...
    def OnSlashed(self, source: GridObject, causer: Character) -> bool: ...
    def OnSplashed(self, source: GridObject, causer: Character) -> bool: ...
    def OnStepPerformed(self) -> None: ...
    def OnTransformUpdate(self, oldTransform: GridTransform, newTransform: GridTransform) -> None: ...
    def Reset(self) -> None: ...
    def TrySetDirection(self, newDirection: Vector3Int) -> bool: ...
    def TrySetPosition(self, newPosition: Vector3Int) -> bool: ...
    # Skipped TrySetTransform due to it being static, abstract and generic.

    TrySetTransform : TrySetTransform_MethodGroup
    class TrySetTransform_MethodGroup:
        @typing.overload
        def __call__(self, transform: GridTransform) -> bool:...
        @typing.overload
        def __call__(self, newPosition: Vector3Int, newDirection: Vector3Int) -> bool:...



class GridTransform(IEquatable_1[GridTransform]):
    def __init__(self, position: Vector3Int, direction: Vector3Int) -> None: ...
    @property
    def Back(self) -> Vector3Int: ...
    @property
    def Direction(self) -> Vector3Int: ...
    @property
    def Forward(self) -> Vector3Int: ...
    @property
    def IsValid(self) -> bool: ...
    @property
    def Left(self) -> Vector3Int: ...
    @property
    def Position(self) -> Vector3Int: ...
    @property
    def Right(self) -> Vector3Int: ...
    def Equals(self, other: GridTransform) -> bool: ...
    def GetAbsoluteDirection(self, relativeDirection: Vector3Int) -> Vector3Int: ...
    def GetAbsolutePosition(self, relativePosition: Vector3Int) -> Vector3Int: ...
    def GetRelativeDirection(self, absoluteDirection: Vector3Int) -> Vector3Int: ...
    def GetRelativePosition(self, absolutePosition: Vector3Int) -> Vector3Int: ...
    def ToString(self) -> str: ...
    def WithDirection(self, direction: Vector3Int) -> GridTransform: ...
    def WithPosition(self, position: Vector3Int) -> GridTransform: ...


class GroundMaterials(typing.SupportsInt):
    @typing.overload
    def __init__(self, value : int) -> None: ...
    @typing.overload
    def __init__(self, value : int, force_if_true: bool) -> None: ...
    def __int__(self) -> int: ...
    
    # Values:
    None_ : GroundMaterials # 0
    ShallowWater : GroundMaterials # 1
    DeepWater : GroundMaterials # 2


class GroundMaterialsExtensions(abc.ABC):
    @staticmethod
    def IsWater(mat: GroundMaterials) -> bool: ...


class OffGridException(InvalidOperationException):
    def __init__(self) -> None: ...
    @property
    def Data(self) -> IDictionary: ...
    @property
    def HelpLink(self) -> str: ...
    @HelpLink.setter
    def HelpLink(self, value: str) -> str: ...
    @property
    def HResult(self) -> int: ...
    @HResult.setter
    def HResult(self, value: int) -> int: ...
    @property
    def InnerException(self) -> Exception: ...
    @property
    def Message(self) -> str: ...
    @property
    def Source(self) -> str: ...
    @Source.setter
    def Source(self, value: str) -> str: ...
    @property
    def StackTrace(self) -> str: ...
    @property
    def TargetSite(self) -> MethodBase: ...


class VoxelGrid:
    def __init__(self, size: Vector3Int) -> None: ...
    PendingEvents : List_1[SimulationEvent]
    WaterLine : int
    @property
    def Characters(self) -> Dictionary_2.ValueCollection_2[int, Character]: ...
    @property
    def Depth(self) -> int: ...
    @property
    def EndConditions(self) -> EndCondition: ...
    @EndConditions.setter
    def EndConditions(self, value: EndCondition) -> EndCondition: ...
    @property
    def MaxHeight(self) -> int: ...
    @MaxHeight.setter
    def MaxHeight(self, value: int) -> int: ...
    @property
    def Objects(self) -> Dictionary_2.ValueCollection_2[Guid, GridObject]: ...
    @property
    def Random(self) -> Random: ...
    @property
    def Size(self) -> Vector3Int: ...
    @Size.setter
    def Size(self, value: Vector3Int) -> Vector3Int: ...
    @property
    def Width(self) -> int: ...
    def AddBlockAt(self, targetPosition: Vector3Int) -> bool: ...
    def AddResolution(self, resolution: Resolution) -> None: ...
    def AllGridObjectsAt(self, position: Vector3Int, result: List_1[GridObject]) -> int: ...
    def CanChangeGroundPosition(self, oldGroundPosition: typing.Optional[Vector3Int], newGroundPosition: typing.Optional[Vector3Int], occupiers: List_1[GridObject]) -> bool: ...
    @staticmethod
    def CanOverlap(a: TypeIds, b: TypeIds) -> bool: ...
    def Contains(self, obj: GridObject) -> bool: ...
    def Copy(self) -> VoxelGrid: ...
    @staticmethod
    def CreateDefaultGrid(gridSize: Vector3Int, platformRadius: typing.Optional[int] = ...) -> VoxelGrid: ...
    def FindClosestGroundMaterial(self, position: Vector3Int, material: GroundMaterials) -> typing.Optional[Vector3Int]: ...
    @staticmethod
    def FromJson(json: str) -> VoxelGrid: ...
    def GetCharacter(self, characterId: typing.Optional[int]) -> Character: ...
    def GetFloorOrZeroHeightPosition(self, position: Vector3Int) -> Vector3Int: ...
    def GetFloorPosition(self, position: Vector3Int) -> typing.Optional[Vector3Int]: ...
    def GetGroundMaterialAt(self, position2d: Vector3Int) -> GroundMaterials: ...
    def GetHighestBlock(self, position: Vector3Int) -> typing.Optional[Vector3Int]: ...
    def HasBlockAt(self, targetPosition: Vector3Int) -> bool: ...
    def HasWaterAt(self, position3d: Vector3Int) -> bool: ...
    def IsInRange(self, gridPosition: Vector3Int) -> bool: ...
    def PlaceOff(self, gridObject: GridObject) -> None: ...
    def Remove(self, gridObject: GridObject) -> bool: ...
    def RemoveBlockAt(self, targetPosition: Vector3Int) -> bool: ...
    def ReportEvent(self, characterEventArgs: SimulationEvent) -> None: ...
    def Resize(self, newSize: Vector3Int) -> None: ...
    def SetFloorHeightAtPosition(self, pos2D: Vector3Int, targetHeight: typing.Optional[int]) -> bool: ...
    def SetRandomSource(self, source: Func_1[Random]) -> None: ...
    def SetWaterHeight(self, position: Vector3Int, height: int) -> None: ...
    # Skipped CanPlace due to it being static, abstract and generic.

    CanPlace : CanPlace_MethodGroup
    class CanPlace_MethodGroup:
        @typing.overload
        def __call__(self, existingObject: GridObject, gridPosition: Vector3Int) -> bool:...
        @typing.overload
        def __call__(self, objectType: TypeIds, gridPosition: Vector3Int, objToIgnore: GridObject = ...) -> bool:...

    # Skipped FindClosestAt due to it being static, abstract and generic.

    FindClosestAt : FindClosestAt_MethodGroup
    class FindClosestAt_MethodGroup:
        def __getitem__(self, t:typing.Type[FindClosestAt_1_T1]) -> FindClosestAt_1[FindClosestAt_1_T1]: ...

        FindClosestAt_1_T1 = typing.TypeVar('FindClosestAt_1_T1')
        class FindClosestAt_1(typing.Generic[FindClosestAt_1_T1]):
            FindClosestAt_1_T = VoxelGrid.FindClosestAt_MethodGroup.FindClosestAt_1_T1
            def __call__(self, position: Vector3Int, predicate: Predicate_1[FindClosestAt_1_T] = ...) -> FindClosestAt_1_T:...

        def __call__(self, position: Vector3Int, typeId: TypeIds, ignored: GridObject = ..., characterId: typing.Optional[int] = ...) -> GridObject:...

    # Skipped FindObject due to it being static, abstract and generic.

    FindObject : FindObject_MethodGroup
    class FindObject_MethodGroup:
        def __getitem__(self, t:typing.Type[FindObject_1_T1]) -> FindObject_1[FindObject_1_T1]: ...

        FindObject_1_T1 = typing.TypeVar('FindObject_1_T1')
        class FindObject_1(typing.Generic[FindObject_1_T1]):
            FindObject_1_T = VoxelGrid.FindObject_MethodGroup.FindObject_1_T1
            def __call__(self, filter: Predicate_1[FindObject_1_T] = ...) -> FindObject_1_T:...

        def __call__(self, filter: Predicate_1[GridObject] = ...) -> GridObject:...

    # Skipped GetObjectAt due to it being static, abstract and generic.

    GetObjectAt : GetObjectAt_MethodGroup
    class GetObjectAt_MethodGroup:
        def __getitem__(self, t:typing.Type[GetObjectAt_1_T1]) -> GetObjectAt_1[GetObjectAt_1_T1]: ...

        GetObjectAt_1_T1 = typing.TypeVar('GetObjectAt_1_T1')
        class GetObjectAt_1(typing.Generic[GetObjectAt_1_T1]):
            GetObjectAt_1_T = VoxelGrid.GetObjectAt_MethodGroup.GetObjectAt_1_T1
            def __call__(self, gridPosition: Vector3Int, exactYMatch: bool, filter: Predicate_1[GetObjectAt_1_T] = ...) -> GetObjectAt_1_T:...

        @typing.overload
        def __call__(self, gridPosition: Vector3Int, exactYMatch: bool, filter: Predicate_1[GridObject] = ...) -> GridObject:...
        @typing.overload
        def __call__(self, gridPosition: Vector3Int, exactYMatch: bool, typeFilter: TypeIds) -> GridObject:...

    # Skipped GetObjectById due to it being static, abstract and generic.

    GetObjectById : GetObjectById_MethodGroup
    class GetObjectById_MethodGroup:
        def __getitem__(self, t:typing.Type[GetObjectById_1_T1]) -> GetObjectById_1[GetObjectById_1_T1]: ...

        GetObjectById_1_T1 = typing.TypeVar('GetObjectById_1_T1')
        class GetObjectById_1(typing.Generic[GetObjectById_1_T1]):
            GetObjectById_1_T = VoxelGrid.GetObjectById_MethodGroup.GetObjectById_1_T1
            def __call__(self, instanceId: typing.Optional[Guid]) -> GetObjectById_1_T:...

        def __call__(self, instanceId: Guid) -> GridObject:...

    # Skipped GetObjects due to it being static, abstract and generic.

    GetObjects : GetObjects_MethodGroup
    class GetObjects_MethodGroup:
        def __getitem__(self, t:typing.Type[GetObjects_1_T1]) -> GetObjects_1[GetObjects_1_T1]: ...

        GetObjects_1_T1 = typing.TypeVar('GetObjects_1_T1')
        class GetObjects_1(typing.Generic[GetObjects_1_T1]):
            GetObjects_1_T = VoxelGrid.GetObjects_MethodGroup.GetObjects_1_T1
            def __call__(self, outResult: List_1[GetObjects_1_T] = ..., filter: Predicate_1[GetObjects_1_T] = ...) -> int:...

        @typing.overload
        def __call__(self, outResult: List_1[GridObject] = ..., filter: Predicate_1[GridObject] = ...) -> int:...
        @typing.overload
        def __call__(self, typeFilter: TypeIds, outResult: List_1[GridObject] = ...) -> int:...

    # Skipped GetObjectsAt due to it being static, abstract and generic.

    GetObjectsAt : GetObjectsAt_MethodGroup
    class GetObjectsAt_MethodGroup:
        def __getitem__(self, t:typing.Type[GetObjectsAt_1_T1]) -> GetObjectsAt_1[GetObjectsAt_1_T1]: ...

        GetObjectsAt_1_T1 = typing.TypeVar('GetObjectsAt_1_T1')
        class GetObjectsAt_1(typing.Generic[GetObjectsAt_1_T1]):
            GetObjectsAt_1_T = VoxelGrid.GetObjectsAt_MethodGroup.GetObjectsAt_1_T1
            def __call__(self, gridPosition: Vector3Int, outResult: List_1[GetObjectsAt_1_T], exactYMatch: bool, filter: Predicate_1[GetObjectsAt_1_T] = ...) -> int:...

        def __call__(self, gridPosition: Vector3Int, outResult: List_1[GridObject], exactYMatch: bool, filter: Predicate_1[GridObject] = ...) -> int:...

    # Skipped PlaceOn due to it being static, abstract and generic.

    PlaceOn : PlaceOn_MethodGroup
    class PlaceOn_MethodGroup:
        @typing.overload
        def __call__(self, type: TypeIds, position: Vector3Int) -> GridObject:...
        @typing.overload
        def __call__(self, type: TypeIds, transform: GridTransform, forceHeight: bool = ...) -> GridObject:...
        @typing.overload
        def __call__(self, gridObject: GridObject, position: Vector3Int, forceHeight: bool = ...) -> bool:...
        @typing.overload
        def __call__(self, gridObject: GridObject, transform: GridTransform, forceHeight: bool = ...) -> bool:...

    # Skipped ToJson due to it being static, abstract and generic.

    ToJson : ToJson_MethodGroup
    class ToJson_MethodGroup:
        @typing.overload
        def __call__(self) -> str:...
        @typing.overload
        def __call__(self, grid: VoxelGrid) -> str:...

    # Skipped TryMoveObject due to it being static, abstract and generic.

    TryMoveObject : TryMoveObject_MethodGroup
    class TryMoveObject_MethodGroup:
        @typing.overload
        def __call__(self, gridObject: GridObject, position: Vector3Int) -> bool:...
        @typing.overload
        def __call__(self, gridObject: GridObject, transform: GridTransform) -> bool:...



class VoxelGridSearch:
    def __init__(self) -> None: ...
    @property
    def VisitedCount(self) -> int: ...
    def Clear(self) -> None: ...
    def DidVisit(self, goal: Vector2Int) -> bool: ...
    def GetPathTo(self, goal: Vector2Int, path: List_1[Vector2Int]) -> None: ...
    @staticmethod
    def IsWalkable(from_: Vector3Int, to: Vector3Int) -> bool: ...
    def Search(self, graph: VoxelGrid, start: Vector2Int, enqueueCheck: Func_3[Vector3Int, Vector3Int, bool], completionCheck: Func_3[typing.Any, Vector3Int, bool] = ..., completionCheckData: typing.Any = ...) -> None: ...

