# -*- coding: utf-8 -*-

# Dialog implementation generated from reading ui file 'preview.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.

from Template_JSON import Template_JSON
from typing import Text, List
from xml.etree.ElementTree import Element, XML
from PyQt5 import QtCore, QtGui, QtWidgets
import sys, copy
from FCPX_XML import FCPX_XML

# 예능자막을 선택할 수 있는 콤보박스 클래스
class TemplateSelectorCombo(QtWidgets.QComboBox):
    def __init__(self, parent:QtWidgets.QWidget=None, items:List[str]=[], defaultText:str=""):
        if len(items) == 0:
            print("템플릿 파일을 읽을 수 없습니다.")
            raise FileNotFoundError
        
        super(TemplateSelectorCombo, self).__init__(parent)

        for item in items: 
            self.addItem(item)

        defalutIndex = self.findText(defaultText)
        self.setCurrentIndex(defalutIndex)

        # 자막 템플릿 콤보박스에서 다른 값을 선택하면 프리뷰 이미지 변경
        self.currentIndexChanged.connect( lambda: self.SetPreviewImage(self.currentText()) )
            
    # 콤보박스 인덱스 교체 시 프리뷰 이미지 설정하는 함수
    def SetPreviewImage(self, emotion: str):
        # 이미지 불러오기
        label = self.getPreviewLabel()
        template_path = "title-template/" + emotion + "/large.png"
        imgPixmap = QtGui.QPixmap(template_path)

        # 이미지 크롭 및 사이즈 조절
        imgWidth, imgHeight = imgPixmap.width(), imgPixmap.height()
        titleSize =  QtCore.QSize(240, 100)
        titleCenter = QtCore.QPoint(imgWidth/2, 297)
        titleTopLeft = QtCore.QPoint(titleCenter.x() - int(titleSize.width()/2), titleCenter.y() - int(titleSize.height()/2))
        titleRect = QtCore.QRect(titleTopLeft, titleSize)
        imgPixmap = imgPixmap.copy(titleRect).scaled(180, 75, QtCore.Qt.KeepAspectRatio)
        label.setPixmap(QtGui.QPixmap(template_path).copy(titleRect))

    # 해당 객체가 속해 있는 자막 에리어의 프리뷰 이미지를 리턴
    def getPreviewLabel(self):
        previewWidget: QtWidgets.QWidget = self.parent()
        titleGridWidget: QtWidgets.QWidget = previewWidget.parent()
        titleWholeWidget: QtWidgets.QLayout = titleGridWidget.parent()
        previewGroup: QtWidgets.QGroupBox = titleWholeWidget.layout().itemAt(2).widget()
        previewLabel: QtWidgets.QLabel = previewGroup.layout().itemAt(0).widget()
        return previewLabel

