import openshot
import os
import re
import time
import pysrt
import shutil
from datetime import datetime
from PIL import Image,ImageDraw,ImageFont
import gspread
import pandas as pd
import csv
from oauth2client.service_account import ServiceAccountCredentials 

def auth_gss_client(path, scopes):
    credentials = ServiceAccountCredentials.from_json_keyfile_name(path, scopes)
    return gspread.authorize(credentials)


auth_json_path = 'noted-tesla-348011-74f70c9caeda.json' #由剛剛建立出的憑證，放置相同目錄以供引入
gss_scopes = ['https://spreadsheets.google.com/feeds'] #我們想要取用的範圍
gss_client = auth_gss_client(auth_json_path, gss_scopes) #呼叫我們的函式

#從剛剛建立的sheet，把網址中 https://docs.google.com/spreadsheets/d/〔key〕/edit 的 〔key〕的值代入 
spreadsheet_key_path = '1LU5O8-oAotIFGPI9STPbElO0NHGA6eynuv9sYz81aOw'
wks = gss_client.open_by_key(spreadsheet_key_path).sheet1

def srt_to_sheet(srt_file):
    subs = pysrt.open(srt_file)
    wks.clear()

    index = 0
    for context in subs:
        index = context.index

    cell_list = wks.range('A1:C'+str(index))
    
    number = 0
    for context in subs:
        #print(context.start.minutes*60+context.start.seconds+ 0.001*context.start.milliseconds)
        index = context.index
        end = context.end
        start = context.start
        #print('A'+str(index))
        cell_list[number].value = str(start)
        cell_list[number+1].value = str(end)
        cell_list[number+2].value = str(context.text)
        number = number+3
    
    wks.update_cells(cell_list)

def sheet_to_text(text_font):
    ck_anchor = cKey(0, 255, 0, 320)
    text_form = []
    for context in wks.get_all_values():
        #print(context.start.minutes*60+context.start.seconds+ 0.001*context.start.milliseconds)
        start = datetime.strptime(context[0], "%H:%M:%S,%f")
        end = datetime.strptime(context[1], "%H:%M:%S,%f") - datetime.strptime(context[0], "%H:%M:%S,%f")
        end_timeStamp=end.seconds+0.000001*end.microseconds
        start_timeStamp=start.minute*60+start.second+ 0.000001*start.microsecond
        text_form.append({'text':context[2],'start':start_timeStamp,'end':end_timeStamp,'size':36,'font':text_font})
        #print({'text':context[2],'start':start_timeStamp,'end':end_timeStamp,'size':36,'font':text_font})

def cKey(r,g,b,fuzz):
    col=openshot.Color()
    col.red=openshot.Keyframe(r)
    col.green=openshot.Keyframe(g)
    col.blue=openshot.Keyframe(b)
    return openshot.ChromaKey(col, openshot.Keyframe(fuzz))

def video_writer_init(path):
    w = openshot.FFmpegWriter(path)
    w.SetAudioOptions(True, "aac", 44100, 2, openshot.LAYOUT_STEREO, 3000000)
    w.SetVideoOptions(True, "libx264", openshot.Fraction(30000, 1000), 1280, 720,
        openshot.Fraction(1, 1), False, False, 3000000)
    return w

def video_photo_clip(video=None,layer=None, position=None, end=None
    ,scale_x=1,scale_y=1,location_x=0,location_y=0,ck=None,audio=True):
    clip = openshot.Clip(video)
    clip.Layer(layer)
    clip.Position(position)
    clip.End(end)
    clip.scale_x=openshot.Keyframe(scale_x)
    clip.scale_y=openshot.Keyframe(scale_y)
    clip.location_x=openshot.Keyframe(location_x)
    clip.location_y=openshot.Keyframe(location_y)
    
    if ck!=None:
        clip.AddEffect(ck)
    if audio==True:
        clip.has_audio=openshot.Keyframe(1)
    else:
        clip.has_audio=openshot.Keyframe(0)
    return clip

