import pygame
import sys

# 初始化Pygame
pygame.init()

# 窗口设置
WINDOW_WIDTH = 600
WINDOW_HEIGHT = 450
BACKGROUND_COLOR = (240, 248, 255)  # 浅色背景
TEXT_COLOR = (30, 30, 50)
INPUT_BOX_COLOR = (255, 255, 255)
INPUT_BOX_ACTIVE_COLOR = (220, 240, 255)
BUTTON_COLOR = (70, 130, 200)
BUTTON_HOVER_COLOR = (100, 160, 230)
RESULT_BG_COLOR = (230, 240, 250)
HEADER_COLOR = (60, 100, 150)

# 字体设置
FONT = pygame.font.Font(None, 36)
SMALL_FONT = pygame.font.Font(None, 28)
TITLE_FONT = pygame.font.Font(None, 40)

# 定义长度单位与米之间的转换关系
UNITS = {
    "千米 (km)": 1000.0,
    "米 (m)": 1.0,
    "分米 (dm)": 0.1,
    "厘米 (cm)": 0.01,
    "毫米 (mm)": 0.001,
    "英里 (mi)": 1609.344,
    "码 (yd)": 0.9144,
    "英尺 (ft)": 0.3048,
    "英寸 (in)": 0.0254
}


class LengthConverter:
    def __init__(self):
        self.screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
        pygame.display.set_caption("长度单位转换器")
        self.clock = pygame.time.Clock()
        self.running = True

        # 单位列表
        self.unit_names = list(UNITS.keys())
        self.unit_display = {name: name.split()[0] for name in self.unit_names}

        # 选择的单位
        self.from_unit = "米 (m)"
        self.to_unit = "英尺 (ft)"

        # 输入框
        self.input_text = ""
        self.input_active = True
        self.input_rect = pygame.Rect(180, 100, 250, 45)

        # 下拉菜单
        self.show_from_dropdown = False
        self.show_to_dropdown = False
        self.dropdown_visible_items = 5
        self.dropdown_item_height = 35

        # 从单位下拉菜单
        self.from_dropdown_rect = pygame.Rect(180, 155, 250, 40)
        self.from_dropdown_items_rect = pygame.Rect(180, 195, 250,
                                                    self.dropdown_item_height * self.dropdown_visible_items)

        # 到单位下拉菜单
        self.to_dropdown_rect = pygame.Rect(180, 240, 250, 40)
        self.to_dropdown_items_rect = pygame.Rect(180, 280, 250,
                                                  self.dropdown_item_height * self.dropdown_visible_items)

        # 滚动偏移
        self.from_scroll = 0
        self.to_scroll = 0

        # 转换按钮
        self.convert_button = pygame.Rect(200, 340, 200, 50)

        # 结果
        self.result = None
        self.error_message = None

    def handle_events(self):
        """处理事件"""
        mouse_pos = pygame.mouse.get_pos()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False

            elif event.type == pygame.MOUSEBUTTONDOWN:
                # 关闭下拉菜单
                if not self.from_dropdown_rect.collidepoint(mouse_pos) and not self.from_dropdown_items_rect.collidepoint(mouse_pos):
                    self.show_from_dropdown = False
                if not self.to_dropdown_rect.collidepoint(mouse_pos) and not self.to_dropdown_items_rect.collidepoint(mouse_pos):
                    self.show_to_dropdown = False

                # 点击从单位选择框
                if self.from_dropdown_rect.collidepoint(mouse_pos):
                    self.show_from_dropdown = not self.show_from_dropdown
                    self.show_to_dropdown = False
                    self.input_active = False

                # 点击到单位选择框
                elif self.to_dropdown_rect.collidepoint(mouse_pos):
                    self.show_to_dropdown = not self.show_to_dropdown
                    self.show_from_dropdown = False
                    self.input_active = False

                # 点击输入框
                elif self.input_rect.collidepoint(mouse_pos):
                    self.input_active = True
                    self.show_from_dropdown = False
                    self.show_to_dropdown = False

                # 点击转换按钮
                elif self.convert_button.collidepoint(mouse_pos):
                    self.convert_length()

                # 处理下拉菜单选择
                elif self.show_from_dropdown:
                    self.handle_dropdown_click(mouse_pos, self.from_dropdown_items_rect,
                                               self.from_scroll, is_from=True)

                elif self.show_to_dropdown:
                    self.handle_dropdown_click(mouse_pos, self.to_dropdown_items_rect,
                                               self.to_scroll, is_from=False)

                else:
                    self.input_active = False

            elif event.type == pygame.KEYDOWN and self.input_active:
                if event.key == pygame.K_RETURN:
                    self.convert_length()
                elif event.key == pygame.K_BACKSPACE:
                    self.input_text = self.input_text[:-1]
                elif event.key == pygame.K_ESCAPE:
                    self.input_text = ""
                else:
                    # 允许输入数字、负号和小数点
                    if (event.unicode.isdigit() or event.unicode == '.' or
                            (event.unicode == '-' and len(self.input_text) == 0)):
                        self.input_text += event.unicode
                    # 限制小数点个数
                    if self.input_text.count('.') > 1:
                        self.input_text = self.input_text[:-1]

    def handle_dropdown_click(self, mouse_pos, dropdown_rect, scroll, is_from):
        """处理下拉菜单点击"""
        if dropdown_rect.collidepoint(mouse_pos):
            # 计算点击的项
            relative_y = mouse_pos[1] - dropdown_rect.y
            item_index = relative_y // self.dropdown_item_height + scroll

            if 0 <= item_index < len(self.unit_names):
                if is_from:
                    self.from_unit = self.unit_names[item_index]
                    self.show_from_dropdown = False
                else:
                    self.to_unit = self.unit_names[item_index]
                    self.show_to_dropdown = False
                self.result = None
                self.error_message = None

    def convert_length(self):
        """执行长度转换"""
        self.error_message = None
        self.result = None

        if not self.input_text:
            self.error_message = "请输入长度值"
            return

        try:
            value = float(self.input_text)
        except ValueError:
            self.error_message = "请输入有效的数字"
            return

        # 转换为米
        meters = value * UNITS[self.from_unit]

        # 转换为目标单位
        result_value = meters / UNITS[self.to_unit]

        # 格式化结果
        if abs(result_value) < 0.0001 and result_value != 0:
            self.result = f"{result_value:.6e}"
        elif abs(result_value) >= 1000000:
            self.result = f"{result_value:.2e}"
        elif result_value.is_integer():
            self.result = f"{int(result_value)}"
        else:
            if abs(result_value) < 0.01:
                self.result = f"{result_value:.6f}"
            elif abs(result_value) < 1:
                self.result = f"{result_value:.4f}"
            elif abs(result_value) < 1000:
                self.result = f"{result_value:.3f}"
            else:
                self.result = f"{result_value:.2f}"

        # 移除末尾多余的0
        if '.' in self.result:
            self.result = self.result.rstrip('0').rstrip('.')

    def draw_dropdown(self, rect, selected_unit, show_dropdown, scroll, is_from):
        """绘制下拉菜单"""
        # 绘制选择框
        color = INPUT_BOX_ACTIVE_COLOR if show_dropdown else INPUT_BOX_COLOR
        pygame.draw.rect(self.screen, color, rect, border_radius=5)
        pygame.draw.rect(self.screen, HEADER_COLOR, rect, 2, border_radius=5)

        # 显示选中的单位
        display_text = f"{self.unit_display[selected_unit]} ({selected_unit.split()[1][1:-1]})"
        text = SMALL_FONT.render(display_text, True, TEXT_COLOR)
        self.screen.blit(text, (rect.x + 10, rect.y + 10))

        # 绘制下拉箭头
        arrow_points = [(rect.right - 20, rect.centery - 5),
                        (rect.right - 10, rect.centery - 5),
                        (rect.right - 15, rect.centery + 5)]
        pygame.draw.polygon(self.screen, HEADER_COLOR, arrow_points)

        # 绘制下拉选项
        if show_dropdown:
            items_rect = pygame.Rect(rect.x, rect.bottom, rect.width,
                                     self.dropdown_item_height * self.dropdown_visible_items)
            pygame.draw.rect(self.screen, INPUT_BOX_COLOR, items_rect)
            pygame.draw.rect(self.screen, HEADER_COLOR, items_rect, 2)

            # 计算可见项
            start_idx = scroll
            end_idx = min(len(self.unit_names), start_idx +
                          self.dropdown_visible_items)

            for i in range(start_idx, end_idx):
                item_rect = pygame.Rect(rect.x, rect.bottom + (i - start_idx) * self.dropdown_item_height,
                                        rect.width, self.dropdown_item_height)

                # 高亮当前选中的项
                if self.unit_names[i] == selected_unit:
                    pygame.draw.rect(
                        self.screen, BUTTON_HOVER_COLOR, item_rect)

                # 显示单位
                unit = self.unit_names[i]
                display_text = f"{self.unit_display[unit]} ({unit.split()[1][1:-1]})"
                text = SMALL_FONT.render(display_text, True, TEXT_COLOR)
                self.screen.blit(text, (item_rect.x + 10, item_rect.y + 8))

            # 绘制滚动条（如果项目太多）
            if len(self.unit_names) > self.dropdown_visible_items:
                scrollbar_rect = pygame.Rect(rect.right - 10, rect.bottom, 10,
                                             self.dropdown_item_height * self.dropdown_visible_items)
                pygame.draw.rect(self.screen, HEADER_COLOR, scrollbar_rect, 1)

                # 滚动条滑块
                scroll_ratio = scroll / \
                    (len(self.unit_names) - self.dropdown_visible_items)
                slider_height = max(
                    20, scrollbar_rect.height * self.dropdown_visible_items / len(self.unit_names))
                slider_y = scrollbar_rect.y + scroll_ratio * \
                    (scrollbar_rect.height - slider_height)
                slider_rect = pygame.Rect(
                    scrollbar_rect.x, slider_y, 10, slider_height)
                pygame.draw.rect(self.screen, BUTTON_COLOR, slider_rect)

    def draw(self):
        """绘制界面"""
        self.screen.fill(BACKGROUND_COLOR)

        # 绘制标题
        title_text = TITLE_FONT.render("📏 长度单位转换器", True, HEADER_COLOR)
        title_rect = title_text.get_rect(center=(WINDOW_WIDTH // 2, 35))
        self.screen.blit(title_text, title_rect)

        # 绘制输入区域
        input_label = SMALL_FONT.render("输入数值:", True, TEXT_COLOR)
        self.screen.blit(input_label, (self.input_rect.x -
                         95, self.input_rect.y + 12))

        # 绘制输入框
        color = INPUT_BOX_ACTIVE_COLOR if self.input_active else INPUT_BOX_COLOR
        pygame.draw.rect(self.screen, color, self.input_rect, border_radius=5)
        pygame.draw.rect(self.screen, HEADER_COLOR,
                         self.input_rect, 2, border_radius=5)

        # 绘制输入文本
        input_surface = FONT.render(self.input_text, True, TEXT_COLOR)
        self.screen.blit(
            input_surface, (self.input_rect.x + 10, self.input_rect.y + 8))

        # 绘制单位标签
        from_label = SMALL_FONT.render("从:", True, TEXT_COLOR)
        to_label = SMALL_FONT.render("到:", True, TEXT_COLOR)
        self.screen.blit(
            from_label, (self.from_dropdown_rect.x - 45, self.from_dropdown_rect.y + 10))
        self.screen.blit(to_label, (self.to_dropdown_rect.x -
                         45, self.to_dropdown_rect.y + 10))

        # 绘制下拉菜单
        self.draw_dropdown(self.from_dropdown_rect, self.from_unit,
                           self.show_from_dropdown, self.from_scroll, True)
        self.draw_dropdown(self.to_dropdown_rect, self.to_unit,
                           self.show_to_dropdown, self.to_scroll, False)

        # 绘制转换按钮
        mouse_pos = pygame.mouse.get_pos()
        btn_color = BUTTON_HOVER_COLOR if self.convert_button.collidepoint(
            mouse_pos) else BUTTON_COLOR
        pygame.draw.rect(self.screen, btn_color,
                         self.convert_button, border_radius=10)
        pygame.draw.rect(self.screen, (255, 255, 255),
                         self.convert_button, 2, border_radius=10)
        convert_text = FONT.render("转 换", True, (255, 255, 255))
        convert_rect = convert_text.get_rect(center=self.convert_button.center)
        self.screen.blit(convert_text, convert_rect)

        # 显示结果
        result_y = 420
        if self.result is not None:
            # 获取单位符号
            from_symbol = self.from_unit.split()[1][1:-1]
            to_symbol = self.to_unit.split()[1][1:-1]

            result_text = FONT.render(f"{self.input_text} {from_symbol} = {self.result} {to_symbol}",
                                      True, TEXT_COLOR)
            result_bg = pygame.Rect(50, result_y - 10, WINDOW_WIDTH - 100, 45)
            pygame.draw.rect(self.screen, RESULT_BG_COLOR,
                             result_bg, border_radius=8)
            pygame.draw.rect(self.screen, HEADER_COLOR,
                             result_bg, 1, border_radius=8)
            result_rect = result_text.get_rect(
                center=(WINDOW_WIDTH // 2, result_y + 12))
            self.screen.blit(result_text, result_rect)

        elif self.error_message is not None:
            error_text = SMALL_FONT.render(
                self.error_message, True, (220, 80, 80))
            error_rect = error_text.get_rect(
                center=(WINDOW_WIDTH // 2, result_y + 12))
            self.screen.blit(error_text, error_rect)

        pygame.display.flip()

    def run(self):
        """主循环"""
        while self.running:
            self.handle_events()
            self.draw()
            self.clock.tick(60)

        pygame.quit()
        sys.exit()


if __name__ == "__main__":
    converter = LengthConverter()
    converter.run()
