import pygame
import math
import random

# 初始化 Pygame
pygame.init()
WIDTH, HEIGHT = 1000, 700
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("3D 唐诗三百首 - Pygame 版")
clock = pygame.time.Clock()

# 颜色定义
WHITE = (255, 255, 255)
GOLD = (255, 215, 0)
CYAN = (0, 255, 255)
BG_COLOR = (20, 20, 30)

# 模拟数据
POEMS = [
    {"title": "静夜思", "author": "李白", "content": "床前明月光，疑是地上霜。举头望明月，低头思故乡。"},
    {"title": "春晓", "author": "孟浩然", "content": "春眠不觉晓，处处闻啼鸟。夜来风雨声，花落知多少。"},
    {"title": "登鹳雀楼", "author": "王之涣", "content": "白日依山尽，黄河入海流。欲穷千里目，更上一层楼。"},
    {"title": "江雪", "author": "柳宗元", "content": "千山鸟飞绝，万径人踪灭。孤舟蓑笠翁，独钓寒江雪。"},
    {"title": "相思", "author": "王维", "content": "红豆生南国，春来发几枝。愿君多采撷，此物最相思。"},
    {"title": "咏鹅", "author": "骆宾王", "content": "鹅鹅鹅，曲项向天歌。白毛浮绿水，红掌拨清波。"}
] * 10  # 复制多份模拟“多首”效果

# 字体设置（请确保系统有中文字体，否则请指定路径）
try:
    font = pygame.font.SysFont("SimHei", 24)
    detail_font = pygame.font.SysFont("SimHei", 32)
except:
    font = pygame.font.SysFont("arial", 24)

class PoemPoint:
    def __init__(self, poem, x, y, z):
        self.poem = poem
        # 3D 坐标
        self.x, self.y, self.z = x, y, z
        self.screen_x = 0
        self.screen_y = 0
        self.scale = 0
        self.rect = None

    def project(self, angle_x, angle_y):
        # 绕 Y 轴旋转
        rad_y = math.radians(angle_y)
        nx = self.x * math.cos(rad_y) - self.z * math.sin(rad_y)
        nz = self.x * math.sin(rad_y) + self.z * math.cos(rad_y)
        
        # 绕 X 轴旋转
        rad_x = math.radians(angle_x)
        ny = self.y * math.cos(rad_x) - nz * math.sin(rad_x)
        nz = self.y * math.sin(rad_x) + nz * math.cos(rad_x)

        # 投影到 2D 屏幕 (透视投影)
        fov = 400  # 视距
        self.scale = fov / (fov + nz + 300) 
        self.screen_x = int(WIDTH / 2 + nx * self.scale)
        self.screen_y = int(HEIGHT / 2 + ny * self.scale)
        
        # 用于点击检测
        text_w = 80 * self.scale
        text_h = 30 * self.scale
        self.rect = pygame.Rect(self.screen_x - text_w/2, self.screen_y - text_h/2, text_w, text_h)
        return nz # 返回深度用于排序

# 初始化 3D 点 (分布在球面上)
points = []
for i, p in enumerate(POEMS):
    phi = math.acos(-1 + (2 * i) / len(POEMS))
    theta = math.sqrt(len(POEMS) * math.pi) * phi
    x = 250 * math.cos(theta) * math.sin(phi)
    y = 250 * math.sin(theta) * math.sin(phi)
    z = 250 * math.cos(phi)
    points.append(PoemPoint(p, x, y, z))

angle_x, angle_y = 0, 0
selected_poem = None
running = True

while running:
    screen.fill(BG_COLOR)
    mouse_pos = pygame.mouse.get_pos()
    
    # 1. 处理事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            if selected_poem:
                selected_poem = None # 点击任意处关闭详情
            else:
                # 检查是否点击了某个诗词
                for p in sorted(points, key=lambda x: x.scale, reverse=True):
                    if p.rect and p.rect.collidepoint(mouse_pos):
                        selected_poem = p.poem
                        break

    # 2. 自动旋转 (如果没有点击查看详情)
    if not selected_poem:
        angle_y += 0.5
        angle_x += 0.2

    # 3. 投影并排序 (先画后面的，再画前面的，解决遮挡问题)
    for p in points:
        p.project(angle_x, angle_y)
    
    # 按深度排序 (z轴从远到近)
    points.sort(key=lambda p: p.scale)

    # 4. 绘制
    for p in points:
        # 根据远近计算颜色亮度
        brightness = int(255 * (p.scale ** 1.5))
        brightness = max(50, min(255, brightness))
        color = (brightness, brightness, 255) if p.rect.collidepoint(mouse_pos) else (brightness, brightness, brightness)
        
        # 渲染文字
        txt_surf = font.render(p.poem["title"], True, color)
        # 缩放文字
        scaled_w = int(txt_surf.get_width() * p.scale)
        scaled_h = int(txt_surf.get_height() * p.scale)
        if scaled_w > 5:
            txt_surf = pygame.transform.scale(txt_surf, (scaled_w, scaled_h))
            screen.blit(txt_surf, (p.screen_x - scaled_w/2, p.screen_y - scaled_h/2))

    # 5. 绘制详情弹窗
    if selected_poem:
        overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 200))
        screen.blit(overlay, (0,0))
        
        # 绘制诗词内容
        box_rect = pygame.Rect(WIDTH/2-250, HEIGHT/2-150, 500, 300)
        pygame.draw.rect(screen, (50, 50, 70), box_rect)
        pygame.draw.rect(screen, GOLD, box_rect, 2)
        
        title_s = detail_font.render(f"《{selected_poem['title']}》", True, GOLD)
        author_s = font.render(selected_poem['author'], True, WHITE)
        content_s = font.render(selected_poem['content'], True, CYAN)
        
        screen.blit(title_s, (WIDTH/2 - title_s.get_width()/2, HEIGHT/2 - 100))
        screen.blit(author_s, (WIDTH/2 - author_s.get_width()/2, HEIGHT/2 - 50))
        screen.blit(content_s, (WIDTH/2 - content_s.get_width()/2, HEIGHT/2 + 20))
        
        tip_s = font.render("点击任意处返回", True, (150, 150, 150))
        screen.blit(tip_s, (WIDTH/2 - tip_s.get_width()/2, HEIGHT/2 + 100))

    pygame.display.flip()
    clock.tick(60)

pygame.quit()