import typing
from TransformsAI.Animo.Data.Database.Tables import ITableItem_1
from System.Collections.Generic import List_1, Dictionary_2
from TransformsAI.Animo.Learning.Observations import AffinityData
from TransformsAI.Animo.Learning.Rewards import NewReward, RewardIds, Reward
from TransformsAI.Animo.Objects import TypeIds, Character
from System import Array_1, IEquatable_1
from TransformsAI.Animo.Grid import VoxelGrid

class AgentData(ITableItem_1[int]):
    def __init__(self) -> None: ...
    @property
    def AffinitySlots(self) -> List_1[AffinityData]: ...
    @AffinitySlots.setter
    def AffinitySlots(self, value: List_1[AffinityData]) -> List_1[AffinityData]: ...
    @property
    def CharacterPoints(self) -> Dictionary_2[int, int]: ...
    @CharacterPoints.setter
    def CharacterPoints(self, value: Dictionary_2[int, int]) -> Dictionary_2[int, int]: ...
    @property
    def CheckpointTimestamps(self) -> List_1[int]: ...
    @CheckpointTimestamps.setter
    def CheckpointTimestamps(self, value: List_1[int]) -> List_1[int]: ...
    @property
    def CurrentRewards(self) -> List_1[NewReward]: ...
    @CurrentRewards.setter
    def CurrentRewards(self, value: List_1[NewReward]) -> List_1[NewReward]: ...
    @property
    def Id(self) -> int: ...
    @Id.setter
    def Id(self, value: int) -> int: ...
    @property
    def ItemPoints(self) -> Dictionary_2[TypeIds, int]: ...
    @ItemPoints.setter
    def ItemPoints(self, value: Dictionary_2[TypeIds, int]) -> Dictionary_2[TypeIds, int]: ...
    @property
    def SelectedCheckpointTimestamp(self) -> int: ...
    @SelectedCheckpointTimestamp.setter
    def SelectedCheckpointTimestamp(self, value: int) -> int: ...
    @property
    def VisionMask(self) -> Array_1[int]: ...
    @VisionMask.setter
    def VisionMask(self, value: Array_1[int]) -> Array_1[int]: ...
    def AddAndSelectCheckpoint(self, cp: CheckpointData) -> None: ...
    def ApplyToCharacter(self, c: Character) -> None: ...
    def GetAffinityData(self, slotNum: int) -> typing.Optional[AffinityData]: ...
    def RecalculateAffinitySlots(self) -> None: ...


class CheckpointData(ITableItem_1[CheckpointId]):
    def __init__(self) -> None: ...
    @property
    def AgentId(self) -> int: ...
    @AgentId.setter
    def AgentId(self, value: int) -> int: ...
    @property
    def EpisodeCount(self) -> int: ...
    @property
    def Episodes(self) -> Array_1[EpisodeData]: ...
    @Episodes.setter
    def Episodes(self, value: Array_1[EpisodeData]) -> Array_1[EpisodeData]: ...
    @property
    def Id(self) -> CheckpointId: ...
    @property
    def IsValid(self) -> bool: ...
    @IsValid.setter
    def IsValid(self, value: bool) -> bool: ...
    @property
    def MeanReward(self) -> float: ...
    @MeanReward.setter
    def MeanReward(self, value: float) -> float: ...
    @property
    def OccurrencesByIndex(self) -> Array_1[int]: ...
    @OccurrencesByIndex.setter
    def OccurrencesByIndex(self, value: Array_1[int]) -> Array_1[int]: ...
    @property
    def RewardFunctions(self) -> List_1[NewReward]: ...
    @RewardFunctions.setter
    def RewardFunctions(self, value: List_1[NewReward]) -> List_1[NewReward]: ...
    @property
    def RewardOccurrences(self) -> Array_1[RewardOccurrenceData]: ...
    @RewardOccurrences.setter
    def RewardOccurrences(self, value: Array_1[RewardOccurrenceData]) -> Array_1[RewardOccurrenceData]: ...
    @property
    def Timestamp(self) -> int: ...
    @Timestamp.setter
    def Timestamp(self, value: int) -> int: ...
    @property
    def TrainingSessionId(self) -> str: ...
    @TrainingSessionId.setter
    def TrainingSessionId(self, value: str) -> str: ...
    @staticmethod
    def CreateDefault(agentId: int) -> CheckpointData: ...
    def GetMeanReward(self, meanType: CheckpointData.MeanTypes = ...) -> float: ...
    def MeanOccurrencesByIndex(self, i: int) -> float: ...
    def MeanRewardByIndex(self, i: int) -> float: ...

    class MeanTypes(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:
        All : CheckpointData.MeanTypes # 0
        Positive : CheckpointData.MeanTypes # 1
        Negative : CheckpointData.MeanTypes # 2



class CheckpointId(IEquatable_1[CheckpointId]):
    def __init__(self, agentId: int, timestamp: int) -> None: ...
    AgentId : int
    Timestamp : int
    def GetHashCode(self) -> int: ...
    def __eq__(self, left: CheckpointId, right: CheckpointId) -> bool: ...
    def __ne__(self, left: CheckpointId, right: CheckpointId) -> bool: ...
    def ToString(self) -> str: ...
    # Skipped Equals due to it being static, abstract and generic.

    Equals : Equals_MethodGroup
    class Equals_MethodGroup:
        @typing.overload
        def __call__(self, other: CheckpointId) -> bool:...
        @typing.overload
        def __call__(self, obj: typing.Any) -> bool:...



class EpisodeData:
    def __init__(self) -> None: ...
    @property
    def OccurrencesByIndex(self) -> Array_1[int]: ...
    @OccurrencesByIndex.setter
    def OccurrencesByIndex(self, value: Array_1[int]) -> Array_1[int]: ...
    @property
    def StepCount(self) -> int: ...
    @StepCount.setter
    def StepCount(self, value: int) -> int: ...
    @property
    def TotalReward(self) -> float: ...
    @TotalReward.setter
    def TotalReward(self, value: float) -> float: ...


class LevelData(ITableItem_1[str]):
    def __init__(self) -> None: ...
    @property
    def Id(self) -> str: ...
    @Id.setter
    def Id(self, value: str) -> str: ...
    @property
    def SavedGrid(self) -> VoxelGrid: ...
    @SavedGrid.setter
    def SavedGrid(self, value: VoxelGrid) -> VoxelGrid: ...


class RewardFunctionData:
    @typing.overload
    def __init__(self, functionId: RewardIds, targetTypeId: TypeIds, scale: float) -> None: ...
    @typing.overload
    def __init__(self, reward: Reward, scale: typing.Optional[float] = ...) -> None: ...
    @property
    def FunctionId(self) -> RewardIds: ...
    @FunctionId.setter
    def FunctionId(self, value: RewardIds) -> RewardIds: ...
    @property
    def Reward(self) -> Reward: ...
    @property
    def Scale(self) -> float: ...
    @Scale.setter
    def Scale(self, value: float) -> float: ...
    @property
    def Signature(self) -> str: ...
    @property
    def TargetTypeId(self) -> TypeIds: ...
    @TargetTypeId.setter
    def TargetTypeId(self, value: TypeIds) -> TypeIds: ...


class RewardOccurrenceData:
    @property
    def Episode(self) -> int: ...
    @Episode.setter
    def Episode(self, value: int) -> int: ...
    @property
    def RewardIndex(self) -> int: ...
    @RewardIndex.setter
    def RewardIndex(self, value: int) -> int: ...
    @property
    def Step(self) -> int: ...
    @Step.setter
    def Step(self, value: int) -> int: ...

