import pygame
import sys
import colorsys

# 初始化Pygame
pygame.init()

# 窗口设置
WIDTH, HEIGHT = 1000, 700
PAINT_WIDTH = 750
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("专业画图板 - HSV颜色选择器+取色器")

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GRAY = (220, 220, 220)
DARK_GRAY = (150, 150, 150)

# 绘画默认设置
drawing = False
brush_size = 5
current_color = BLACK
hue = 0.0
saturation = 1.0
value = 1.0
color_picker_mode = False  # 取色器模式开关

# 按钮区域定义（新增取色器按钮）
clear_btn = pygame.Rect(20, 15, 80, 40)
size_up_btn = pygame.Rect(120, 15, 60, 40)
size_down_btn = pygame.Rect(200, 15, 60, 40)
eraser_btn = pygame.Rect(280, 15, 80, 40)
color_picker_btn = pygame.Rect(380, 15, 80, 40)  # 新增取色器按钮
quit_btn = pygame.Rect(620, 15, 80, 40)

# HSV颜色选择器区域
color_panel_x = PAINT_WIDTH + 20
color_panel_y = 100
slider_width = 200
slider_height = 20
handle_radius = 12

# 色相滑块
hue_slider_rect = pygame.Rect(color_panel_x, color_panel_y, slider_width, slider_height)
hue_handle_x = color_panel_x

# 饱和度滑块
sat_slider_rect = pygame.Rect(color_panel_x, color_panel_y + 60, slider_width, slider_height)
sat_handle_x = color_panel_x + slider_width

# 亮度滑块
val_slider_rect = pygame.Rect(color_panel_x, color_panel_y + 120, slider_width, slider_height)
val_handle_x = color_panel_x + slider_width

# 颜色预览框
preview_rect = pygame.Rect(color_panel_x, color_panel_y + 180, 100, 50)

# 拖动状态
dragging_hue = False
dragging_sat = False
dragging_val = False

# 支持中文字体
font = pygame.font.SysFont("simhei", 20)
small_font = pygame.font.SysFont("simhei", 16)

# 初始背景为白色
screen.fill(WHITE)

# 生成色相渐变条
def create_hue_gradient(width, height):
    gradient = pygame.Surface((width, height))
    for x in range(width):
        hue = x / width
        r, g, b = colorsys.hsv_to_rgb(hue, 1.0, 1.0)
        color = (int(r*255), int(g*255), int(b*255))
        pygame.draw.line(gradient, color, (x, 0), (x, height))
    return gradient

# 生成饱和度渐变条
def create_sat_gradient(width, height, hue):
    gradient = pygame.Surface((width, height))
    for x in range(width):
        sat = x / width
        r, g, b = colorsys.hsv_to_rgb(hue, sat, 1.0)
        color = (int(r*255), int(g*255), int(b*255))
        pygame.draw.line(gradient, color, (x, 0), (x, height))
    return gradient

# 生成亮度渐变条
def create_val_gradient(width, height, hue, sat):
    gradient = pygame.Surface((width, height))
    for x in range(width):
        val = x / width
        r, g, b = colorsys.hsv_to_rgb(hue, sat, val)
        color = (int(r*255), int(g*255), int(b*255))
        pygame.draw.line(gradient, color, (x, 0), (x, height))
    return gradient

# RGB转HSV（用于取色器同步滑块）
def rgb_to_hsv(r, g, b):
    r_norm = r / 255.0
    g_norm = g / 255.0
    b_norm = b / 255.0
    return colorsys.rgb_to_hsv(r_norm, g_norm, b_norm)

# 预先生成色相渐变条
hue_gradient = create_hue_gradient(slider_width, slider_height)