class Preview_UI(QtWidgets.QDialog):

    # 초기화: 해당 창의 크기(가로, 세로) 설정
    # 프리뷰 화면이 열릴때 XML 객체도 같이 가지고 올 수 있도록 설정 
    def __init__(self, xml: FCPX_XML, width=800, height=500):
        super().__init__() 
        self.__width = width
        self.__height = height
        self.fcpx_xml: FCPX_XML = xml
        self.modified_xml = copy.deepcopy(self.fcpx_xml)
        self.__xml_saved = True
        self.videoElements = self.modified_xml.loadAllVideoElements()

        # 창 설정 후 출력
        self.setupUi()

    # ui 형성 (가로:900, 세로:400)
    def setupUi(self):
        # 창 자체의 설정
        self.setObjectName("Dialog")
        self.setFixedSize(self.__width, self.__height)

        # TODO: 해당 UI는 영상에 들어간 자막 클립에 따라 가변적인 구조를 가지고 있음. 가변적인 구조의 창 필요
        # TODO: GridLayout 여러 개를 하나의 verticalLayout에 집어넣은 다음 scroolArea로 영역 제한을 할 필요가 있음

        font = QtGui.QFont()
        font.setFamily("Apple SD Gothic Neo")
        self.setFont(font)

        # 레이아웃이 창 안으로 들어감 (전체 레이아웃) - 자막들과 버튼들을 구분하는 영역
        # self.wholeWidget = QtWidgets.QWidget(self)
        self.wholeLayout = QtWidgets.QVBoxLayout(self)
        self.wholeLayout.setObjectName("wholeLayout")
        
        # 스크롤 가능한 영역 삽입
        self.scrollArea = QtWidgets.QScrollArea()
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.wholeLayout.addWidget(self.scrollArea)

        # 자막들이 들어가는 세로 배치 레이아웃 설정
        self.multipleTitleWidget = QtWidgets.QWidget(self.scrollArea)
        self.multipleTitleLayout = QtWidgets.QVBoxLayout()
        self.multipleTitleLayout.setObjectName("verticalLayout")
        self.multipleTitleWidget.setLayout(self.multipleTitleLayout)
        self.scrollArea.setWidget(self.multipleTitleWidget)

        # 각 예능자막 텍스트 태그를 불러오고, 요소를 불러와 UI에 적용하는 과정(Initialize)
        self.initializeTitles()

        # 버튼 2개가 들어갈 레이아웃 설정하고 안에다가 스페이서 3개, 버튼 2개 집어넣음

        self.buttonLayout = QtWidgets.QHBoxLayout()
        self.buttonLayout.setObjectName("horizontalLayout_10")

        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)

        self.buttonLayout.addItem(spacerItem)

        self.closeButton = QtWidgets.QPushButton(self.scrollArea)
        self.closeButton.setObjectName("closeButton")
        self.buttonLayout.addWidget(self.closeButton)
        self.closeButton.setText('닫기')
        self.closeButton.released.connect(self.close)

        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)

        self.buttonLayout.addItem(spacerItem1)

        self.saveButton = QtWidgets.QPushButton(self.scrollArea)
        self.saveButton.setObjectName("saveButton")
        self.buttonLayout.addWidget(self.saveButton)
        self.saveButton.setText('저장')
        self.saveButton.clicked.connect(self.filesave)

        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)

        self.buttonLayout.addItem(spacerItem2)

        self.wholeLayout.addLayout(self.buttonLayout)

        self.retranslateUi(self)
        QtCore.QMetaObject.connectSlotsByName(self)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "XML 프리뷰"))

    # 창을 닫으려 할 때 저장하지 않았으면 저장할 것인지 물음
    def closeEvent(self, event):
        # 테스트용
        if self.__xml_saved is True:
            event.accept()
        else:
            buttonSelected = QtWidgets.QMessageBox.question(self, '수정된 자막이 저장되지 않음', '수정된 자막 파일이 저장되지 않았습니다.\n저장하고 종료하시려면 Save를, 저장하지 않고 종료하시려면 Discard를 눌러주세요.\n종료를 취소하려면 Cancel을 눌러주세요.', QtWidgets.QMessageBox.Save | QtWidgets.QMessageBox.Discard | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel)
            if buttonSelected == QtWidgets.QMessageBox.Save: 
                self.filesave()
                event.accept()
            elif buttonSelected == QtWidgets.QMessageBox.Discard:
                event.accept()
            else:
                event.ignore()

    def readyToSave(self):
        self.__xml_saved = False
    
    def filesave(self):
        videoElement: dict = None
        for i in range(self.multipleTitleLayout.count()):
            videoElement = self.videoElements[i]["node"]
            # 전체 레이아웃에서 저장할 데이터가 있는 레이아웃을 하나씩 추출
            titleWholeWidget: QtWidgets.QWidget = self.multipleTitleWidget.layout().itemAt(i).widget()
            startEndGroup: QtWidgets.QWidget = titleWholeWidget.layout().itemAt(0).widget()
            startEndLayout: QtWidgets.QGridLayout = startEndGroup.layout()
            startWidget: QtWidgets.QWidget = startEndLayout.itemAtPosition(1, 2).widget()
            endWidget: QtWidgets.QHBoxLayout = startEndLayout.itemAtPosition(2, 2).widget()

            templateTitleGroup: QtWidgets.QWidget = titleWholeWidget.layout().itemAt(1).widget()
            templateTitleLayout: QtWidgets.QGridLayout = templateTitleGroup.layout()
            titleTemplateComboWidget = templateTitleLayout.itemAtPosition(1, 2).widget()

            # 시작, 끝 시각 부분의 각 요소 추출
            startHours = int(startWidget.layout().itemAt(0).widget().value())
            startMinutes = int(startWidget.layout().itemAt(2).widget().value())
            startSS = int(startWidget.layout().itemAt(4).widget().value())
            startMS = int(startWidget.layout().itemAt(6).widget().value())
            startDivisor = int(self.startDivisorList[i])

            durationHours = int(endWidget.layout().itemAt(0).widget().value()) - startHours
            durationMinutes = int(endWidget.layout().itemAt(2).widget().value()) - startMinutes
            durationSS = int(endWidget.layout().itemAt(4).widget().value()) - startSS
            durationMS = int(endWidget.layout().itemAt(6).widget().value()) - startMS
            durationDivisor = int(self.durationDivisorList[i])

            # 콤보박스, 텍스트박스의 각 요소 추출
            titleTemplate = titleTemplateComboWidget.layout().itemAt(0).widget().currentText()
            titleText = templateTitleLayout.itemAtPosition(2, 2).widget().toPlainText()

            # video 태그의 offset, duration 속성의 속성값 설정
            offset_text = self.HMSSToSecondsStr(startHours, startMinutes, startSS, startMS, startDivisor)
            duration_text = self.HMSSToSecondsStr(durationHours, durationMinutes, durationSS, durationMS, durationDivisor)

            # 끝 시각이 시작 시각보다 더 앞서면 안내 띄우기, 저장 취소
            if duration_text == None:
                saveErrorMessage = QtWidgets.QMessageBox()
                saveErrorMessage.setIcon(QtWidgets.QMessageBox.Warning)
                saveErrorMessage.setWindowTitle('저장 오류')
                saveErrorMessage.setText('클립의 끝 시각은 시작 시각보다 더 짧을 수 없습니다.\n저장을 취소합니다.')
                saveErrorMessage.setStandardButtons(QtWidgets.QMessageBox.Ok)
                saveErrorMessage.exec_()
                return

            # 기존 video 태그 변환
            self.modified_xml.video_xml_modification(videoElement, offset_text, duration_text, titleTemplate, titleText)

        del self.fcpx_xml
        self.fcpx_xml = self.modified_xml
        self.modified_xml = copy.deepcopy(self.fcpx_xml)
        print("저장 완료")
        self.__xml_saved = True


    # 예능자막 태그를 전부 불러와서 UI에 적용시키는 함수
    def initializeTitles(self):
        # 텍스트박스와 프리뷰 이미지 라벨을 리스트로 초기화
        self.startLineEditList = []
        self.endLineEditList = []
        self.templateSelectorList = []
        self.titlePlainTextEdits = []
        self.previewLabelList = []

        self.startHHLineEditList = []
        self.startMMLineEditList = []
        self.startSSLineEditList = []
        self.startMSLineEditList = []

        self.endHHLineEditList = []
        self.endMMLineEditList = []
        self.endSSLineEditList = []
        self.endMSLineEditList = []

        self.startDivisorList = []
        self.durationDivisorList = []

        # 모든 변환된 예능자막 템플릿 태그(<video> 태그)를 불러오기
            
        videoElement: Element = None #타입 지정 
        for i, videoElement in enumerate(self.videoElements):
            title_text = ''

            # 시작, 끝, 자막템플릿 종류, 자막 텍스트 등 정보를 UI에 표시
            # 전체 위젯
            titleWholeWidget = QtWidgets.QWidget(self.multipleTitleWidget)
            titleWholeLayout = QtWidgets.QHBoxLayout()
            titleWholeLayout.setObjectName("titleWholeLayout")
            titleWholeWidget.setLayout(titleWholeLayout)
            self.multipleTitleLayout.addWidget(titleWholeWidget)

            # # 시작~자막텍스트 위젯
            # titleGridWidget = QtWidgets.QWidget(titleWholeWidget)
            # titleGridLayout = QtWidgets.QGridLayout()
            # titleGridLayout.setObjectName("titleGridLayout")
            # titleGridWidget.setLayout(titleGridLayout)
            # titleWholeLayout.addWidget(titleGridWidget)

            # 시작-끝 모두 담는 그룹박스 위젯
            startEndGroup = QtWidgets.QGroupBox("시작 시각과 끝 시각", self.multipleTitleWidget)
            startEndGrid = QtWidgets.QGridLayout()
            startEndGroup.setLayout(startEndGrid)
            titleWholeLayout.addWidget(startEndGroup)

            # '시작' 라벨
            startLabel = QtWidgets.QLabel(startEndGroup)
            font = QtGui.QFont()
            font.setFamily("Apple SD Gothic Neo")
            startLabel.setFont(font)
            startLabel.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
            startLabel.setObjectName("startLabel")
            startLabel.setText("시작")
            startEndGrid.addWidget(startLabel, 1, 1, 1, 1)

            # 시작 시각 (시:분:초:1/100초)을 표시하고 수정할 수 있는 라인에디트 박스
            # TODO: 시작 시각을 video태그에서 검색한 다음 계산해서 settext 명령어로 텍스트를 삽입
            startWidget = QtWidgets.QWidget(startEndGroup)
            startLayout = QtWidgets.QHBoxLayout()
            startLayout.setObjectName("startLayout")
            startLayout.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
            startWidget.setLayout(startLayout)
            startEndGrid.addWidget(startWidget, 1, 2, 1, 1)

            #시작 시간을 직접 계산해서 텍스트 박스애 넣어 주기
            offset_attrib = videoElement['node'].attrib['offset']            
            offset_attrib = offset_attrib.rstrip('s')                        
            start_numbers = offset_attrib .split('/')                        
            if len(start_numbers) == 1:
                dividend, divisor = int(start_numbers[0]), 1
            else:
                dividend, divisor = int(start_numbers[0]), int(start_numbers[1])   
            self.startDivisorList.append(divisor)                               
            start_second = dividend / divisor

            # 시작 시간, 분, 초, 밀리초 부분을 화살표 없는 스핀박스로 만듬.
            hh, mm, ss, ms = self.secondsToHMSSTuple(start_second)

            # 시각 텍스트박스 
            startHHLineEdit = QtWidgets.QSpinBox(startWidget)
            startHHLineEdit.setMinimum(0)
            startHHLineEdit.setMaximum(99)
            startHHLineEdit.setSingleStep(1)
            startHHLineEdit.setValue(int(hh))
            startHHLineEdit.setAlignment(QtCore.Qt.AlignRight)
            startHHLineEdit.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
            startHHLineEdit.valueChanged.connect(self.readyToSave)
            startLayout.addWidget(startHHLineEdit)
            
            startTimeDividor1 = QtWidgets.QLabel(startWidget)
            startTimeDividor1.setText(":")
            startLayout.addWidget(startTimeDividor1)

            # 분 텍스트 박스
            startMMLineEdit = QtWidgets.QSpinBox(startWidget)
            startMMLineEdit.setMinimum(0)
            startMMLineEdit.setMaximum(59)
            startMMLineEdit.setSingleStep(1)
            startMMLineEdit.setValue(int(mm))
            startMMLineEdit.setAlignment(QtCore.Qt.AlignRight)
            startMMLineEdit.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
            startMMLineEdit.valueChanged.connect(self.readyToSave)
            startLayout.addWidget(startMMLineEdit)

            startTimeDividor2 = QtWidgets.QLabel(startWidget)
            startTimeDividor2.setText(":")
            startLayout.addWidget(startTimeDividor2)
            
            # 초 텍스트 박스
            startSSLineEdit = QtWidgets.QSpinBox(startWidget)
            startSSLineEdit.setMinimum(0)
            startSSLineEdit.setMaximum(59)
            startSSLineEdit.setSingleStep(1)
            startSSLineEdit.setValue(int(ss))
            startSSLineEdit.setAlignment(QtCore.Qt.AlignRight)
            startSSLineEdit.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
            startSSLineEdit.valueChanged.connect(self.readyToSave)
            startLayout.addWidget(startSSLineEdit)

            startTimeDividor3 = QtWidgets.QLabel(startWidget)
            startTimeDividor3.setText(".")
            startLayout.addWidget(startTimeDividor3)

            # 밀리초 텍스트 박스
            startMSLineEdit = QtWidgets.QSpinBox(startWidget)
            startMSLineEdit.setMinimum(0)
            startMSLineEdit.setMaximum(999)
            startMSLineEdit.setSingleStep(1)
            startMSLineEdit.setValue(int(ms))
            startMSLineEdit.setAlignment(QtCore.Qt.AlignRight)
            startMSLineEdit.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
            startMSLineEdit.valueChanged.connect(self.readyToSave)
            startLayout.addWidget(startMSLineEdit)

            # '끝' 라벨
            endLabel = QtWidgets.QLabel(startEndGroup)
            font = QtGui.QFont()
            font.setFamily("Apple SD Gothic Neo")
            endLabel.setFont(font)
            endLabel.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
            endLabel.setObjectName("endLabel")
            endLabel.setText('끝')
            startEndGrid.addWidget(endLabel, 2, 1, 1, 1)

            # 끝 시각 (시:분:초:1/100초)을 표시하고 수정할 수 있는 라인에디트 박스
            # TODO: 끝 시각을 video태그에서 검색한 다음 계산해서 settext 명령어로 텍스트를 삽입
            endWidget = QtWidgets.QWidget(startEndGroup)
            endLayout = QtWidgets.QHBoxLayout()
            endLayout.setObjectName("endlayout")
            endLayout.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
            endWidget.setLayout(endLayout)
            startEndGrid.addWidget(endWidget, 2, 2, 1, 1)

            # 끝 시간을 직접 계산해서 텍스트 박스애 넣어 주기
            offset_attrib = videoElement['node'].attrib['duration']               
            offset_attrib = offset_attrib.rstrip('s')                             
            duration_numbers = offset_attrib .split('/')                        
            if len(duration_numbers) == 1:
                dividend, divisor = int(duration_numbers[0]), 1
            else:
                dividend, divisor = int(duration_numbers[0]), int(duration_numbers[1])   
            self.durationDivisorList.append(divisor)                              
            duration_second = dividend / divisor
            end_second = start_second + duration_second

            # 시작 시간, 분, 초, 밀리초 부분을 화살표 없는 스핀박스로 만듬.
            hh, mm, ss, ms = self.secondsToHMSSTuple(end_second)

            # 시각 텍스트박스 
            endHHLineEdit = QtWidgets.QSpinBox(endWidget)
            endHHLineEdit.setMinimum(0)
            endHHLineEdit.setMaximum(99)
            endHHLineEdit.setSingleStep(1)
            endHHLineEdit.setValue(int(hh))
            endHHLineEdit.setAlignment(QtCore.Qt.AlignRight)
            endHHLineEdit.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
            endHHLineEdit.valueChanged.connect(self.readyToSave)
            endLayout.addWidget(endHHLineEdit)
            
            endTimeDividor1 = QtWidgets.QLabel(endWidget)
            endTimeDividor1.setText(":")
            endLayout.addWidget(endTimeDividor1)

            # 분 텍스트 박스
            endMMLineEdit = QtWidgets.QSpinBox(endWidget)
            endMMLineEdit.setMinimum(0)
            endMMLineEdit.setMaximum(59)
            endMMLineEdit.setSingleStep(1)
            endMMLineEdit.setValue(int(mm))
            endMMLineEdit.setAlignment(QtCore.Qt.AlignRight)
            endMMLineEdit.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
            endMMLineEdit.valueChanged.connect(self.readyToSave)
            endLayout.addWidget(endMMLineEdit)

            endTimeDividor2 = QtWidgets.QLabel(endWidget)
            endTimeDividor2.setText(":")
            endLayout.addWidget(endTimeDividor2)
            
            # 초 텍스트 박스
            endSSLineEdit = QtWidgets.QSpinBox(endWidget)
            endSSLineEdit.setMinimum(0)
            endSSLineEdit.setMaximum(59)
            endSSLineEdit.setSingleStep(1)
            endSSLineEdit.setValue(int(ss))
            endSSLineEdit.setAlignment(QtCore.Qt.AlignRight)
            endSSLineEdit.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
            endSSLineEdit.valueChanged.connect(self.readyToSave)
            endLayout.addWidget(endSSLineEdit)

            endTimeDividor3 = QtWidgets.QLabel(endWidget)
            endTimeDividor3.setText(".")
            endLayout.addWidget(endTimeDividor3)

            # 밀리초 텍스트 박스
            endMSLineEdit = QtWidgets.QSpinBox(endWidget)
            endMSLineEdit.setMinimum(0)
            endMSLineEdit.setMaximum(999)
            endMSLineEdit.setSingleStep(1)
            endMSLineEdit.setValue(int(ms))
            endMSLineEdit.setAlignment(QtCore.Qt.AlignRight)
            endMSLineEdit.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
            endMSLineEdit.valueChanged.connect(self.readyToSave)
            endLayout.addWidget(endMSLineEdit)


            # 2열과 3열 사이 Spacer 설정
            # spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
            # titleGridLayout.addItem(spacerItem4, 1, 3, 1, 1)
            # spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
            # titleGridLayout.addItem(spacerItem5, 2, 3, 1, 1)


            # 자막 템플릿의 스타일과 텍스트를 수정하는 요소를 담은 그룹박스
            templateTitleGroup = QtWidgets.QGroupBox("스타일과 텍스트", titleWholeWidget)
            templateTitleGrid = QtWidgets.QGridLayout()
            templateTitleGroup.setLayout(templateTitleGrid)
            titleWholeLayout.addWidget(templateTitleGroup)

            # '자막 템플릿' 라벨
            titleTemplateLabel = QtWidgets.QLabel(templateTitleGroup)
            font = QtGui.QFont()
            font.setFamily("Apple SD Gothic Neo")
            titleTemplateLabel.setFont(font)
            titleTemplateLabel.setAlignment(QtCore.Qt.AlignCenter)
            titleTemplateLabel.setObjectName("titleTemplateLabel")
            titleTemplateLabel.setText("자막 템플릿")
            templateTitleGrid.addWidget(titleTemplateLabel, 1, 1, 1, 1)

            # 자막 템플릿을 선택할 수 있는 콤보박스와 이를 감싸는 레이아웃
            titleTemplateComboWidget = QtWidgets.QWidget(templateTitleGroup)
            titleTemplateComboLayout = QtWidgets.QHBoxLayout()
            titleTemplateComboLayout.setObjectName("titleTemplateComboLayout")
            titleTemplateComboWidget.setLayout(titleTemplateComboLayout)
            templateTitleGrid.addWidget(titleTemplateComboWidget, 1, 2, 1, 1)

            # 자막 템플릿을 콤보박스에 추가 
            template_list = self.fcpx_xml.get_all_template()
            template_name_list = [template["video"]["name"] for template in template_list]
            template_name = videoElement["node"].attrib["name"]
            templateSelector = TemplateSelectorCombo(titleTemplateComboWidget, template_name_list, template_name)

            # 자막 템플릿을 바꿨을때 저장되지 않은 상태로 바꾸기
            templateSelector.currentIndexChanged.connect(self.readyToSave)
            titleTemplateComboLayout.addWidget(templateSelector)

            # 오른쪽에 Spacer 배치
            spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
            titleTemplateComboLayout.addItem(spacerItem5)

            # '자막 텍스트' 라벨
            titleTextLabel = QtWidgets.QLabel(templateTitleGroup)
            font = QtGui.QFont()
            font.setFamily("Apple SD Gothic Neo")
            titleTextLabel.setFont(font)
            titleTextLabel.setAlignment(QtCore.Qt.AlignCenter)
            titleTextLabel.setObjectName("titleTextLabel")
            titleTextLabel.setText("자막 텍스트")
            templateTitleGrid.addWidget(titleTextLabel, 2, 1, 1, 1)

            # 자막 텍스트가 출력되는 텍스트박스
            titlePlainTextEdit = QtWidgets.QPlainTextEdit(templateTitleGroup)
            titlePlainTextEdit.setObjectName("titlePlainTextEdit")
            for param in videoElement["node"].iter():
                if param.attrib["name"] == "Text":
                    titlePlainTextEdit.setPlainText(param.attrib["value"])
                    title_text = param.attrib["value"]
            titlePlainTextEdit.textChanged.connect(self.readyToSave)
            templateTitleGrid.addWidget(titlePlainTextEdit, 2, 2, 1, 1)

            # 미리보기 이미지를 보여주는 그룹박스
            previewGroup = QtWidgets.QGroupBox("템플릿 미리보기 이미지", titleWholeWidget)
            previewLayout = QtWidgets.QHBoxLayout()
            previewGroup.setLayout(previewLayout)
            titleWholeLayout.addWidget(previewGroup)
            
            # 미리보기 이미지 라벨
            previewLabel = QtWidgets.QLabel(previewGroup)
            previewLabel.setObjectName("previewLabel")
            previewLabel.setText("Preview Image (Alternative Text)")
            previewLayout.addWidget(previewLabel)

            # 프리뷰 이미지 지정
            templateSelector.SetPreviewImage(template_name)
            
            # 디버깅 용도: 처리되고 있는 자막 표시
            print("showing titles", title_text)

    #초를 시분초로 바꾸는 함수
    def secondsToHMSS(self, seconds: float) -> str:
        hours = int(seconds // 3600)
        minuts = int( ( seconds - (hours*3600) ) // 60 )
        ss = int( seconds % 60 )

        hours = str(hours).zfill(2)
        minuts = str(minuts).zfill(2)
        ss = str(ss).zfill(2)
        ms = "{:.3f}".format(seconds)[-3:]

        return hours + ":" + minuts + ":" + ss + "." + ms

    #초를 시분초로 바꾸는 함수 (튜플 변환)
    def secondsToHMSSTuple(self, seconds: float) -> tuple:
        hours = int(seconds // 3600)
        minuts = int( ( seconds - (hours*3600) ) // 60 )
        ss = int( seconds % 60 )

        hours = str(hours).zfill(2)
        minuts = str(minuts).zfill(2)
        ss = str(ss).zfill(2)
        ms = "{:.3f}".format(seconds)[-3:]

        return hours, minuts, ss, ms
    
    def HMSSToSecondsStr(self, hours: int, minutes: int, ss: int, ms: int, divisor: int) -> str:
        seconds = float(hours) * 3600 + float(minutes) * 60 + float(ss) + float(ms) * 0.001
        if seconds <= 0:
            return None
        seconds = int(seconds * divisor)
        seconds = str(seconds) + '/' + str(divisor) + 's'
        return seconds





# 메인함수 실행
def main() -> int:
    app = QtWidgets.QApplication(sys.argv)
    preview_xml = FCPX_XML('contest_woowakgood_edit.fcpxml')
    preview_ui = Preview_UI(preview_xml, 1200, 700)
    preview_ui.show()
    sys.exit(app.exec_())

    return 0

# 이 코드가 처음으로 실행될 경우 메인함수 실행
if __name__ == '__main__':
    print("program exited with code", main())
    
