"""
# Animation Library
A simple 2D frame animation tool that supports loading images, automatic playback, and displaying animations.
And if you need help in the editor, use the animation_help() function to get assistance. Go ahead and try it out!

Usage Example:
    add_file_path("Path", "Animation Name")
    animation_start("Animation Name", Total Frames)
    image_show("Animation Name", x, y, Window)
Exceptions:
    NotFoundFileError - Raised when the file does not exist
    UnboundWindowError - Raised when the window is not bound
    ImageNotShowError - Raised when the image is not displayed
    NotFoundAliasError - Raised when the alias does not exist
    ValueError - Raised when the input data is inconsistent with the facts


# Animation 动画库
简易 2D 帧动画工具，支持加载图片、自动播放、显示动画
以及拥有在编辑器中寻求帮助，使用 animation_help() 函数去寻求帮助，快去试试吧！

使用示例：
    add_file_path("路径", "动画名")
    animation_start("动画名", 总帧数)
    image_show("动画名", x, y, 窗口)

异常：
    NotFoundFileError  - 文件不存在时抛出
    UnboundWindowError - 窗口未绑定时抛出
    ImageNotShowError  - 图像未显示时抛出
    NotFoundAliasError - 别名不存在时抛出
    ValueError         - 填写的数据不符合事实时抛出
"""


import os
import json
from typing import Optional, Callable, Literal
import pygame

class NotFoundFileError(Exception):
    """
    File not found in animation assets.

    动画资源中未找到文件。
    """
    ...
class UnboundWindowError(Exception):
    """
    Animation file is not bound to any window.
    
    动画文件未设置显示到哪个窗口。
    """
    ...
class ImageNotShowError(Exception):
    """
    Image is not displayed using image_show() function.
    
    未使用 image_show() 函数显示图像。
    """
    ...

class NotFoundAliasError(Exception):
    """
    Alias does not exist.
    
    别名不存在。
    """
    ...

def animation_help():
    """
    This function displays the help information of the animation library.
    Example:
    animation_help()


    这个函数会显示动画库的帮助信息。
    示例：
    animation_help()
    """
    ...

def is_image_showing(alias : str) -> bool:
    """
    This function returns whether the specified image is displayed.
    Example: 
    is_image_showing("player_walk") # Returns True or False

    Raises:
        NotFoundAliasError - The alias does not exist.



    这个函数会返回指定的图片是否已经显示。
    示例：
    is_image_showing("player_walk") # 返回 True 或 False

    引发：
        NotFoundAliasError - 别名不存在。
    """
    ...
    
def is_animation_started(alias : str) -> bool:
    """
    This function returns whether the specified animation has started playing.
    Example:
    is_animation_started("player_walk") # Returns True or False

    Raises:
        NotFoundAliasError - The alias does not exist.


    这个函数会返回指定的动画是否已经开始播放。
    示例：
    is_animation_started("player_walk") # 返回 True 或 False

    引发：
        NotFoundAliasError - 别名不存在。
    """
    ...

def get_animation_frame(alias : str) -> int:
    """
    This function returns the current frame of the specified animation.
    Example:
    get_animation_frame("player_walk") # Returns the current frame number

    Raises:
        NotFoundAliasError - The alias does not exist.


    这个函数会返回指定动画的当前帧。
    示例：
    get_animation_frame("player_walk") # 返回当前帧数

    引发：
        NotFoundAliasError - 别名不存在。
    """
    ...


def add_file_path(file_path : str, alias : str, wait : int = 10) -> None:
    """
    This function loads image paths into a dictionary and assigns an alias to them. 
    For example:
    add_file_path(r"D:\image\player_walk_1.png", "player_walk"). 
    
    Args:
        file_path: The path of the image.
        alias: The alias of the image.
        wait: The frame interval, which is the waiting time between frames (ms).

    Raises:
        NotFoundFileError - The file does not exist.
        ValueError        - The input data is less than 0.
    

    该函数将图片路径加载到字典中，并为其设置别名。
    示例：
    add_file_path(r"D:\image\player_walk_1.png", "player_walk")。

    参数：
        file_path： 图片路径
        alias： 别名
        wait： 帧间隔，在调用 animation_start() 函数时的等待时间（ms）

    引发：
        NotFoundFileError - 文件不存在。
        ValueError        - 输入的数据小于0

    """
    ...

def image_show(alias : str, x : int, y : int, window : pygame.Surface) -> None:
    """
    This function sets and displays the position of the image on the window. 
    For example:
    image_show("player_walk", 100, 100, Window) # sets the position of the image to (100, 100)

    Raises:
        NotFoundAliasError - Alias not found.
        UnboundWindowError - Window not bound.


    
    此函数用于设置并显示图像在窗口中的位置。
    例如：
    image_show("player_walk", 100, 100, Window) # 将图像位置设置为(100, 100)

    引发：
        NotFoundAliasError - 别名不存在。
        UnboundWindowError - 窗口未绑定。
    """
    ...