def trim_punctuation(s):
    pat_block = u'[^\u4e00-\u9fff0-9a-zA-Z]+'
    pattern = u'([0-9]+{0}[0-9]+)|{0}'.format(pat_block)
    res = re.sub(pattern, lambda x: x.group(1) if x.group(1) else u" " ,s)
    return res

#文字轉圖片
def txt2image(content, save_target,lang='zh',size=26,fon="font/DFT_B7.ttc"):
    unicode_text = trim_punctuation(content)
    font = ''
    if lang=='zh':
        font = ImageFont.truetype(font=fon, size=size)
    else :
        font = ImageFont.truetype(font="font/arial.ttf", size=size)
    
    W, H = (1280,500)
    canvas = Image.new('RGB', (W, H), "#00FF00")
    draw = ImageDraw.Draw(canvas)
    
    text= content
    if "\n" in text:
        w, h = draw.textsize(text.split("\n")[0],font = font)
        #draw.text(((W-w)/2,0), text[0:18],'black', font)
        text_border(draw,(W-w)/2,0,text.split("\n")[0],font,'black','white')
        w, h = draw.textsize(text.split("\n")[1],font = font)
        #draw.text(((W-w)/2,h+2), text[18:],'black', font)
        text_border(draw,(W-w)/2,h+2,text.split("\n")[1],font,'black','white')
    else:
        w, h = draw.textsize(content,font = font)
        #draw.text(((W-w)/2,0), text,'black', font)
        text_border(draw,(W-w)/2,0,text,font,'black','white')
    canvas.save(save_target, "PNG")

def text_border(draw,x,y,text,font,shadowcolor,fillcolor):
    draw.text((x-1, y), text, font=font, fill=shadowcolor)
    draw.text((x+1, y), text, font=font, fill=shadowcolor)
    draw.text((x, y-1), text, font=font, fill=shadowcolor)
    draw.text((x, y+1), text, font=font, fill=shadowcolor)

    draw.text((x-1, y+1), text, font=font, fill=shadowcolor)
    draw.text((x+1, y-1), text, font=font, fill=shadowcolor)
    draw.text((x-1, y-1), text, font=font, fill=shadowcolor)
    draw.text((x+1, y+1), text, font=font, fill=shadowcolor)
    # thicker border
    draw.text((x-2, y-2), text, font=font, fill=shadowcolor)
    draw.text((x+2, y-2), text, font=font, fill=shadowcolor)
    draw.text((x-2, y+2), text, font=font, fill=shadowcolor)
    draw.text((x+2, y+2), text, font=font, fill=shadowcolor)

    # now draw the text over it
    draw.text((x, y), text, font=font, fill=fillcolor)

def srt_to_csv(srt_file):
    subs = pysrt.open(srt_file)
    csv_file = srt_file.split('.')[0] + ".csv"
    with open(csv_file, 'w', newline='') as csvfile:
        # 建立 CSV 檔寫入器
        writer = csv.writer(csvfile)
        for context in subs:
            writer.writerow([context.index, context.start,context.end, context.text])
    return csv_file

def csv_to_text(csv_file,text_font):
    text_form = []
    with open(csv_file, newline='') as csvfile:

        # 讀取 CSV 檔案內容
        rows = csv.reader(csvfile)

        # 以迴圈輸出每一列
        for row in rows:
            start = datetime.strptime(row[1], "%H:%M:%S,%f")
            end = datetime.strptime(row[2], "%H:%M:%S,%f") - datetime.strptime(row[1], "%H:%M:%S,%f")
            end_timeStamp=end.seconds+0.000001*end.microseconds
            start_timeStamp=start.minute*60+start.second+ 0.000001*start.microsecond
            text_form.append({'text':row[3],'start':start_timeStamp,'end':end_timeStamp,'size':36,'font':text_font})
    
    return text_form

