# -*- encoding: utf-8 -*-
'''
@File    :   gameui.py   
@License :   (C)Copyright 2018-2022

@Modify Time      @Author    @Version    @Desciption
------------      -------    --------    -----------
2022/12/22 10:01   zart20      1.0         None
'''

import time
from data import *
import pygame

# 定义颜色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
ORANGE = (255, 140, 0)  # 橘色
YELLOW = (250, 224, 103)  # 蛋黄
SILVER = (192, 192, 192)  # 银色
RED = (200, 0, 0)
bc = 40  # 定义全局边长


class MyTimer:
    def __init__(self):
        self.elapsed = 0.0
        self.running = False
        self.last_start_time = None

    def start(self):
        if not self.running:
            self.running = True
            self.last_start_time = time.time()

    def pause(self):
        if self.running:
            self.running = False
            self.elapsed += time.time() - self.last_start_time

    def get_elapsed(self):
        elapsed = self.elapsed
        if self.running:
            elapsed += time.time() - self.last_start_time
        return '{:>2.0f}分{:>2.0f}秒'.format(elapsed // 60, elapsed % 60)


def GuiForm():
    pygame.init()  # pygame 的初始化
    pygame.display.set_caption("数独")
    form = pygame.display.set_mode((840, 610))  # 主窗口
    form.fill(ORANGE)  # 填充橘色
    pygame.display.update()
    return form


# form = GuiForm()


def rect_draw(bc, row, col):
    '''画一个小方格对象'''
    # row = row-1
    # col = col-1
    face = pygame.Surface((bc, bc))  # 创建一个Surface对象
    block_color = [3, 4, 5]  # 显色宫格依据
    logi_row = row in block_color and col in block_color  # 显色逻辑
    logi_col = row in block_color or col in block_color  # 显色逻辑
    if not logi_row and logi_col:
        face.fill(YELLOW)
    else:
        face.fill(WHITE)  # 为对象填充颜色
    return face


def show_face(form, face, bc, row, col, ):
    """将小方格face在form上显示出来"""
    form.blit(face, (row * (bc + 3) + 50, col * (bc + 3) + 50))
    pygame.display.update()


def refresh(form:pygame.Surface,martix,u_martix, note_martix):
    # 将整个数组刷新一遍
    for i in range(9):
        for j in range(9):
            face = rect_draw(40, i, j)  # 创建一个基于位置的小方格
            if u_martix[j][i] != 0:
                if u_martix[j][i] != 11:

                    face1 = number_draw(face, martix, u_martix, bc, i, j)
                else:
                    face.fill(SILVER)
                    for note in note_martix:  # 如果这个空格有笔记直接覆盖清空笔记
                        if note[0] == i and note[1] == j:
                            possible = note[2]

                    face1 = possible_num(bc, i, j, possible)
                show_face(form, face1, bc, i, j)
            else:

                show_face(form, face, bc, i, j)


def xianse(form,martix, u_martix, x, y, note_martix=None):
    # 更新单个单元格为银色
    if note_martix is None:
        note_martix = list()
    if x >= 1 and y >= 1:
        i = x - 1  # 映射坐标时加了一现在要减掉
        j = y - 1
        face = rect_draw(bc, i, j)  # 创建一个基于位置的小方格
        face.fill(SILVER, (3, 3, 34, 34))
        if u_martix[j][i] != 0:
            if u_martix[j][i] != 11:

                number_draw(face, martix, u_martix, bc, i, j)
            else:
                # face.fill(SILVER)
                for note in note_martix:  # 如果这个空格有笔记直接覆盖清空笔记
                    if note[0] == i and note[1] == j:
                        possible = note[2]
                face = possible_num(bc, x, y, possible)
                # show_face(form,face,bc,i,j)

        show_face(form, face, bc, i, j)


def mini_rect_draw(face, bc, possible):
    """单独一个格子里的小数字"""
    num_font = pygame.font.SysFont('幼圆', 16, True)  # 加载系统字体
    bc1 = bc  # 当出现空集时用于定位
    bc = int(bc / 3)
    n = 1
    for i in range(3):
        for j in range(3):
            mini = pygame.Surface((bc, bc))  # 创建Surface对象
            mini.set_colorkey([0, 0, 0])  # 设置透明色
            mini = mini.convert_alpha()  # 设置透明色
            if possible:  # 在用户已填的部分有可能导致部分格子无解,所以先加一个判断
                for k in possible:
                    if n == k:
                        num_text = num_font.render(f"{k}", False, (109, 45, 250))  # 创建字体
                        rel = num_text.get_rect()
                        mini.blit(num_text, (int((bc - rel[2]) / 2), int((bc - rel[3]) / 2)))  # 数字显示居中
                n += 1
                face.blit(mini, (i * bc, j * bc))
            else:
                num_text = num_font.render(f"{None}", False, (109, 45, 250))
                rel = num_text.get_rect()
                face.blit(num_text, (int((bc1 - rel[2]) / 2), int((bc1 - rel[3]) / 2)))
    return face


def possible_num(bc, row, col, possible):
    """显示一个格子的可能值"""
    row = row - 1
    col = col - 1
    face = rect_draw(bc, row, col)
    face.fill(SILVER)
    mface = mini_rect_draw(face, bc, possible)
    return mface


def number_draw(face, martix, u_martix, bc, row, col):
    """向小格子里画数字"""
    num_font = pygame.font.SysFont('幼圆', 32, True)  # 加载系统字体
    if martix[col,row] == 0:
        if u_martix[col,row] not in GetPossible(martix,col,row):    # 判断是否符合数组要求
            print((col,row), GetPossible(martix, col, row))
            num_text = num_font.render(f"{u_martix[col][row]}", True, RED)  # 不符合要求显示红色
        else:
            num_text = num_font.render(f"{u_martix[col][row]}", True, BLACK)  # 创建字体
    else:
        num_text = num_font.render(f"{u_martix[col][row]}", True, BLACK)  # 创建字体
    rect_l = num_text.get_rect()  # 获取字体边长大小
    face.blit(num_text, (int((bc - rect_l[2]) / 2), int(bc - rect_l[3]) / 2))  # 数字显示居中
    return face


def control_number(form, bc, color1=SILVER, color2=WHITE):
    # 0-9 按键控制
    for num in range(9):
        control_number_xs(form, bc, num, color1, color2)


def control_number_xs(form, bc, num, color1=SILVER, color2=WHITE):
    ck = 6  # 边框
    num_font = pygame.font.SysFont('幼圆', 32, True)  # 加载系统字体
    face = pygame.Surface((bc, bc))
    # face1 = pygame.Surface((bc-ck, bc-ck))
    face.fill(color1)  # 外层银色
    face.fill(color2, (ck // 2, ck // 2, bc - ck, bc - ck))  # 里层白色
    num_text = num_font.render(f"{num + 1}", True, (0, 0, 0))  # 创建字体
    rect_l = num_text.get_rect()  # 获取字体边长大小
    face.blit(num_text, (int((bc - rect_l[2]) / 2), int(bc - rect_l[3]) / 2))  # 数字显示居中
    # face.blit(face,(int(ck/2),int(ck/2)))
    form.blit(face, (num * (bc + 3) + 50, (bc + 3) * 12 + 10))


def control(form, bc):
    # 5个控制按键
    lon = 9 * (bc + 3) + 50
    lon = lon // 5 - 12  # 控制按键长度
    num_font = pygame.font.SysFont('幼圆', 18, True)  # 加载系统字体
    ctl = ["撤回", "擦除", "笔记", "一键笔记", "提示"]
    for i in range(5):
        face = pygame.Surface((lon, bc))
        # face.set_colorkey([0,0,0])
        # face = face.convert_alpha()     # 透明色
        face.fill(WHITE)
        num_text = num_font.render(f"{ctl[i]}", False, (0, 0, 0))  # 创建字体
        rel = num_text.get_size()
        face.blit(num_text, (int((lon - rel[0]) / 2), int((bc - rel[1]) / 2)))  # 数字显示居中
        form.blit(face, ((lon + 2) * i + 50, (bc + 3) * 11 + 8))


def control_xs(form, bc, i):
    lon = 9 * (bc + 3) + 50
    lon = lon // 5 - 12  # 控制按键长度
    num_font = pygame.font.SysFont('幼圆', 18, True)  # 加载系统字体
    ctl = ["撤回", "擦除", "笔记", "一键笔记", "提示"]
    face = pygame.Surface((lon, bc))
    face.fill(SILVER)
    num_text = num_font.render(f"{ctl[i]}", False, (0, 0, 0))  # 创建字体
    rel = num_text.get_size()
    face.blit(num_text, (int((lon - rel[0]) / 2), int((bc - rel[1]) / 2)))  # 数字显示居中
    form.blit(face, ((lon + 2) * i + 50, (bc + 3) * 11 + 8))


def text_enter(bc):
    """文字框"""
    top_x = (bc + 3) * 11 # 文本框顶点x
    top_y = 50  # 文本框顶点y
    bc_x = (bc + 3) * 7 + 20  # 文本框宽度
    bc_y = (bc + 3) * 12  # 文本框高度
    ck = 6  # 间隔

    face = pygame.Surface((bc_x, bc_y))
    face.fill(SILVER)
    face.fill(WHITE, (ck // 2, ck // 2, bc_x - ck, bc_y - ck))
    return face, (top_x, top_y)


def timer(face, time1, empty, *args):
    """
    时间难度显示:
    :param face:
    :param time1: 时间
    :param empty: 原始空格数目
    :return:
    """

    num_font = pygame.font.SysFont('幼圆', 18, True)  # 加载系统字体
    info_time = num_font.render(f"运行时间:{time1.get_elapsed()}", False, BLACK)
    w, h = info_time.get_size()
    face.blit(info_time, (5, 5))

    info_level = num_font.render("难度:{:.2f}".format(empty / 81), False, BLACK)
    face.blit(info_level, (15 + w, 5))

    return face


def noter(face, tag):
    """显示笔记提示"""
    num_font = pygame.font.SysFont('幼圆', 18, True)  # 加载系统字体
    note_help1 = num_font.render(f"False 时保存笔记,当前笔记:{tag}", False, RED)
    w1, h1 = note_help1.get_size()
    face.blit(note_help1, (5, 15 + h1))

    # note_tag = num_font.render(f"笔记模式:{tag}", False, BLACK)
    # face.blit(note_tag, (5, 31+10+h1))  #
    return face


def seq_recode(face: pygame.Surface, STEP):
    num_font = pygame.font.SysFont('幼圆', 18, True)  # 加载系统字体
    note_help1 = num_font.render(f"步骤记录:", False, BLACK)
    w1, h1 = note_help1.get_size()
    face.blit(note_help1, (5, 15 + (3 + h1) * 2))
    for i in range(len(STEP)):
        if i != 0:
            step = num_font.render(f"{STEP[i][:3]}", False, BLACK)
            w, h = step.get_size()
            wf, wh = face.get_size()
            if 15 + (3 + h) * (i + 2) < wh:
                face.blit(step, (5, 15 + (3 + h) * (i + 2)))
            else:
                face.blit(step, (15 + w, 16+h+(3 + h) * (i + 2 -22)))
    return face


def win(face: pygame.Surface, u_martix, timer: MyTimer):
    count = 0  # 计数
    num_font = pygame.font.SysFont('幼圆', 18, True)  # 加载系统字体
    win_words = num_font.render(f"游戏结束,恭喜通过", False, BLACK)

    w1, h1 = win_words.get_size()
    for i in range(9):
        for j in range(9):
            if u_martix[i][j] == 0 or u_martix[i][j] == 11:
                count += 1
    if count == 0:
        if Judge(u_martix):
            time1 = timer.get_elapsed()
            timer.pause()
            time1_words = num_font.render(f"耗时:{time1}", False, BLACK)
            wt, ht = time1_words.get_size()
            face.fill(WHITE)
            w, h = face.get_size()
            face.blit(win_words, ((w - w1) // 2, (h - h1) // 2))
            face.blit(time1_words, ((w - wt) // 2, (h - ht) // 2 - h1 - 5))

    return face