def animation_start(alias : str, total_frames : int, callback : Optional[Callable[[], None]] = None,  
                    _ : bool = True, file_type : str = "png") -> None:
    """
    This funcion you can use animation_start to input the alias and decide whether to append an underscore suffix. 
    If it is "True", the result will be player_walk_1.png; if "False", it will be player_walk.png. 

    Additionally, you can specify the image format. 
    For example:
    animation_start("player_walk", 10,  True, "png") # player_walk_1.png

    Secondly, you can display the animation data (.animationdata) created by the animation_engine on the window.

    Prerequisite:
    Use 'add_file_path(r"D: ...", "alias")' to enable the program to obtain the file path.

    Then:
    Run 'animation_start("player_walk")'

    There is no need to write the total_frames parameter here, as the animation_engine will automatically generate the total number of frames.

    Args:
        alias: The alias of the image.
        total_frames: Total number of frames.
        callback: Callback function.
        _: Whether to use underscore suffix (True = "name_1.png", False = "name1.png")
        file_type: Image file extension.

    Raises:
        NotFoundAliasError - The alias does not exist.

    
    你可使用本函数通过 animation_start 传入别名，并决定是否追加下划线后缀。
    若参数为“True”，生成结果为 player_walk_1.png；若为“False”，则生成 player_walk.png。

    此外，你还可以指定图片格式。
    例如：
    animation_start("player_walk", 10, True, "png") # 生成 player_walk_1.png

    其次，可以通过 animation_engine 制作出来的动画数据（.animationdata）来显示到窗口上。
    前提：
    add_file_path(r"D: ...", "alias)
    来让程序获取到这个文件路径。
    然后：
    animation_start("player_walk")
    这里不用写 total_frames 参数，因为 animation_engine 会自动生成总帧数。
    

    参数：
        alias： 别名
        total_frames： 总帧数
        callback： 回调函数
        _: 是否使用下划线后缀（True = "name_1.png", False = "name1.png"）
        file_type： 图片文件扩展名

    引发：
        NotFoundAliasError - 别名不存在。
    """
    ...

def animation_stop(alias : str) -> None:
    """
    This function stops the animation of the image. 
    For example:
    animation_stop("player_walk")
    
    However, it is important to note that the animation_start() function will restart the animation, 
    so animation_stop() should be called only after ensuring that animation_start() will not be invoked.

    Raises:
        NotFoundAliasError - The alias does not exist.

    此函数停止图像的动画。
    例如：animation_stop("player_walk")。

    然而，需要注意的是，animation_start() 函数会重新启动动画，
    因此应在确保 animation_start() 不会被调用后，再调用 animation_stop()。

    引发：
        NotFoundAliasError - 别名不存在。
    """
    ...

def set_animation_frame(alias : str, frame : int = 1) -> None:
    """
    This function sets the current frame of the animation. 
    For example:
    set_animation_frame("player_walk", 1) # sets the current frame to 1

    Args:
        alias: The alias of the animation.
        frame: The frame to be set.

    Raises:
        NotFoundAliasError - The alias does not exist.


    此函数用于设置动画的当前帧。
    例如：set_animation_frame("player_walk", 1) # 将当前帧设置为1

    参数：
        alias： 别名
        frame： 设为的帧数

    引发：
        NotFoundAliasError - 别名不存在。
    """
    ...

def set_animation_speed(alias : str, speed : int = 2) -> None:
    """

    This function sets the speed of the animation. 
    For example:
    set_animation_speed("player_walk", 2) # sets the speed to 2


    这个函数用来设置动画的速度。
    例如：
    set_animation_speed("player_walk", 2) # 设置速度为2

    """
    ...

def animation_reverse(alias : str) -> None:
    """

    This function reverses the animation of the image. 
    For example:
    animation_reverse("player_walk")


    这个函数用来反转动画。
    例如：
    animation_reverse("player_walk")

    """
    ...

def animation_reverse_back(alias : str) -> None:
    """

    This function reverses the animation of the image back to its original state. 
    For example:
    animation_reverse_back("player_walk")


    这个函数用来将动画恢复到原来的状态。
    例如：
    animation_reverse_back("player_walk")

    """
    ...

class AnimationStatus:
    """
        This class is used to get the status of the animation. 
        For example:
        status = AnimationStatus("player_walk")
        status.get_settings() # Returns the settings of the animation
        status.get_status("animation_started") # Returns whether the animation has started playing

        Args:
            alias: The alias of the animation.

        Raises:
            NotFoundAliasError - The alias does not exist.

        这个类用于获取动画的状态。
        例如：
        status = AnimationStatus("player_walk")
        status.get_settings() # 返回动画的设置
        status.get_status("animation_started") # 返回动画是否已经开始播放

        参数：
            alias： 别名

        引发：
            NotFoundAliasError - 别名不存在。
    """
    def __init__(self, alias : str) -> None: ...

    def get_settings(self) -> str:
        """

        This function returns a string in JSON format that contains most of the animation information.
        includes:
            "alias"
            "is_showing"
            "is_started"
            "frame"
            "speed"
            "is_reverse"
            "file_path"
            "file_name"
            "total_frames"
            "current_frame"
            "image_type"


        这个函数返回的是一个json格式的字符串，包含了动画的大部分信息。
        有：
            "alias"
            "is_showing"
            "is_started"
            "frame"
            "speed"
            "is_reverse"
            "file_path"
            "file_name"
            "total_frames"
            "current_frame"
            "image_type"
        """
        ...

    def get_status(self, status : Literal["animation_started", 
                                          "image_showing", 
                                          "animation_start", 
                                          "animation_end", 
                                          "animation_reverse"]) -> bool:
        """

        This function returns some status information of the current animation.
        For example:
            animation_started -> bool
            image_showing -> bool
            animation_start -> bool
            animation_end -> bool
            animation_reverse -> bool


        这个函数返回的是当前动画的一些状态信息。
        比如：
            animation_started -> bool
            image_showing -> bool
            animation_start -> bool
            animation_end -> bool
            animation_reverse -> bool

        """
        ...