def text_to_short_vedio(mp4_file = "input/example/test3.mp4",sound_file = None
                        ,vedio_time = 30,output_filename="output/demo.mp4",text_font = "font/DFT_B7.ttc",mode = "csv",correct = False):
    t = openshot.Timeline(1280, 720, openshot.Fraction(30000, 1000), 44100, 2, openshot.LAYOUT_STEREO)
    t.Open()
    
    # 去背參數
    ck = cKey(0, 254, 0, 270)
    ck_anchor = cKey(0, 255, 0, 320)

    anchor = openshot.FFmpegReader(mp4_file)
    anchor.Open()
    anchor_clip = video_photo_clip(video=anchor,layer=2,scale_x=1,scale_y=1,
            location_x=0,location_y=0,position=0, end=vedio_time,audio=True)
    t.AddClip(anchor_clip)
    anchor.Close()
    number = 0

    sound_srt_file = ""
    text_form = []

    if sound_file==None:
        if mode!= "google":
            sound_file = mp4_file
            correct = False

    if ".csv" in sound_file :
        correct = True
        mode = "csv"

    #音檔自動產生srt(逐字稿)
    if not correct: # 未修正過的、需要產生SRT檔
        cmd = "autosub -S zh-TW -D zh-TW " + sound_file
        os.system(cmd)
        sound_srt_file = sound_file.split('.')[0] + ".srt"

        if mode == "google" :
            srt_to_sheet(sound_srt_file)
            text_form = sheet_to_text(text_font)
        elif mode == "csv" :
            csv_file = srt_to_csv(sound_srt_file)
            text_form = csv_to_text(csv_file,text_font)
    else:
        if ".srt" in sound_file:
            sound_srt_file = sound_file
            if mode == "google" :
                srt_to_sheet(sound_srt_file)
                text_form = sheet_to_text(text_font)
            elif mode == "csv" :
                csv_file = srt_to_csv(sound_srt_file)
                text_form = csv_to_text(csv_file,text_font)
        else:
            if mode == "google" :
                text_form = sheet_to_text(text_font)
            elif mode == "csv" :
                csv_file = sound_file
                text_form = csv_to_text(csv_file,text_font)

    #產生字幕
    try:
        number = 0
        for text_tmp in text_form:
            file_name = "tmp/save_target_" + str(number) + ".png"
            txt2image(text_tmp['text'], file_name,lang='zh',size = text_tmp['size'],fon = text_tmp['font'])
            exec('text_anchor_{} = openshot.QtImageReader("tmp/save_target_{}.png")'.format(number,number))
            exec('text_anchor_{}.Open()'.format(number))
            exec('text_anchor_{}.Open()'.format(number))
            exec('text_anchor_clip_{} = video_photo_clip(video=text_anchor_{},layer=4,scale_x=1,scale_y=1,\
                        location_x=0,location_y=0.67,position=text_tmp["start"], end=text_tmp["end"],ck=ck_anchor,audio=True)'.format(number,number))
            exec('t.AddClip(text_anchor_clip_{})'.format(number))
            exec('text_anchor_{}.Close()'.format(number))
            number = number+1
    except:
        print("無法開啟srt檔案(字幕產生失敗)")

    w = video_writer_init(output_filename)
    w.Open()

    frames = int(t.info.fps)*int(vedio_time)
    for n in range(frames):
        f=t.GetFrame(n)
        w.WriteFrame(f)

    t.Close()
    w.Close()

    #刪除暫存檔案
    shutil.rmtree('tmp')
    os.mkdir('tmp')


if __name__ == '__main__':
    
    #text_to_short_vedio(mp4_file = "input/example/導盲犬_投影片2.mp4",
        #sound_file ='input/example/導盲犬_投影片2.srt',vedio_time =110,text_font ="font/DFT_R7.ttc")
    file = srt_to_csv('input/example/導盲犬_投影片2.srt')
    text = csv_to_text(file,"font/DFT_R7.ttc")
    print(text)
    

