import pygame
import sys
import random
import math

# 初始化Pygame
pygame.init()

# 屏幕设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("配色练习")

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (128, 128, 128)
LIGHT_GRAY = (200, 200, 200)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

# 修复中文显示：使用系统中文字体
def get_chinese_font(size):
    font_names = [
        "SimHei", "Microsoft YaHei", "SimSun",
        "PingFang SC", "Heiti SC",
        "WenQuanYi Micro Hei", "Noto Sans CJK SC"
    ]
    
    for font_name in font_names:
        try:
            font = pygame.font.SysFont(font_name, size)
            test_text = font.render("测试", True, BLACK)
            if test_text.get_width() > 10:
                return font
        except:
            continue
    
    print("警告：未找到支持中文的字体，中文可能显示为方块")
    return pygame.font.Font(None, size)

# 字体设置
font_large = get_chinese_font(40)
font_medium = get_chinese_font(28)
font_small = get_chinese_font(22)

# 滑块类
class Slider:
    def __init__(self, x, y, width, min_val=0, max_val=255, initial_val=128, color=GRAY):
        self.x = x
        self.y = y
        self.width = width
        self.height = 10
        self.min_val = min_val
        self.max_val = max_val
        self.value = initial_val
        self.color = color
        self.dragging = False
        
        # 滑块按钮尺寸
        self.handle_width = 20
        self.handle_height = 30
        self.update_handle_pos()
    
    def update_handle_pos(self):
        ratio = (self.value - self.min_val) / (self.max_val - self.min_val)
        self.handle_x = self.x + ratio * self.width - self.handle_width // 2
        self.handle_y = self.y - self.handle_height // 2 + self.height // 2
    
    def draw(self, screen):
        # 绘制轨道
        pygame.draw.rect(screen, LIGHT_GRAY, (self.x, self.y, self.width, self.height))
        pygame.draw.rect(screen, BLACK, (self.x, self.y, self.width, self.height), 1)
        
        # 绘制滑块按钮
        handle_rect = pygame.Rect(self.handle_x, self.handle_y, self.handle_width, self.handle_height)
        pygame.draw.rect(screen, self.color, handle_rect)
        pygame.draw.rect(screen, BLACK, handle_rect, 2)
    
    def handle_event(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
            handle_rect = pygame.Rect(self.handle_x, self.handle_y, self.handle_width, self.handle_height)
            if handle_rect.collidepoint(event.pos):
                self.dragging = True
        
        if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
            self.dragging = False
        
        if event.type == pygame.MOUSEMOTION and self.dragging:
            mouse_x = event.pos[0]
            # 限制滑块范围
            mouse_x = max(self.x, min(mouse_x, self.x + self.width))
            ratio = (mouse_x - self.x) / self.width
            self.value = int(self.min_val + ratio * (self.max_val - self.min_val))
            self.update_handle_pos()

# 按钮类
class Button:
    def __init__(self, x, y, w, h, text, color=LIGHT_GRAY, hover_color=GRAY):
        self.rect = pygame.Rect(x, y, w, h)
        self.text = text
        self.color = color
        self.hover_color = hover_color
        self.is_hovered = False

    def draw(self, screen):
        current_color = self.hover_color if self.is_hovered else self.color
        pygame.draw.rect(screen, current_color, self.rect)
        pygame.draw.rect(screen, BLACK, self.rect, 2)
        text_surface = font_medium.render(self.text, True, BLACK)
        screen.blit(text_surface, (self.rect.x + self.rect.width//2 - text_surface.get_width()//2,
                                  self.rect.y + self.rect.height//2 - text_surface.get_height()//2))

    def handle_event(self, event):
        if event.type == pygame.MOUSEMOTION:
            self.is_hovered = self.rect.collidepoint(event.pos)
        if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
            if self.rect.collidepoint(event.pos):
                return True
        return False

# 计算颜色匹配度（0-100分）
def calculate_similarity(color1, color2):
    r1, g1, b1 = color1
    r2, g2, b2 = color2
    # 欧氏距离计算颜色差异
    distance = math.sqrt((r1-r2)**2 + (g1-g2)**2 + (b1-b2)**2)
    max_distance = math.sqrt(255**2 * 3)
    similarity = 100 * (1 - distance / max_distance)
    return round(similarity, 1)

# 生成随机目标颜色
def generate_target_color():
    r = random.randint(0, 255)
    g = random.randint(0, 255)
    b = random.randint(0, 255)
    return (r, g, b)

# 主程序
def main():
    # 初始化滑块
    slider_r = Slider(200, 380, 400, color=RED)
    slider_g = Slider(200, 430, 400, color=GREEN)
    slider_b = Slider(200, 480, 400, color=BLUE)
    
    # 初始化目标颜色
    target_color = generate_target_color()
    
    # 按钮
    next_button = Button(300, 530, 200, 50, "下一题")
    
    # 最佳得分记录
    best_score = 0
    
    while True:
        # 获取用户当前颜色
        user_color = (slider_r.value, slider_g.value, slider_b.value)
        score = calculate_similarity(user_color, target_color)
        if score > best_score:
            best_score = score
        
        screen.fill(WHITE)
        
        # 绘制标题
        title = font_large.render("RGB配色练习", True, BLACK)
        screen.blit(title, (WIDTH//2 - title.get_width()//2, 30))
        
        # 绘制目标颜色
        target_label = font_medium.render("目标颜色", True, BLACK)
        screen.blit(target_label, (150, 90))
        pygame.draw.rect(screen, target_color, (100, 130, 200, 200))
        pygame.draw.rect(screen, BLACK, (100, 130, 200, 200), 3)
        target_rgb = font_small.render(f"RGB: {target_color}", True, BLACK)
        screen.blit(target_rgb, (100, 340))
        
        # 绘制用户颜色
        user_label = font_medium.render("你的颜色", True, BLACK)
        screen.blit(user_label, (500, 90))
        pygame.draw.rect(screen, user_color, (450, 130, 200, 200))
        pygame.draw.rect(screen, BLACK, (450, 130, 200, 200), 3)
        user_rgb = font_small.render(f"RGB: {user_color}", True, BLACK)
        screen.blit(user_rgb, (450, 340))
        
        # 绘制匹配度
        score_text = font_large.render(f"匹配度: {score}%", True, BLACK)
        screen.blit(score_text, (WIDTH//2 - score_text.get_width()//2, 90))
        
        best_text = font_small.render(f"本局最佳: {best_score}%", True, GRAY)
        screen.blit(best_text, (WIDTH//2 - best_text.get_width()//2, 140))
        
        # 绘制滑块标签
        r_label = font_medium.render("R", True, RED)
        g_label = font_medium.render("G", True, GREEN)
        b_label = font_medium.render("B", True, BLUE)
        screen.blit(r_label, (160, 370))
        screen.blit(g_label, (160, 420))
        screen.blit(b_label, (160, 470))
        
        # 绘制滑块数值
        r_val = font_small.render(str(slider_r.value), True, BLACK)
        g_val = font_small.render(str(slider_g.value), True, BLACK)
        b_val = font_small.render(str(slider_b.value), True, BLACK)
        screen.blit(r_val, (620, 375))
        screen.blit(g_val, (620, 425))
        screen.blit(b_val, (620, 475))
        
        # 绘制滑块
        slider_r.draw(screen)
        slider_g.draw(screen)
        slider_b.draw(screen)
        
        # 绘制按钮
        next_button.draw(screen)
        
        # 操作提示
        hint = font_small.render("拖动滑块匹配目标颜色，越接近得分越高", True, GRAY)
        screen.blit(hint, (WIDTH//2 - hint.get_width()//2, 300))
        
        # 事件处理
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()
            
            # 滑块事件
            slider_r.handle_event(event)
            slider_g.handle_event(event)
            slider_b.handle_event(event)
            
            # 按钮事件
            if next_button.handle_event(event):
                target_color = generate_target_color()
                best_score = 0
        
        pygame.display.flip()

if __name__ == "__main__":
    main()