"""RectTransform - 一个轻量级的 Unity-like RectTransform 实现（Python 层 MVP）

提供 anchors/pivot/anchored_position/size_delta 的数据结构和
把相对锚点映射到像素矩形的计算方法。

此实现不修改底层 C++ LUI，而是在 Python 层计算并把结果应用到
`LUIObject` 的 `left/top/width/height` 属性上。
"""
from typing import Tuple

class RectTransform(object):
    def __init__(self,
                 anchor_min=(0.5, 0.5),
                 anchor_max=(0.5, 0.5),
                 pivot=(0.5, 0.5),
                 anchored_position=(0.0, 0.0),
                 size_delta=(100.0, 30.0)):
        # 值域: anchor/pivot 为 0..1，anchored_position/size_delta 为像素
        self.anchor_min = tuple(anchor_min)
        self.anchor_max = tuple(anchor_max)
        self.pivot = tuple(pivot)
        self.anchored_position = tuple(anchored_position)
        self.size_delta = tuple(size_delta)

    def compute_pixel_rect(self, parent_rect: Tuple[float, float, float, float]):
        """
        将 RectTransform 转换为相对于父节点的像素矩形 (left, top, width, height)

        parent_rect: (parent_left, parent_top, parent_width, parent_height)
        """
        p_left, p_top, p_w, p_h = parent_rect

        a_min_x = self.anchor_min[0]
        a_min_y = self.anchor_min[1]
        a_max_x = self.anchor_max[0]
        a_max_y = self.anchor_max[1]

        # 计算锚框的像素坐标（left/top 和 right/bottom）
        anchor_left = p_left + a_min_x * p_w
        anchor_right = p_left + a_max_x * p_w
        anchor_top = p_top + a_min_y * p_h
        anchor_bottom = p_top + a_max_y * p_h

        # 宽高
        if abs(a_max_x - a_min_x) < 1e-6:
            # 固定锚点 -> 使用 size_delta.x
            width = float(self.size_delta[0])
            # anchored_position.x 表示相对于锚点框的位置（像素）
            left = anchor_left + float(self.anchored_position[0]) - self.pivot[0] * width
        else:
            # 拉伸到锚框再加上 size_delta.x
            width = (anchor_right - anchor_left) + float(self.size_delta[0])
            # anchored_position.x 表示锚框内的像素偏移
            left = anchor_left + float(self.anchored_position[0])

        if abs(a_max_y - a_min_y) < 1e-6:
            height = float(self.size_delta[1])
            # 注意：engine 中 top 增大表示向下，所以 anchored_position.y 保持像素系
            top = anchor_top + float(self.anchored_position[1]) - self.pivot[1] * height
        else:
            height = (anchor_bottom - anchor_top) + float(self.size_delta[1])
            top = anchor_top + float(self.anchored_position[1])

        return (left, top, width, height)

    def apply_to_lui(self, lui_obj, parent_rect: Tuple[float, float, float, float]):
        """计算并应用到给定的 LUIObject（设置 left/top/width/height）"""
        left, top, width, height = self.compute_pixel_rect(parent_rect)
        try:
            lui_obj.left = left
            lui_obj.top = top
            lui_obj.width = width
            lui_obj.height = height
        except Exception:
            # 忽略不能设置的属性，调用者应保证对象支持这些属性
            pass

    def to_dict(self):
        return {
            'anchor_min': tuple(self.anchor_min),
            'anchor_max': tuple(self.anchor_max),
            'pivot': tuple(self.pivot),
            'anchored_position': tuple(self.anchored_position),
            'size_delta': tuple(self.size_delta),
        }
