#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#先在say_txt.csv設定刺激詞語或句子，之後會在recwav檔案夾中存相應音檔，音檔會覆蓋，測完後應備份
#第30行設定字型, 系統中要安裝 '文鼎標楷注音'才會顯示注音
#pyinstaller -F --icon=rt.ico say_txt.py

import random
import tkinter
from tkinter import *
import tkinter.font as font
from tkinter import messagebox
from tkinter.filedialog import askopenfilename
import sounddevice as sd
import soundfile as sf
from scipy.io.wavfile import write
import pandas

seconds = 2
fs = 22050
wavpath='txtrecwav'
BACKGROUND_COLOR = "#B1DDC6"
FOREGROUND_COLOR = "black"
current_card={}
to_show={}
itemno=0
showno=0
filename1=''
csvfile="say_txt.csv"
total_num=0 
to_show=[]

window= Tk()
window.title("我會說")
myFont1 = font.Font(size=20)
myFont2 = font.Font(family='文鼎標楷注音',size=64,weight="bold") #設定字型
swidth = window.winfo_screenwidth()-20
sheight = window.winfo_screenheight()-10
print("Screen width:", swidth)
print("Screen height:", sheight)
window.geometry(f'{swidth}x{sheight}')
#window.geometry("1000x700")
window.geometry('+0+0')
window.config(padx=50, pady=50, bg = BACKGROUND_COLOR)
window.resizable(False,False) #Make window non-resizable, optimal view
mycanvas= Canvas(width=swidth/1.6, height=sheight/1.6)
mycanvas.pack()

introword='請先按[下一題]看題目，再按[V]錄音，之後可按[聽聽看]聽錄音。'
card_word=mycanvas.create_text(swidth/3,200, text=str(introword), font=myFont1, width = 800)
showno_text=mycanvas.create_text(10,10, text=str(showno), font=myFont1, width = 20)

label_text = Label(window, text = '錄音秒數:',width = 7)
label_text.place(x=0, y=0)

myentry = Entry(window, bd =1,width = 3 )
myentry.place(x=66, y=0)
myentry.insert(-1, '2')

def csvread():
    global csvfile, total_num, to_show  
    try:
        data=pandas.read_csv(csvfile)
        to_show = data.to_dict(orient="records")
        #print(to_show)    
    except FileNotFoundError:
        original_data= pandas.read_csv("say_txt.csv",encoding="utf-8")
        to_show=original_data.to_dict(orient="records")
    total_num=len(to_show)
    
csvread()    

def nextsti():
    global current_card, itemno, showno,card_word,total_num,to_show
    if showno >= total_num:
        showno = total_num
    else: 
        showno += 1
    current_card= to_show[showno-1]
    #print(current_card)
    word=current_card["stiword"]
    itemno=current_card["itemno"]
    mycanvas.itemconfig(card_word, text=str(word),font=myFont2, justify='center')
    mycanvas.itemconfig(showno_text, text=str(showno))
 
def presti():
    global current_card, itemno, showno,card_word,total_num,to_show
    if showno<=1:
        showno=1
    else: 
        showno -= 1
    current_card= to_show[showno-1]
    #print(current_card)
    word=current_card["stiword"]
    itemno=current_card["itemno"]
    mycanvas.itemconfig(card_word, text=str(word),font=myFont2, justify='center')
    mycanvas.itemconfig(showno_text, text=str(showno))
          
def rec():
    global seconds, samplerate, fs, wavpath, itemno, filename1 
    if myentry.get()!= '':
        seconds = int(myentry.get())
    myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels = 1 ,dtype='int16')
    sd.wait()
    filename1 = "%s/q_%s.wav" %(wavpath,str(itemno))
    write(filename1, fs, myrecording)

def playrec():
    global filename1
    data, fs = sf.read(filename1, dtype='int16')
    sd.play(data, fs)
    sd.wait()
    if next_button["state"] == DISABLED:
        messagebox.showinfo('The end', '測試完畢，請檢視錄音音檔!')
'''
def playsti():
    global stifilename
    data, fs = sf.read(stifilename, dtype='int16')
    sd.play(data, fs)
''' 

ok_image = PhotoImage(file="ok.png")
ok_button = Button(window,image=ok_image,highlightthickness= 0, command=rec) 
ok_button.place(x=swidth/2, y=sheight-250, width=130, height=110)

next_button = Button(window,text='下一題',highlightthickness= 2,bg = "#9fede5", font=("Ariel", 20, 'bold'),command=nextsti) 
#next_button['font'] = myFont1
next_button.place(x=swidth-swidth/5, y=sheight-250, width=160, height=110)

pre_button = Button(window,text='上一題',highlightthickness= 2,bg = "#9fede5", font=("Ariel", 20, 'bold'),command=presti) 
#next_button['font'] = myFont1
pre_button.place(x=-10, y=sheight-250, width=100, height=80)

#listen_button1 = Button(window,text='聽刺激',highlightthickness= 0, command=playsti) 
#listen_button1.place(x=500, y=580, width=100, height=60)

listen_button2=Button(window,text='聽聽看',highlightthickness= 1, bg = "#f5beb0",command=playrec) 
listen_button2['font'] = myFont1
listen_button2.place(x=swidth/2+200, y=sheight-250, width=120, height=100)


def instruction():
        in_text='1.文字刺激檔預設為say_txt.csv，可用Setup manu第1項改為其他檔案， 但格式須和say_txt.csv一致(如utf-8、檔頭等)。\n 2.預設音檔存檔是q_數字.wav，存於txtrecwav目錄中。\n 3.題項呈現順序可用Setup manu第2項改隨機呈現。\n 4.錄音時若文字過長，該題需改錄音時間，預設為2秒、取樣頻率22kHz'
        messagebox.showinfo('注意事項',in_text)
    
def copyrightjj():
    messagebox.showinfo('開發','此程式為國立高雄師範大學 聽語研究所 鄭靜宜教授開發，\n 敬請指教，jengyi12345@gmail.com')   

def popupwin1():
    global csvfile
    csvfile = askopenfilename(parent=window,filetypes= (("csv files","*.csv"),("all files","*.*")))
    if (csvfile=='') or (csvfile is None) : 
        csvfile = 'say_txt.csv'
    print(csvfile)
    csvread()
    messagebox.showinfo('資料檔', '資料檔為 {} !'.format(csvfile))

def popupwin2():
    global to_show
    MsgBox = messagebox.askquestion('題項順序?','題項順序是否要改為隨機順序?')
    if MsgBox == 'yes':
        random.shuffle(to_show) 
    else:
        pass

def manuq():
    menubar = Menu()
    filemenu = Menu(menubar,tearoff=0)
    filemenu.add_command(label="設定資料檔(csv)",command=popupwin1)
    filemenu.add_command(label="順序設定",command=popupwin2)
    menubar.add_cascade(label="Setup",menu=filemenu)

    helpmenu = Menu(menubar,tearoff=0)
    helpmenu.add_command(label="使用說明",command=instruction)
    helpmenu.add_command(label="版權",command=copyrightjj)
    helpmenu.add_command(label="退出",command=window.quit)
    menubar.add_cascade(label="Help",menu=helpmenu)
    window.config(menu=menubar)


manuq()
window.mainloop()