import xlrd as excel
from tkinter import *
import tkinter.messagebox as msgbox
import random
import sys
import win32con, win32api
import winsound
import time

filename = "./data/names.xls"
configname = "./data/config.data"
selname = "./assets/sel.wav"
procname = "./assets/proc.wav"
iconname = "./assets/点名器.ico"
gui_size = "620x200"

sound = True

gui = Tk()

gui.withdraw()
gui.title("点名器")
gui.geometry(gui_size)
gui.resizable(0,0)
gui.configure(bg = "white")

try:
    file = open(iconname)
    file.close()
    gui.iconbitmap(iconname)
except IOError:
    if not msgbox.askokcancel('资源文件错误', '在 ./assets目录下未能找到 点名器.ico 文件,点击「确定」将加载默认图标,点击「取消」以关闭程序'):
        sys.exit()

try:
    file = open(selname)
    file.close()
    file = open(procname)
    file.close()
except IOError:
    if msgbox.askokcancel('资源文件错误', '在 ./assets目录下未能找到音频文件,点击「确定」将关闭声音,点击「取消」以关闭程序'):
        sound = False
    else:
        sys.exit()

class Student(object):
    name = ""
    subject = ""
    id = ""
    class_name = ""

    def __init__(self,id,class_name,subject,name):
        self.id = id
        self.class_name = class_name
        self.subject = subject
        self.name = name

protection_override = False
up_percent = 30
down_persent = 40
elim_rows = 1
percent_override = True

try:
    with excel.open_workbook(filename) as excel_data:
        table = excel_data.sheets()[0]
        # win32api.SetFileAttributes(filename,win32con.FILE_ATTRIBUTE_HIDDEN)
except FileNotFoundError:
    msgbox.showerror('找不到数据库文件', '在相同目录下未能找到 names.xls 文件,请确认您的文件存在')
    sys.exit()

try:
    cols = table.ncols
    rows = table.nrows
    assert cols == 4
    assert rows > 1
except AssertionError:
    msgbox.showerror('数据库文件格式不正确', '数据库文件内行/列数不合法,请确认数据库文件拥有超过1的行数和等于4的列数,当前行数:' + str(rows) + ' 当前列数:' + str(cols))
    sys.exit()

elim_id = []
up_id = []
down_id = []

try:
   with open(configname,'r') as file:
        # win32api.SetFileAttributes(configname,win32con.FILE_ATTRIBUTE_HIDDEN)
        config = file.read().splitlines()
        for unit in config:
            temp = unit.split(",")
            if temp[1] == '0':
                elim_id.append(int(temp[0]))
            elif temp[1] == '+':
                up_id.append(int(temp[0]))
            elif temp[1] == "-":
                down_id.append(int(temp[0]))
            else:
                pass
except:
    percent_override = False

up_percent = len(up_id) * 5 if len(up_id) <= 6 else 30
down_percent = len(down_id) * 8 if len(down_id) <= 5 else 40

gui.deiconify()

students = []
classes = []
subjects = []
filter = []

last_choice = ""

# print("读取数据库成功:" + str(cols) + "列 " + str(rows) + "行")

for i in range(elim_rows,rows):
    tmp_list = [str(table.cell_value(i,j)) for j in range(0,cols)]
    if (int(float(tmp_list[0])) not in elim_id):
        student = Student(tmp_list[0],tmp_list[1],tmp_list[2],tmp_list[3])
        students.append(student)

cur_stu = []

cur_stu = students[:]

for student in students:
    if student.class_name not in classes:
        classes.append(student.class_name)
    if student.subject not in subjects:
        subjects.append(student.subject)

cur_name = StringVar()

def upd_name(name):
    cur_name.set(name)

upd_name("")

listbox = Listbox(gui, selectmode = MULTIPLE, height = 5)

for tmp_class in classes:
    listbox.insert("end",tmp_class)

def sel_class(flag = 1):
    global filter, listbox, classes, cur_stu, students, percent_override
    filter.clear()
    for selection in listbox.curselection():
        # print(selection)
        filter.append(classes[selection])
    # print(filter)
    if filter:
        if flag:
            msgbox.showinfo('班级选择已应用', '已应用当前班级选择', parent=gui)
            percent_override = False
        cur_stu.clear()
        for student in students:
            if student.class_name in filter:
                # print(student.name)
                cur_stu.append(student)
    else:
        if flag:
            msgbox.showwarning('班级选择已应用', '当前设置会选择所有班级的名单,这样对吗?', parent=gui)
            percent_override = False
        filter = classes[:]
        cur_stu = students[:]



def choose():
    global last_choice, cur_stu
    sel_class(0)
    # 触发30%概率,从up中挑选
    if (random.randint(1,100) < up_percent and percent_override):
        protection_override = True;
        temp = []
        for student in cur_stu:
            if int(float(student.id)) in up_id:
                temp.append(student)
        cur_stu = temp[:]
    elif (random.randint(1,100) < down_persent and percent_override):
        protection_override = True;
        temp = [];
        for student in cur_stu:
            if int(float(student.id)) not in down_id:
                temp.append(student)
        cur_stu = temp[:]
    else:
        protection_override = False
    if not cur_stu:
        protection_override = False
        sel_class(0)
    choice = random.choice(cur_stu)
    # print(choice.name)
    counter = 0;
    while (last_choice == choice.name and (not protection_override) and (len(cur_stu) > 1)) or choice.id in elim_id:
        choice = random.choice(cur_stu)
        counter = counter + 1
        if counter >= 100:
            break
        # print(choice.name)
    upd_name(choice.name)
    class_label.config(text = choice.class_name)
    subject_label.config(text = choice.subject)
    last_choice = choice.name
    if sound:
        winsound.PlaySound(selname, winsound.SND_ASYNC | winsound.SND_FILENAME)

startrandom = Button(gui, text = "立刻摇人!", font = ("宋体", 17, "bold"), height = 2, fg = "red", command = choose, bg = "white")

setclass = Button(gui, text = "应用班级选用", font = ("宋体", 17), height = 2, command = sel_class, bg = "white")

name_label = Label(gui, textvariable = cur_name, font = ("宋体", 30, "bold"), width = 20, bg = "white", fg = "blue")
class_label = Label(gui, text = "", font = ("宋体", 15), width = 20, bg = "white")
subject_label = Label(gui, text = "", font = ("宋体", 15), width = 20, bg = "white")

class_label.grid(row = 2, column = 1, sticky = N+S+E+W)
subject_label.grid(row = 2, column = 2, sticky = N+S+E+W)
name_label.grid(row = 1, column = 1, sticky = N+S)
listbox.grid(row = 1, column = 2, sticky = N+S)
startrandom.grid(row = 3, column = 1, sticky = N+S+E+W)
setclass.grid(row = 3, column = 2, sticky = N+S+E+W)

gui.mainloop()