class MainWindow(QWidget):
    
	def __init__(self, inList):
		super().__init__()
		self.inList = inList
		self.nameFrom = 'Folder'
		self.codec = 'utvideo'
		self.alpha = False
		self.frameRate = 24
		self.defaulStyle = ''
		
		self.okIcon = QIcon(self.style().standardIcon(QStyle.SP_CustomBase))
		self.okPix = QPixmap(self.okIcon.pixmap(QSize(13, 13)))
		self.goodIcon = QIcon(self.style().standardIcon(QStyle.SP_DialogApplyButton))
		self.goodPix = QPixmap(self.goodIcon.pixmap(QSize(13, 13)))
		self.badIcon = QIcon(self.style().standardIcon(QStyle.SP_MessageBoxCritical))
		self.badPix = QPixmap(self.badIcon.pixmap(QSize(13, 13)))
		self.processingIcon = QIcon(self.style().standardIcon(QStyle.SP_ArrowRight))
		self.processingPix = QPixmap(self.processingIcon.pixmap(QSize(13, 13)))
		self.removeIcon = QIcon(self.style().standardIcon(QStyle.SP_DockWidgetCloseButton))
		self.removePix = QPixmap(self.removeIcon.pixmap(QSize(19, 19)))
		self.folderIcon = QIcon(self.style().standardIcon(QStyle.SP_FileDialogNewFolder))
		self.folderPix = QPixmap(self.folderIcon.pixmap(QSize(19, 19)))
		
		self.pbList = []
		self.chList = []
		self.lblList = []
		self.rmbList = []
		#self.newFolders = []
		self.initUI()

	def initUI(self):
		self.resize(720, 300)
		self.setWindowTitle('FFMpeg Python Compressor')
		self.verticalLayout = QVBoxLayout(self)
		self.verticalLayout.setContentsMargins(11, 11, 11, 11)
		self.verticalLayout.setSpacing(11)
		
		#COMBOBOX LABELS
		self.gridLayoutControlls = QGridLayout()
		self.codecLabel = QLabel('Codec', self)
		self.codecLabel.setMinimumHeight(13)
		self.alphaLabel = QLabel('Alpha' , self)
		self.alphaLabel.setMinimumHeight(13)
		self.frameRateLabel = QLabel('Frame Rate' , self)
		self.frameRateLabel.setMinimumHeight(13)
		self.gridLayoutControlls.addWidget(self.codecLabel, 0, 0, 1, 1)
		self.gridLayoutControlls.addWidget(self.alphaLabel, 0, 1, 1, 1)
		self.gridLayoutControlls.addWidget(self.frameRateLabel, 0, 2, 1, 1)
		
		#COMBOBOXES AND COMPRESS BUTTON
		self.codecComboBox = QComboBox(self)
		self.codecComboBox.setMinimumSize(80,23)
		self.codecComboBox.addItem("UT Video")
		self.codecComboBox.activated[str].connect(self.chooseCodec)
		
		self.alphaComboBox = QComboBox(self)
		self.alphaComboBox.setMinimumSize(80,23)
		self.alphaComboBox.addItem("No Alpha")
		self.alphaComboBox.addItem("with Alpha")
		self.alphaComboBox.activated[str].connect(self.chooseAlpha)
		
		self.frameRateComboBox = QComboBox(self)
		self.frameRateComboBox.setMinimumSize(80,23)
		self.frameRateComboBox.addItem("23.976")
		self.frameRateComboBox.addItem("24.00")
		self.frameRateComboBox.addItem("29.97")
		self.frameRateComboBox.addItem("30.00")
		self.frameRateComboBox.setCurrentIndex(1)
		self.frameRateComboBox.activated[str].connect(self.chooseFrameRate)
		
		self.compressButton = QPushButton('Compress', self)
		self.compressButton.setMinimumSize(80,23)
		self.compressButton.clicked[bool].connect(self.compressPress)
			
		self.gridLayoutControlls.addWidget(self.codecComboBox, 1, 0, 1, 1)
		self.gridLayoutControlls.addWidget(self.alphaComboBox, 1, 1, 1, 1)
		self.gridLayoutControlls.addWidget(self.frameRateComboBox, 1, 2, 1, 1)
		self.gridLayoutControlls.addWidget(self.compressButton, 1, 3, 1, 1)
			
		#RADIO BUTTON GROUP
		self.groupBox = QButtonGroup(self)
		self.radio1 = QRadioButton('Output file name from Folder name', self)
		self.radio1.setMinimumSize(80,25)
		self.radio2 = QRadioButton('Output file name from File name', self)
		self.radio2.setMinimumSize(80,25)
		self.radio1.setChecked(True)
		self.groupBox.addButton(self.radio1,1)
		self.groupBox.addButton(self.radio2,2)
		self.groupBox.buttonClicked[int].connect(self.radioBtnState)
		
		self.gridLayoutControlls.addWidget(self.radio1, 2, 0, 1, 2)
		self.gridLayoutControlls.addWidget(self.radio2, 2, 2, 1, 2)
		
		#LINE
		self.line = QFrame(self)
		self.line.setLineWidth(2)
		self.line.setMinimumHeight(3)
		self.line.setFrameShape(QFrame.HLine)
		self.line.setFrameShadow(QFrame.Sunken)
		
		self.gridLayoutControlls.addWidget(self.line, 3, 0, 1, 4)
		
		#PROGRESS BAR 
		self.gridLayoutProgress = QGridLayout()
		self.gridLayoutProgress.setVerticalSpacing(11)
		self.gridLayoutProgress.setHorizontalSpacing(6)
		self.gridLayoutProgress.setSizeConstraint(QLayout.SetNoConstraint)
		
		self.removeGroupBox = QButtonGroup(self)
		self.addProgressBarUI(self.inList)			
		self.removeGroupBox.buttonClicked[int].connect(self.removeButtonClicked)

		#ADD MORE AREA
		self.gridLayoutAddMore = QGridLayout()
		self.gridLayoutAddMore.setContentsMargins(0, 0, 0, 0)
		
		self.dragAndDropLabel_1 = QLabel("Drag and Drop folders here", self)
		self.dragAndDropLabel_1.setMinimumSize(QSize(120, 40))
		self.dragAndDropLabel_1.setAlignment(Qt.AlignCenter)
		
		self.dragAndDropLabel_2 = QLabel("", self)
		self.dragAndDropLabel_2.setFixedSize(QSize(20, 40))
		self.dragAndDropLabel_2.setAlignment(Qt.AlignCenter)
		self.dragAndDropLabel_2.setPixmap(self.folderPix)
		
		sI = QSpacerItem(40, 40,QSizePolicy.Expanding, QSizePolicy.Minimum)
		sI2 = QSpacerItem(40, 40,QSizePolicy.Expanding, QSizePolicy.Minimum)
		
		self.gridLayoutAddMore.addItem(sI, 1, 0, 1, 1)
		self.gridLayoutAddMore.addWidget(self.dragAndDropLabel_2, 1, 1, 1, 1)
		self.gridLayoutAddMore.addWidget(self.dragAndDropLabel_1, 1, 2, 1, 1)
		self.gridLayoutAddMore.addItem(sI2, 1, 3, 1, 1)
		
		#DEBUG AREA
		self.gridLayoutDebug = QGridLayout()
		self.line_2 = QFrame(self)
		self.line_2.setLineWidth(2)
		self.line_2.setFrameShape(QFrame.HLine)
		self.line_2.setFrameShadow(QFrame.Sunken)
		
		self.exploreOutputBtn = QPushButton('Explore Output',self)
		self.exploreOutputBtn.clicked[bool].connect(self.exploreOutput)

		self.hideShowLog = QPushButton('Show Log',self)
		self.hideShowLog.setCheckable(True)
		self.hideShowLog.clicked[bool].connect(self.showDebugLog)
		#self.hideShowLog.setMinimumSize(QSize(0, 20))
		
		self.logText = QPlainTextEdit('',self)
		self.logText.setReadOnly(True)
		self.logText.hide()
		
		self.spacerItem = QSpacerItem(20, 0, QSizePolicy.Minimum, QSizePolicy.Expanding)
		
		self.gridLayoutDebug.addWidget(self.line_2, 0, 0, 1, 1)
		self.gridLayoutDebug.addWidget(self.exploreOutputBtn, 1, 0, 1, 1)
		self.gridLayoutDebug.addWidget(self.hideShowLog, 2, 0, 1, 1)
		self.gridLayoutDebug.addWidget(self.logText, 3, 0, 1, 1)
		self.gridLayoutDebug.addItem(self.spacerItem, 4, 0, 1, 1)
		
		self.verticalLayout.addLayout(self.gridLayoutControlls)
		self.verticalLayout.addLayout(self.gridLayoutProgress)
		self.verticalLayout.addLayout(self.gridLayoutAddMore)
		self.verticalLayout.addLayout(self.gridLayoutDebug)
		
		# Enable dragging and dropping onto the GUI
		self.setAcceptDrops(True)
		
		#QtCore.QMetaObject.connectSlotsByName(self)
		self.show()
		self.setMinimumSize(self.size())
		
		self.threadpool = QThreadPool()
		self.threadpool.setMaxThreadCount(1)
		print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
    
	
	
	'''
	Progress bar populate function
	'''
	def addProgressBarUI(self, arr):
		pbCount = len(self.pbList)
		for i in range(len(arr)):
			tempCheckBox = QCheckBox(self)
			tempCheckBox.setChecked(True)
			tempCheckBox.setMinimumSize(14,21)
			
			tempRemoveButton = QPushButton(self)
			tempRemoveButton.setIcon(self.removeIcon)
			tempRemoveButton.setFlat(True)
			tempRemoveButton.setIconSize(QSize(19,19))
			tempRemoveButton.setFixedSize(QSize(19,21))
			
			
			tempPB = QProgressBar(self)
			tempPB.setMinimumSize(50,21)
			tempPB.setMinimum(0)
			tempPB.setMaximum(100)
			tempPB.setTextVisible(True)
			tempPB.setFormat(str(arr[i])+" %p%")
			tempPB.setAlignment(Qt.AlignCenter)
			tempPB.setValue(0)
			if i==0:
				self.defaulStyle = tempPB.styleSheet()
			
			tempStatusLabel = QLabel(self)			
			tempStatusLabel.setPixmap(self.okPix)
			tempStatusLabel.setMinimumSize(13,21)
			
			self.gridLayoutProgress.addWidget(tempCheckBox, pbCount+i, 0, 1, 1)
			self.gridLayoutProgress.addWidget(tempPB, pbCount+i, 1, 1, 1)
			self.gridLayoutProgress.addWidget(tempStatusLabel, pbCount+i, 2, 1, 1)
			self.gridLayoutProgress.addWidget(tempRemoveButton, pbCount+i, 3, 1, 1)
			self.removeGroupBox.addButton(tempRemoveButton, pbCount+i)
			
			self.pbList.append(tempPB)
			self.chList.append(tempCheckBox)
			self.lblList.append(tempStatusLabel)
			self.rmbList.append(tempRemoveButton)
	
		
	'''
	Drag+Drop Functions
	'''
	# The following three methods set up dragging and dropping for the app
	def dragEnterEvent(self, e):
		if e.mimeData().hasUrls:
			e.accept()
		else:
			e.ignore()

	def dragMoveEvent(self, e):
		if e.mimeData().hasUrls:
			e.accept()
		else:
			e.ignore()

	def dropEvent(self, e):
		"""
		Drop files directly onto the widget
		File locations are stored in fname
		:param e:
		:return:
		"""
		newFolders = []
		if e.mimeData().hasUrls:
			e.setDropAction(Qt.CopyAction)
			e.accept()
			# Workaround for OSx dragging and dropping
			for url in e.mimeData().urls():
				if op_sys == 'Darwin':
					#check for dir here as well
					fname = str(NSURL.URLWithString_(str(url.toString())).filePathURL().path())
				else:
					fname = str(url.toLocalFile())
					if os.path.isdir(fname) == True:
						newFolders.append(fname)
					#print(fname)

			#self.fname = fname
			#print(self.fname)
			#self.load_image()
			self.addNewFolders(newFolders)
			self.inList = self.inList + newFolders
		else:
			e.ignore()
	

	def addNewFolders(self, newFolders):
		self.addProgressBarUI(newFolders)
		self.setMinimumHeight(self.height()+len(newFolders)*32)
		#self.resize(self.width(),self.height()+200)
		self.update()
		self.adjustSize()
		self.setMinimumSize(self.size())
	'''
	Button Functions
	'''
	def chooseAlpha(self, text):
		switcher={
			"No Alpha":False,
			"with Alpha":True
		}
		self.alpha = switcher.get(text,"Invalid day of week")
		#print (self.alpha)

	def chooseCodec(self, text):
		switcher={
			"UT Video":"utvideo"
		}
		self.codec =  switcher.get(text,"Invalid day of week")
		#print (self.codec)
		
	def chooseFrameRate(self, text):
		self.frameRate =  float(text)
		#print (self.frameRate)
	
	
	def currentData(self, widget):
		return widget.currentText() 

	def radioBtnState(self, text):
		switcher={
			1:'Folder',
			2:'File'
		}
		self.nameFrom = switcher.get(text,"Invalid day of week")
		#print(self.nameFrom)
	
	def removeButtonClicked(self, i):
		#print('remove trigger on id '+str(i))
		
		#self.pbList.pop(i)
		'''
		self.pbList[i].hide()
		self.chList[i].setChecked(False)
		self.chList[i].hide()
		self.lblList[i].hide()
		self.rmbList[i].hide()
		'''
		print(self.gridLayoutProgress.rowCount())
		self.pbList[i].setParent(None)
		self.chList[i].setChecked(False)
		self.chList[i].setParent(None)
		self.lblList[i].setParent(None)
		self.rmbList[i].setParent(None)
		
		self.removeGroupBox.removeButton(self.rmbList[i])

		self.gridLayoutProgress.removeWidget(self.pbList[i])
		self.gridLayoutProgress.removeWidget(self.chList[i])
		self.gridLayoutProgress.removeWidget(self.lblList[i])
		self.gridLayoutProgress.removeWidget(self.rmbList[i])
		self.gridLayoutProgress.invalidate()
		self.gridLayoutProgress = QGridLayout()
		self.gridLayoutProgress.setVerticalSpacing(11)
		self.gridLayoutProgress.setHorizontalSpacing(6)
		self.gridLayoutProgress.setSizeConstraint(QLayout.SetDefaultConstraint)
		self.verticalLayout.insertLayout(1,self.gridLayoutProgress)
		
		print(self.gridLayoutProgress.rowCount())
		'''
		print(self.pbList)
		print(self.chList)
		print(self.lblList)
		print(self.rmbList)
		'''
		
		self.pbList.pop(i)
		self.chList.pop(i)
		self.lblList.pop(i)
		self.rmbList.pop(i)
		self.inList.pop(i)		
		

		#clear the gridLayout
		for j in reversed(range(len(self.pbList))):
			self.pbList[j].setParent(None)
			self.chList[j].setParent(None)
			self.lblList[j].setParent(None)
			self.rmbList[j].setParent(None)
		
		
		#reorder the gridLayout
		for j in range(len(self.pbList)):
			self.gridLayoutProgress.addWidget(self.chList[j], j, 0, 1, 1)
			self.gridLayoutProgress.addWidget(self.pbList[j], j, 1, 1, 1)
			self.gridLayoutProgress.addWidget(self.lblList[j], j, 2, 1, 1)
			self.gridLayoutProgress.addWidget(self.rmbList[j], j, 3, 1, 1)
			self.removeGroupBox.setId(self.rmbList[j],j)

		
		
		self.setMinimumHeight(self.height()-30)
		#self.setMinimumHeight(100)
		self.adjustSize()
		self.setMinimumSize(self.size())
		print(self.gridLayoutProgress.rowCount())
		#self.correctSize()
		'''
		for j in range(len(self.removeGroupBox.buttons())):
			button = self.removeGroupBox.buttons()[j]
			#print(button)
			#print('original id '+str(self.removeGroupBox.id(button)))
			#print('new id '+str(j))
			self.removeGroupBox.setId(button,j)
		'''
	
	def correctSize(self):
			self.logText.show()
			self.gridLayoutDebug.removeItem(self.spacerItem)
			self.adjustSize()
			self.setMinimumSize(self.size())
			self.repaint()
			self.gridLayoutDebug.addItem(self.spacerItem)
			self.logText.hide()
			self.setMinimumHeight(100)
			self.adjustSize()
			self.setMinimumSize(self.size())
	
	def showDebugLog(self, bol):
		if bol:
			self.logText.show()
			self.hideShowLog.setText('Hide Log')
			self.gridLayoutDebug.removeItem(self.spacerItem)
			self.adjustSize()
			#self.resize(self.width(), self.height()+80)
			self.setMinimumSize(self.size())
		else:
			self.gridLayoutDebug.addItem(self.spacerItem)
			self.logText.hide()
			self.hideShowLog.setText('Show Log')
			self.setMinimumHeight(100)
			self.adjustSize()
			self.setMinimumSize(self.size())
			#self.resize(self.width(), 100)
			#self.setGeometry(0,0,self.width(),100)
	
	'''
	Execution Functions
	'''
	def execute_this_fn(self, path, codec, alpha, frameRate, nameFrom, i, progress_callback, errorFFMPEG_callback):
		#print(path)
		pyCompression = pyFFMEGCompress(path, codec, alpha, frameRate, nameFrom)
		ffProcess = pyCompression.ffmpegCompress()
		self.lblList[i].setPixmap(self.processingPix)
		
		#with kwargs
		kwargs = {'progress_callback':progress_callback, 'errorFFMPEG_callback':errorFFMPEG_callback}
		pyCompression.printProcess(ffProcess, **kwargs)

		return (pyCompression.debugString,pyCompression.error,i)
 
	def printOutput(self, s):
		print("Printing output "+ str(s))
		
	def threadComplete(self, r):
		#print("THREAD COMPLETE! WITH ERROR " + str(r[2]) )
		if r[1] == False:
			self.lblList[r[2]].setPixmap(self.goodPix)
			self.pbList[r[2]].setStyleSheet("QProgressBar::chunk {background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #44dd14,stop: 0.4999 #39c10f,stop: 0.5 #39c10f,stop: 1 #39c10f );border-radius: 3px; border: 1px solid #29880b;}QProgressBar{color:white}")
			self.pbList[r[2]].setValue(100)

	def errorPB(self, err):
		for i in range(len(self.pbList)):
			if self.pbList[i].format() == err:
				self.pbList[i].setValue(100)
				self.pbList[i].setStyleSheet("QProgressBar::chunk {background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #FF0350,stop: 0.4999 #FF0020,stop: 0.5 #FF0019,stop: 1 #FF0000 );border-radius: 3px; border: 1px solid #a60233;}QProgressBar{color:white}")
				self.pbList[i].setFormat(self.pbList[i].format()+" - Error")
				self.chList[i].setChecked(False)
				self.lblList[i].setPixmap(self.badPix)
				
	def resetProgressBar(self, pb, text, lbl):
		pb.setValue(0)
		pb.setFormat(text + ' %p%')
		pb.setStyleSheet(self.defaulStyle)
		lbl.setPixmap(self.okPix)
	

	def compressPress(self):
		for i in range(len(self.pbList)):				
			if self.chList[i].isChecked():
				self.resetProgressBar(self.pbList[i],self.inList[i],self.lblList[i])
				
				worker = Worker(self.execute_this_fn, self.inList[i], self.codec, self.alpha, self.frameRate, self.nameFrom, i) # Any other args, kwargs are passed to the run function
				#worker.signals.result.connect(self.printOutput)
				worker.signals.result.connect(self.logText.appendPlainText)
				worker.signals.progress.connect(self.pbList[i].setValue)
				worker.signals.errorFFMPEG.connect(self.errorPB)
				worker.signals.error.connect(self.errorPB)
				worker.signals.finished.connect(self.threadComplete)
				#worker.signals.finished.connect(self.logText.appendPlainText)
				
				# Execute
				self.threadpool.start(worker)

	def exploreOutput(self):
		FILEBROWSER_PATH = os.path.join(os.getenv('WINDIR'), 'explorer.exe')
		explorePath = os.path.normpath('C:\\ExportedMOVs')
		subprocess.run([FILEBROWSER_PATH, explorePath])