import pygame
import sys
import math
import random
import os

# 初始化Pygame
pygame.init()

# 屏幕设置
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("七巧板模拟")

# 颜色
COLORS = {
    'background': (240, 240, 240),
    'grid': (200, 200, 200),
    'red': (255, 99, 71),
    'blue': (70, 130, 180),
    'green': (60, 179, 113),
    'yellow': (255, 215, 0),
    'purple': (138, 43, 226),
    'orange': (255, 165, 0),
    'pink': (255, 105, 180),
}

# ========== 中文字体支持 ==========
def get_chinese_font(size):
    """获取支持中文的字体"""
    # 尝试常见的中文字体路径
    font_paths = [
        # Windows
        "C:/Windows/Fonts/simsun.ttc",      # 宋体
        "C:/Windows/Fonts/simhei.ttf",      # 黑体
        "C:/Windows/Fonts/msyh.ttc",        # 微软雅黑
        "C:/Windows/Fonts/STKAITI.TTF",     # 楷体
        # macOS
        "/System/Library/Fonts/PingFang.ttc",
        "/System/Library/Fonts/STHeiti Light.ttc",
        # Linux
        "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc",
        "/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc",
        "/usr/share/fonts/truetype/arphic/uming.ttc",
    ]
    
    for path in font_paths:
        if os.path.exists(path):
            try:
                return pygame.font.Font(path, size)
            except:
                continue
    
    # 如果都找不到，使用默认字体（可能不支持中文，但不会报错）
    return pygame.font.Font(None, size)

# 创建字体对象
FONT_SMALL = get_chinese_font(20)
FONT_MEDIUM = get_chinese_font(28)
FONT_LARGE = get_chinese_font(36)

# 板块形状定义（相对坐标，后续会缩放）
# 每个形状由顶点列表定义（逆时针顺序）
SHAPES = {
    '大三角形1': {
        'color': COLORS['red'],
        'points': [(0, 0), (1, 0), (0.5, 0.5)],
        'offset': (0, 0)
    },
    '大三角形2': {
        'color': COLORS['blue'],
        'points': [(0, 0), (1, 0), (0.5, 0.5)],
        'offset': (1.5, 0)
    },
    '中三角形': {
        'color': COLORS['green'],
        'points': [(0, 0), (1, 0), (0.5, 0.5)],
        'offset': (0, 1.5)
    },
    '小三角形1': {
        'color': COLORS['yellow'],
        'points': [(0, 0), (0.5, 0), (0.25, 0.25)],
        'offset': (2, 1.5)
    },
    '小三角形2': {
        'color': COLORS['purple'],
        'points': [(0, 0), (0.5, 0), (0.25, 0.25)],
        'offset': (3, 0)
    },
    '正方形': {
        'color': COLORS['orange'],
        'points': [(0, 0), (0.4, 0), (0.4, 0.4), (0, 0.4)],
        'offset': (3, 2.5)
    },
    '平行四边形': {
        'color': COLORS['pink'],
        'points': [(0, 0), (0.6, 0), (0.4, 0.4), (-0.2, 0.4)],
        'offset': (1.5, 3)
    }
}

class TangramPiece:
    """七巧板块类"""
    def __init__(self, name, color, points, offset, scale=80):
        self.name = name
        self.color = color
        self.scale = scale
        self.angle = 0
        self.dragging = False
        self.drag_offset = (0, 0)
        
        # 初始位置（像素坐标）
        self.pos = (offset[0] * scale + 100, offset[1] * scale + 50)
        
        # 原始顶点（归一化坐标）
        self.original_points = points
        self.original_center = self._calculate_center(points)
        
        # 当前顶点（世界坐标）
        self.world_points = []
        self._update_points()
    
    def _calculate_center(self, points):
        """计算多边形中心"""
        cx = sum(p[0] for p in points) / len(points)
        cy = sum(p[1] for p in points) / len(points)
        return (cx, cy)
    
    def _update_points(self):
        """更新世界坐标顶点"""
        world_pts = []
        for x, y in self.original_points:
            dx = x - self.original_center[0]
            dy = y - self.original_center[1]
            
            dx *= self.scale
            dy *= self.scale
            
            angle_rad = math.radians(self.angle)
            cos_a = math.cos(angle_rad)
            sin_a = math.sin(angle_rad)
            rx = dx * cos_a - dy * sin_a
            ry = dx * sin_a + dy * cos_a
            
            wx = self.pos[0] + rx
            wy = self.pos[1] + ry
            world_pts.append((wx, wy))
        
        self.world_points = world_pts
    
    def draw(self, surface):
        """绘制板块"""
        if len(self.world_points) >= 3:
            pygame.draw.polygon(surface, self.color, self.world_points)
            pygame.draw.polygon(surface, (50, 50, 50), self.world_points, 2)
    
    def contains_point(self, point):
        """检测点是否在板块内（使用射线法）"""
        x, y = point
        inside = False
        n = len(self.world_points)
        
        for i in range(n):
            x1, y1 = self.world_points[i]
            x2, y2 = self.world_points[(i + 1) % n]
            
            if ((y1 > y) != (y2 > y)):
                x_intersect = x1 + (x2 - x1) * (y - y1) / (y2 - y1)
                if x < x_intersect:
                    inside = not inside
        
        return inside
    
    def set_position(self, pos):
        """设置位置"""
        self.pos = pos
        self._update_points()
    
    def move(self, delta):
        """移动板块"""
        self.pos = (self.pos[0] + delta[0], self.pos[1] + delta[1])
        self._update_points()
    
    def rotate(self, angle_delta):
        """旋转板块"""
        self.angle = (self.angle + angle_delta) % 360
        self._update_points()
    
    def get_bounding_box(self):
        """获取边界框"""
        if not self.world_points:
            return (0, 0, 0, 0)
        xs = [p[0] for p in self.world_points]
        ys = [p[1] for p in self.world_points]
        return (min(xs), min(ys), max(xs), max(ys))

