import pygame, sys, os, random
pygame.init()

WIDTH, HEIGHT = 1000, 700
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("唐诗注释浮窗示例")
clock = pygame.time.Clock()
FONT = pygame.font.SysFont("simhei", 20)
FONT_B = pygame.font.SysFont("simhei", 26, bold=True)

BG = (30, 38, 50)
PANEL = (22, 28, 36)
ACCENT = (220, 180, 100)
TEXT = (235,235,235)
HINT = (170,170,170)
OVERLAY = (10, 12, 18, 200)

# 示例数据（带注释、押韵与平仄）
POEMS = [
    {
        "id":"p1",
        "title":"静夜思",
        "author":"李白",
        "content":"床前明月光，疑是地上霜。举头望明月，低头思故乡。",
        "notes": {
            "明月": "明亮的月亮。此处常用来寄托思念或怀乡之情。",
            "举头": "抬头向上看。",
            "故乡": "家乡，表达对故土的怀念。"
        },
        "rhyme": "押『阳』韵（近体诗押尾韵，示例）",
        "pingze": ["平平仄仄平，", "仄是平平仄。", "平平仄平仄，", "仄平仄平平。"]  # 示例标注（非严格）
    },
    {
        "id":"p2",
        "title":"登鹳雀楼",
        "author":"王之涣",
        "content":"白日依山尽，黄河入海流。欲穷千里目，更上一层楼。",
        "notes": {
            "穷千里目": "把视野看得更远。'穷'在这里通‘尽’的意思，即达到极致。",
            "更上一层楼": "更进一步登高以望远，比喻有更高的追求。"
        },
        "rhyme": "押『流/楼』韵（示例）",
        "pingze": ["平仄平平仄，", "平平入仄平。", "仄平平仄仄，", "仄上一平平。"]
    }
]

LEFT_W = 280
selected = 0
show_notes = False
note_rect = pygame.Rect(120, 120, 560, 360)  # 浮窗位置与大小
dragging = False
drag_offset = (0,0)

def draw_sidebar():
    s = pygame.Surface((LEFT_W, HEIGHT))
    s.fill(PANEL)
    y = 20
    draw_text(s, "唐诗列表", 16, 8, FONT_B, ACCENT)
    for i, p in enumerate(POEMS):
        col = TEXT if i!=selected else ACCENT
        draw_text(s, f"{p['title']} — {p['author']}", 12, y+50*i, FONT, col)
    screen.blit(s, (0,0))

def draw_text(surf, text, x, y, font, color=(255,255,255)):
    surf.blit(font.render(text, True, color), (x,y))

def draw_main():
    main = pygame.Surface((WIDTH-LEFT_W, HEIGHT))
    main.fill(BG)
    px = LEFT_W + 20
    py = 20
    p = POEMS[selected]
    # Title & author (正文隐藏)
    draw_text(screen, p['title'], px, py, FONT_B, ACCENT)
    draw_text(screen, f"—— {p['author']}", px+8, py+40, FONT, TEXT)
    draw_text(screen, "(正文已隐藏)", px, py+90, FONT, HINT)
    # Notes button
    btn_rect = pygame.Rect(px, py+120, 140, 36)
    pygame.draw.rect(screen, ACCENT if show_notes else (80,100,120), btn_rect, border_radius=6)
    draw_text(screen, "显示注释 / 生词", btn_rect.x+12, btn_rect.y+6, FONT, (10,10,10) if show_notes else TEXT)
    # hint
    draw_text(screen, "按 H 可切换注释浮窗，拖动浮窗可移动，点击词条查看详情。", px, py+170, FONT, HINT)
    # show last line of poem obfuscated as hint (optional)
    # screen.blit(main, (LEFT_W,0))
    return btn_rect