# 主循环
running = True
while running:
    # 绘制顶部工具栏
    pygame.draw.rect(screen, GRAY, (0, 0, PAINT_WIDTH, 70))
    
    # 绘制功能按钮（取色器按钮根据模式变色）
    pygame.draw.rect(screen, WHITE, clear_btn)
    pygame.draw.rect(screen, WHITE, size_up_btn)
    pygame.draw.rect(screen, WHITE, size_down_btn)
    pygame.draw.rect(screen, WHITE, eraser_btn)
    # 取色器模式激活时按钮变蓝色
    picker_btn_color = (0, 150, 255) if color_picker_mode else WHITE
    pygame.draw.rect(screen, picker_btn_color, color_picker_btn)
    pygame.draw.rect(screen, RED, quit_btn)
    
    # 绘制功能按钮文字
    screen.blit(font.render("清屏", True, BLACK), (35, 23))
    screen.blit(font.render("放大", True, BLACK), (130, 23))
    screen.blit(font.render("缩小", True, BLACK), (210, 23))
    screen.blit(font.render("橡皮擦", True, BLACK), (290, 23))
    # 取色器按钮文字颜色根据模式变化
    picker_text_color = WHITE if color_picker_mode else BLACK
    screen.blit(font.render("取色器", True, picker_text_color), (390, 23))
    screen.blit(font.render("退出", True, WHITE), (635, 23))
    
    # 显示当前画笔大小和模式
    size_text = small_font.render(f"画笔大小: {brush_size}", True, BLACK)
    screen.blit(size_text, (480, 25))
    if color_picker_mode:
        mode_text = small_font.render("当前模式: 取色中", True, (0, 150, 255))
        screen.blit(mode_text, (480, 45))
    
    # 绘制右侧颜色选择器面板背景
    pygame.draw.rect(screen, GRAY, (PAINT_WIDTH, 0, WIDTH-PAINT_WIDTH, HEIGHT))
    
    # 绘制颜色选择器标题
    screen.blit(font.render("颜色选择器", True, BLACK), (color_panel_x, 50))
    
    # 绘制色相滑块
    screen.blit(hue_gradient, hue_slider_rect)
    pygame.draw.circle(screen, WHITE, (int(hue_handle_x), hue_slider_rect.centery), handle_radius)
    pygame.draw.circle(screen, BLACK, (int(hue_handle_x), hue_slider_rect.centery), handle_radius, 2)
    screen.blit(small_font.render(f"色相: {int(hue*360)}°", True, BLACK), (color_panel_x, color_panel_y - 25))
    
    # 绘制饱和度滑块
    sat_gradient = create_sat_gradient(slider_width, slider_height, hue)
    screen.blit(sat_gradient, sat_slider_rect)
    pygame.draw.circle(screen, WHITE, (int(sat_handle_x), sat_slider_rect.centery), handle_radius)
    pygame.draw.circle(screen, BLACK, (int(sat_handle_x), sat_slider_rect.centery), handle_radius, 2)
    screen.blit(small_font.render(f"饱和度: {int(saturation*100)}%", True, BLACK), (color_panel_x, color_panel_y + 35))
    
    # 绘制亮度滑块
    val_gradient = create_val_gradient(slider_width, slider_height, hue, saturation)
    screen.blit(val_gradient, val_slider_rect)
    pygame.draw.circle(screen, WHITE, (int(val_handle_x), val_slider_rect.centery), handle_radius)
    pygame.draw.circle(screen, BLACK, (int(val_handle_x), val_slider_rect.centery), handle_radius, 2)
    screen.blit(small_font.render(f"亮度: {int(value*100)}%", True, BLACK), (color_panel_x, color_panel_y + 95))
    
    # 绘制颜色预览框
    pygame.draw.rect(screen, current_color, preview_rect)
    pygame.draw.rect(screen, BLACK, preview_rect, 2)
    screen.blit(small_font.render("当前颜色", True, BLACK), (color_panel_x + 110, color_panel_y + 195))
    
    # 显示RGB值
    r, g, b = current_color
    rgb_text = small_font.render(f"RGB: ({r}, {g}, {b})", True, BLACK)
    screen.blit(rgb_text, (color_panel_x, color_panel_y + 250))
    
    # 事件处理
    for event in pygame.event.get():
        # 退出程序
        if event.type == pygame.QUIT:
            running = False

        # 鼠标按下事件
        if event.type == pygame.MOUSEBUTTONDOWN:
            mouse_x, mouse_y = event.pos
            
            # 取色器模式：点击绘画区域提取颜色
            if color_picker_mode and mouse_x < PAINT_WIDTH and mouse_y > 70:
                # 获取点击位置的颜色
                color = screen.get_at((mouse_x, mouse_y))
                r, g, b = color[0], color[1], color[2]
                current_color = (r, g, b)
                
                # 转换为HSV并同步更新滑块
                h, s, v = rgb_to_hsv(r, g, b)
                hue = h
                saturation = s
                value = v
                
                # 更新滑块手柄位置
                hue_handle_x = color_panel_x + hue * slider_width
                sat_handle_x = color_panel_x + saturation * slider_width
                val_handle_x = color_panel_x + value * slider_width
                
                # 取色完成后自动退出取色模式
                color_picker_mode = False
            
            # 正常绘画模式
            elif mouse_x < PAINT_WIDTH and mouse_y > 70 and not color_picker_mode:
                drawing = True
            
            # 检查功能按钮
            elif clear_btn.collidepoint(event.pos):
                screen.fill(WHITE)
            elif size_up_btn.collidepoint(event.pos):
                brush_size = min(brush_size + 2, 50)
            elif size_down_btn.collidepoint(event.pos):
                brush_size = max(brush_size - 2, 1)
            elif eraser_btn.collidepoint(event.pos):
                current_color = WHITE
                color_picker_mode = False  # 点击橡皮擦退出取色模式
            elif color_picker_btn.collidepoint(event.pos):
                color_picker_mode = not color_picker_mode  # 切换取色模式
            elif quit_btn.collidepoint(event.pos):
                running = False
            
            # 检查颜色滑块
            elif hue_slider_rect.collidepoint(event.pos):
                dragging_hue = True
                hue_handle_x = max(color_panel_x, min(mouse_x, color_panel_x + slider_width))
                hue = (hue_handle_x - color_panel_x) / slider_width
                r, g, b = colorsys.hsv_to_rgb(hue, saturation, value)
                current_color = (int(r*255), int(g*255), int(b*255))
                color_picker_mode = False  # 拖动滑块退出取色模式
            
            elif sat_slider_rect.collidepoint(event.pos):
                dragging_sat = True
                sat_handle_x = max(color_panel_x, min(mouse_x, color_panel_x + slider_width))
                saturation = (sat_handle_x - color_panel_x) / slider_width
                r, g, b = colorsys.hsv_to_rgb(hue, saturation, value)
                current_color = (int(r*255), int(g*255), int(b*255))
                color_picker_mode = False
            
            elif val_slider_rect.collidepoint(event.pos):
                dragging_val = True
                val_handle_x = max(color_panel_x, min(mouse_x, color_panel_x + slider_width))
                value = (val_handle_x - color_panel_x) / slider_width
                r, g, b = colorsys.hsv_to_rgb(hue, saturation, value)
                current_color = (int(r*255), int(g*255), int(b*255))
                color_picker_mode = False

        # 鼠标松开事件
        if event.type == pygame.MOUSEBUTTONUP:
            drawing = False
            dragging_hue = False
            dragging_sat = False
            dragging_val = False

        # 鼠标移动事件
        if event.type == pygame.MOUSEMOTION:
            mouse_x, mouse_y = event.pos
            
            # 绘画（仅在非取色模式下）
            if drawing and mouse_x < PAINT_WIDTH and mouse_y > 70 and not color_picker_mode:
                pygame.draw.circle(screen, current_color, event.pos, brush_size)
            
            # 拖动色相滑块
            if dragging_hue:
                hue_handle_x = max(color_panel_x, min(mouse_x, color_panel_x + slider_width))
                hue = (hue_handle_x - color_panel_x) / slider_width
                r, g, b = colorsys.hsv_to_rgb(hue, saturation, value)
                current_color = (int(r*255), int(g*255), int(b*255))
            
            # 拖动饱和度滑块
            if dragging_sat:
                sat_handle_x = max(color_panel_x, min(mouse_x, color_panel_x + slider_width))
                saturation = (sat_handle_x - color_panel_x) / slider_width
                r, g, b = colorsys.hsv_to_rgb(hue, saturation, value)
                current_color = (int(r*255), int(g*255), int(b*255))
            
            # 拖动亮度滑块
            if dragging_val:
                val_handle_x = max(color_panel_x, min(mouse_x, color_panel_x + slider_width))
                value = (val_handle_x - color_panel_x) / slider_width
                r, g, b = colorsys.hsv_to_rgb(hue, saturation, value)
                current_color = (int(r*255), int(g*255), int(b*255))

    # 刷新画面
    pygame.display.flip()

# 退出程序
pygame.quit()
sys.exit()