class TangramSimulation:
    """七巧板模拟主类"""
    def __init__(self):
        self.pieces = []
        self.selected_piece = None
        self.dragging_piece = None
        self.show_help = True
        
        # 初始化板块
        scale = 70
        for name, data in SHAPES.items():
            offset_x = data['offset'][0] * scale + random.randint(-10, 10)
            offset_y = data['offset'][1] * scale + random.randint(-10, 10)
            
            piece = TangramPiece(
                name=name,
                color=data['color'],
                points=data['points'],
                offset=(offset_x/scale, offset_y/scale),
                scale=scale
            )
            self.pieces.append(piece)
    
    def handle_event(self, event):
        """处理事件"""
        if event.type == pygame.QUIT:
            return False
        
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                for piece in reversed(self.pieces):
                    if piece.contains_point(event.pos):
                        self.selected_piece = piece
                        self.dragging_piece = piece
                        piece.dragging = True
                        piece.drag_offset = (piece.pos[0] - event.pos[0], 
                                            piece.pos[1] - event.pos[1])
                        self.pieces.remove(piece)
                        self.pieces.append(piece)
                        break
            elif event.button == 4:
                if self.selected_piece:
                    self.selected_piece.rotate(15)
            elif event.button == 5:
                if self.selected_piece:
                    self.selected_piece.rotate(-15)
        
        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                if self.dragging_piece:
                    self.dragging_piece.dragging = False
                    self.dragging_piece = None
        
        elif event.type == pygame.MOUSEMOTION:
            if self.dragging_piece:
                new_pos = (event.pos[0] + self.dragging_piece.drag_offset[0],
                          event.pos[1] + self.dragging_piece.drag_offset[1])
                self.dragging_piece.set_position(new_pos)
        
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_r and self.selected_piece:
                self.selected_piece.angle = 0
                self.selected_piece._update_points()
            elif event.key == pygame.K_h:
                self.show_help = not self.show_help
            elif event.key == pygame.K_SPACE:
                self.reset_pieces()
        
        return True
    
    def reset_pieces(self):
        """重置所有板块到初始位置"""
        scale = 70
        for name, data in SHAPES.items():
            piece = next((p for p in self.pieces if p.name == name), None)
            if piece:
                offset_x = data['offset'][0] * scale + 100
                offset_y = data['offset'][1] * scale + 50
                piece.set_position((offset_x, offset_y))
                piece.angle = 0
                piece._update_points()
    
    def draw(self, surface):
        """绘制所有内容"""
        surface.fill(COLORS['background'])
        
        # 绘制网格参考线
        for x in range(0, WINDOW_WIDTH, 50):
            pygame.draw.line(surface, COLORS['grid'], (x, 0), (x, WINDOW_HEIGHT), 1)
        for y in range(0, WINDOW_HEIGHT, 50):
            pygame.draw.line(surface, COLORS['grid'], (0, y), (WINDOW_WIDTH, y), 1)
        
        # 绘制所有板块
        for piece in self.pieces:
            piece.draw(surface)
        
        # 显示选中板块信息（使用中文字体）
        if self.selected_piece:
            info_text = f"选中: {self.selected_piece.name} | 角度: {self.selected_piece.angle:.0f}°"
            info_surf = FONT_MEDIUM.render(info_text, True, (50, 50, 50))
            surface.blit(info_surf, (10, 10))
        
        # 显示帮助信息（使用中文字体）
        if self.show_help:
            help_lines = [
                "七巧板模拟 - 操作说明",
                "点击拖拽: 移动板块",
                "滚轮: 旋转选中板块",
                "R键: 重置选中板块旋转",
                "空格键: 重置所有板块位置",
                "H键: 切换帮助显示",
                "",
                "提示: 点击选中板块后即可操作"
            ]
            y_offset = WINDOW_HEIGHT - len(help_lines) * 28 - 10
            for line in help_lines:
                text_surf = FONT_SMALL.render(line, True, (80, 80, 80))
                surface.blit(text_surf, (10, y_offset))
                y_offset += 28
        
        # 标题（使用中文字体）
        title = FONT_LARGE.render("七巧板模拟", True, (30, 30, 30))
        surface.blit(title, (WINDOW_WIDTH - 180, 10))

def main():
    clock = pygame.time.Clock()
    sim = TangramSimulation()
    running = True
    
    while running:
        for event in pygame.event.get():
            if not sim.handle_event(event):
                running = False
        
        sim.draw(screen)
        pygame.display.flip()
        clock.tick(60)
    
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()