def draw_notes_window():
    # 背景半透明
    s = pygame.Surface((note_rect.width, note_rect.height), pygame.SRCALPHA)
    s.fill((12, 16, 22, 220))
    # header
    draw_text(s, "注释与赏析", 12, 10, FONT_B, ACCENT)
    # get poem data
    p = POEMS[selected]
    # left column: word notes list
    lx, ly = 12, 50
    draw_text(s, "生词 / 词义：", lx, ly-30, FONT, TEXT)
    notes = p.get("notes", {})
    i = 0
    item_rects = []
    for word, note in notes.items():
        y = ly + i*28
        r = pygame.Rect(lx, y, 240, 26)
        # draw background for hover (handled externally)
        pygame.draw.rect(s, (0,0,0,0), r)
        draw_text(s, word, lx+6, y+2, FONT, ACCENT)
        # short preview of note
        preview = note if len(note)<=18 else note[:18]+"…"
        draw_text(s, preview, lx+80, y+2, FONT, TEXT)
        item_rects.append((pygame.Rect(note_rect.x+ r.x, note_rect.y + r.y, r.w, r.h), word, note))
        i += 1
    # right column: rhyme & pingze & annotation
    rx = 280
    ry = 50
    draw_text(s, "押韵信息：", rx, ry-30, FONT, TEXT)
    draw_text(s, p.get("rhyme","—"), rx, ry, FONT, HINT)
    draw_text(s, "平仄提示：", rx, ry+60, FONT, TEXT)
    # list pingze lines
    pyoff = ry+90
    for idx, line in enumerate(p.get("pingze", [])):
        draw_text(s, line, rx, pyoff + idx*26, FONT, HINT)
    draw_text(s, "赏析：", rx, pyoff + len(p.get("pingze", []))*28 + 8, FONT, TEXT)
    # small annotation placeholder
    ann = p.get("annotation", "未提供赏析。")
    draw_text(s, ann, rx, pyoff + len(p.get("pingze", []))*28 + 38, FONT, HINT)
    # blit to screen
    screen.blit(s, (note_rect.x, note_rect.y))
    return item_rects

# small popup for a single word detail
detail_popup = None  # tuple (rect, word, note)

def main_loop():
    global selected, show_notes, note_rect, dragging, drag_offset, detail_popup
    running = True
    while running:
        mx,my = pygame.mouse.get_pos()
        for ev in pygame.event.get():
            if ev.type == pygame.QUIT:
                running = False
            elif ev.type == pygame.KEYDOWN:
                if ev.key == pygame.K_h:
                    show_notes = not show_notes
                elif ev.key == pygame.K_TAB:
                    selected = (selected+1) % len(POEMS)
            elif ev.type == pygame.MOUSEBUTTONDOWN:
                if ev.button == 1:
                    # check sidebar clicks
                    if mx < LEFT_W:
                        # compute which poem clicked
                        rel_y = my - 20
                        idx = rel_y // 36
                        if 0 <= idx < len(POEMS):
                            selected = int(idx)
                    else:
                        btn = draw_main()  # note this draws again but ok
                        if btn.collidepoint(mx,my):
                            show_notes = not show_notes
                        # check click on note window header area to start dragging
                        if show_notes and note_rect.collidepoint(mx,my):
                            # if click within title bar area
                            local_x = mx - note_rect.x
                            local_y = my - note_rect.y
                            if 0 <= local_x <= note_rect.width and 0 <= local_y <= 36:
                                dragging = True
                                drag_offset = (mx - note_rect.x, my - note_rect.y)
            elif ev.type == pygame.MOUSEBUTTONUP:
                if ev.button == 1:
                    dragging = False
                    # check clicks on note items
                    if show_notes:
                        items = draw_notes_window()
                        for (r, word, note) in items:
                            if r.collidepoint(mx,my):
                                # open detail popup near mouse
                                pw, ph = 320, 140
                                px = min(mx, WIDTH - pw - 10)
                                py = min(my, HEIGHT - ph - 10)
                                detail_popup = (pygame.Rect(px, py, pw, ph), word, note)
                                break
            elif ev.type == pygame.MOUSEMOTION:
                if dragging:
                    note_rect.x = mx - drag_offset[0]
                    note_rect.y = my - drag_offset[1]
                    # clamp
                    note_rect.x = max(20, min(WIDTH-note_rect.width-20, note_rect.x))
                    note_rect.y = max(20, min(HEIGHT-note_rect.height-20, note_rect.y))

        # draw UI
        screen.fill((40,46,56))
        draw_sidebar()
        btn_rect = draw_main()

        if show_notes:
            items = draw_notes_window()

        # draw detail popup if any
        if detail_popup:
            r, w, n = detail_popup
            s = pygame.Surface((r.width, r.height))
            s.fill((18,20,26))
            draw_text(s, f"词语：{w}", 12, 10, FONT_B, ACCENT)
            draw_text(s, "详解：", 12, 48, FONT, TEXT)
            # wrap note text
            lines = []
            words = n.split(' ')
            cur = ""
            for ch in n:
                cur += ch
                # rough wrap by character count
                if len(cur) >= 26:
                    lines.append(cur)
                    cur = ""
            if cur:
                lines.append(cur)
            for i, ln in enumerate(lines[:5]):
                draw_text(s, ln, 12, 80 + i*22, FONT, HINT)
            pygame.draw.rect(s, (120,120,120), (r.width-34, 6, 28, 28), 2)
            screen.blit(s, (r.x, r.y))

        pygame.display.flip()
        clock.tick(60)

    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main_loop()