#!/usr/bin/python
# -*- coding: Utf-8 -*-

import os
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from gui_modules_animation.animation_base import Base
from moteur_modules_animation.mplayer import Mplayer

class Label(QWidget):
	"""barre de sélection d'un extrait vidéo"""
	def __init__(self, parent, largeur=200):
		# parent nous permettra d'accéder à la valeur du curseur
		QWidget.__init__(self)
		# dimensions minimales de la barre. On gardera 30 px en horizontal. La barre prendra tout l'espace en horizontal
		self.x, self.y = largeur, 35
		self.setMinimumSize(self.x, self.y)
		self.setMaximumSize(self.x, self.y)
		self.parent = parent
	
	def paintEvent(self, event):
		paint = QPainter()
		paint.begin(self)
		
		# QFont.Light: police légère (par défaut)
		font = QFont('Serif', 7, QFont.Light)
		paint.setFont(font)
		
		# récupération de la valeur de la marque du début, de fin et de la durée de la vidéo
		marques = self.parent.marques
		# Et oui, debut peut correspondre à la valeur de fin
		# si l'utilisateur s'emmêle les pinceaux
		debut = float(marques[0])
		fin = float(marques[1])
		duree = float(marques[2])
		
		# nbr de px correspondant à la marque de début et de fin de la sélection de la vidéo
		debutPx = int((debut/duree)*self.x)
		finPx = int((fin/duree)*self.x)
		
		## traçage des 2 rectangles (le global et celui de la zone sélectionnée
		## pas de contour pour les couleurs
		#paint.setPen(QColor(255, 255, 255))
		#paint.setBrush(QColor(175, 175, 175)) # gris
		#paint.setBrush(QColor(185, 165, 185)) # gris-pourpre
		paint.setBrush(QColor(235,215,235)) # mauve clair
		# rectangle plein de la barre
		paint.drawRect(0, 0, self.x, self.y)
		# vert
		#paint.setPen(QColor(175, 255, 175)) # vert clair
		#paint.setBrush(QColor(175, 255, 175)) # vert clair
		paint.setPen(QColor(60, 150, 60)) # vert
		paint.setBrush(QColor(60, 150, 60)) # vert
		paint.drawRect(debutPx, 0, finPx-debutPx, self.y)
		
		
		# on paramètre une ligne solide
		pen = QPen(QColor(20, 20, 20), 1, Qt.SolidLine)
		paint.setPen(pen)
		# pas de dessin de fond sinon on ne pourra plus inscrire de rectangle variable dans la barre
		paint.setBrush(Qt.NoBrush)
		# dessin du contour de la barre
		paint.drawRect(0, 0, self.x-1, self.y-1)
		
		# Indicateur de temps pour le début
		# dessin graduations
		paint.drawLine(debutPx, 0, debutPx, 5)
		# police métrique
		metrics = paint.fontMetrics()
		# taille des valeurs de la police métrique
		debutMetrique="%.1f" %(debut)
		largMetrique = metrics.width(debutMetrique)
		# dessin des valeurs de la police métrique - alignement avec les graduations
		paint.drawText(debutPx-largMetrique/2, 15, debutMetrique)
		
		# Indicateur de temps pour la fin
		# dessin graduations
		paint.drawLine(finPx, self.y-5, finPx, self.y)
		# police métrique
		metrics = paint.fontMetrics()
		# taille des valeurs de la police métrique
		finMetrique="%.1f" %(fin)
		largMetrique = metrics.width(finMetrique)
		# dessin des valeurs de la police métrique - alignement avec les graduations
		paint.drawText(finPx-largMetrique/2, self.y -8, finMetrique)
		
		paint.end()


class Animation_MontagVideoDecoupUneVideo(QWidget):
	# -------------------------------------------------------------------------------------
	# Cadre accueillant les widgets de : Animation >> Montage Vidéo >> Découper une Vidéo
	# -------------------------------------------------------------------------------------
	def __init__(self, parent):
		QWidget.__init__(self)
		
		# -------------------------------
		# Parametres généraux du widget
		# -------------------------------
		self.base = Base(self) # module de animation
		#=== tout sera mis dans une boîte verticale ===#
		vbox=QVBoxLayout(self)
		
		#=== Variable de configuration ===#
		self.config=parent.config
		
		#=== Identifiant de la classe ===#
		self.idSection = "Animation - Decouper une Video"
		self.base.printSection()
		
		#=== Drapeaux ===#
		# drapeau pour savoir si la valeur de début de la sélection vidéo été enregistré
		self.debutEstSelect = False
		# drapeau pour savoir si la valeur de fin de la sélection vidéo été enregistré
		self.finEstSelect = False
		# drapeau d'extraction du son
		self.extraireSon = True
		
		# -------------------------------------------------------------------
		# Boîte de groupe : "Fichier vidéo source"
		# -------------------------------------------------------------------
		self.base.widgetSource(vbox)
		
		# --------------------------------------------------------------------------
		# Boîte de groupe de réglage: visualisation et de marquage de la sélection
		# --------------------------------------------------------------------------
		
		# Création de la boite de groupe de réglage (contenant la boite self.layoutReglage)
		self.base.widgetReglage(vbox, _(u"Choix de la sélection"), boite='vbox')
		
		# Widget qui seront inclus dans la boite de réglage
		
		#=== Widgets mplayer ===#
		vboxMplayer = QVBoxLayout()
		# Le facteur limitant est la largeur -> + simple à coder à cause de la largeur de la barre
		self.mplayer=Mplayer(taille=(300,270), facteurLimitant=Mplayer.LARGEUR,
			choixWidget=(Mplayer.PAS_PRECEDENT_SUIVANT,Mplayer.CURSEUR_A_PART))
		self.mplayer.listeVideos = [self.ligneEditionSource.text()]
		self.mplayer.setToolTip(_(u"La lecture de la vidéo est nécessaire pour achever la sélection d'une zone de la vidéo"))
		self.mplayer.setEnabled(False)
		hbox = QHBoxLayout()
		hbox.addStretch()
		hbox.addWidget(self.mplayer)
		hbox.addStretch()
		vboxMplayer.addLayout(hbox)
		
		self.radioSource = QRadioButton(_(u"vidéo(s) source(s)"))
		self.radioSource.setChecked(True)
		self.radioSource.setEnabled(False)
		self.connect(self.radioSource, SIGNAL("clicked(bool)"), self.fctRadioSource)
		self.radioApercu = QRadioButton(_(u"aperçu"))
		self.radioApercu.setEnabled(False)
		self.connect(self.radioApercu, SIGNAL("clicked(bool)"), self.fctRadioApercu)
		self.radioConvert = QRadioButton(_(u"vidéo convertie"))
		self.radioConvert.setEnabled(False)
		self.connect(self.radioConvert, SIGNAL("clicked(bool)"), self.fctRadioConvert)
		self.layoutReglage.addLayout(vboxMplayer)
		
		# Le widget-mplayer récupère des informations tous les 10ème
		# de seconde au lieu de toutes les secondes -> le marquage du
		# début et de la fin de la sélection seront plus précis
		self.mplayer.dureeTimer=100
		
		self.connect(self.mplayer.bout_LectPause, SIGNAL('clicked()'), self.lectureMPlayer)
		
		#=== Marquage et affichage des bornes de la sélection ===#
		
		#||| Label de visualisation de la sélection |||#
		
		self.marques = (0,0,1)
		self.visuSelect = Label(self, 300)
		self.visuSelect.setToolTip(_(u"La zone sélectionnée apparait en vert dans cette bande"))
		self.valeurDebut=0
		self.valeurFin=0
		
		hbox=QHBoxLayout()
		hbox.addWidget(self.visuSelect)
		self.layoutReglage.addLayout(hbox)
		
		#||| boutons de marquage de la sélection |||#
		
		iconTaille = 28
		
		self.frameMarque = QFrame()
		boiteMarque = QHBoxLayout()
		boiteMarque.addStretch()
		
		boutMarqDebutSelect=QPushButton()
		boutMarqDebutSelect.setIcon(QIcon("Icones/Tdebut.png"))
		boutMarqDebutSelect.setIconSize(QSize(iconTaille, iconTaille))
		boutMarqDebutSelect.setToolTip(_(u"Marquer le début de la sélection"))
		boiteMarque.addWidget(boutMarqDebutSelect)
		
		self.boutMarqFinSelect=QPushButton()
		self.boutMarqFinSelect.setIcon(QIcon("Icones/Tfin.png"))
		self.boutMarqFinSelect.setIconSize(QSize(iconTaille, iconTaille))
		self.boutMarqFinSelect.setToolTip(_(u"Marquer la fin de la sélection"))
		self.boutMarqFinSelect.setEnabled(False)
		boiteMarque.addWidget(self.boutMarqFinSelect)
		
		boutMarqDebutSelect_min=QPushButton()
		boutMarqDebutSelect_min.setIcon(QIcon("Icones/Tdebut2.png"))
		boutMarqDebutSelect_min.setIconSize(QSize(iconTaille, iconTaille))
		boutMarqDebutSelect_min.setToolTip(_(u"Marquer le début de la sélection au temps minimum (t=0)"))
		boiteMarque.addWidget(boutMarqDebutSelect_min)
		
		self.boutMarqFinSelect_max=QPushButton()
		self.boutMarqFinSelect_max.setIcon(QIcon("Icones/Tfin2.png"))
		self.boutMarqFinSelect_max.setIconSize(QSize(iconTaille, iconTaille))
		self.boutMarqFinSelect_max.setToolTip(_(u"Marquer la fin de la sélection au temps maximum (t=\"la durée de la vidéo\")"))
		self.boutMarqFinSelect_max.setEnabled(False)
		boiteMarque.addWidget(self.boutMarqFinSelect_max)
		
		boutMiseAZeroSelect=QPushButton()
		boutMiseAZeroSelect.setIcon(QIcon("Icones/update.png"))
		boutMiseAZeroSelect.setIconSize(QSize(iconTaille, iconTaille))
		boutMiseAZeroSelect.setToolTip(_(u"Remettre à zéro les paramètres"))
		boiteMarque.addWidget(boutMiseAZeroSelect)
		
		self.boutExtractionSon=QPushButton()
		self.boutExtractionSon.setIcon(QIcon("Icones/sound.png"))
		self.boutExtractionSon.setIconSize(QSize(iconTaille, iconTaille))
		self.boutExtractionSon.setToolTip(_(u"Pressez le bouton si vous voulez exclure le son de l'extraction vidéo"))
		boiteMarque.addWidget(self.boutExtractionSon)
		
		self.connect(boutMarqDebutSelect, SIGNAL("clicked()"), self.marqDebutSelect)
		self.connect(self.boutMarqFinSelect, SIGNAL("clicked()"), self.marqFinSelect)
		self.connect(boutMarqDebutSelect_min, SIGNAL("clicked()"), self.marqDebutSelect_min)
		self.connect(self.boutMarqFinSelect_max, SIGNAL("clicked()"), self.marqFinSelect_max)
		self.connect(boutMiseAZeroSelect, SIGNAL("clicked()"), self.miseAZeroSelect)
		self.connect(self.boutExtractionSon, SIGNAL("clicked()"), self.reglageSon)
		
		self.frameMarque.setLayout(boiteMarque)
		# On grise le widget au début
		self.frameMarque.setEnabled(False)
		
		self.layoutReglage.addWidget(self.frameMarque)
		boiteMarque.addStretch()
		
		#||| boutons radio de lecture de la source ou du fichier converti|||#
		hbox = QHBoxLayout()
		hbox.addWidget(self.radioSource)
		hbox.addWidget(self.radioApercu)
		hbox.addWidget(self.radioConvert)
		hbox.setAlignment(Qt.AlignHCenter)
		self.layoutReglage.addLayout(hbox)
		
		# -------------------------------------------------------------------
		# widgets du bas : ligne + boutons Aide et Appliquer
		# -------------------------------------------------------------------
		self.base.widgetBas(vbox)
		
		# affichage de la boîte principale
		self.setLayout(vbox)
	
	
	def lectureMPlayer(self):
		"""Dégriser les 2 boutons de sélection de fin si le début a déjà été sélectionné"""
		if self.debutEstSelect:
			self.boutMarqFinSelect.setEnabled(True)
			self.boutMarqFinSelect_max.setEnabled(True)
	
	def reglageSon(self):
		"""Extraire ou pas le son de la vidéo lors de l'extraction vidéo"""
		if self.extraireSon:
			self.extraireSon = False
			self.boutExtractionSon.setIcon(QIcon("Icones/nosound.png"))
			self.boutExtractionSon.setToolTip(_(u"Pressez le bouton si vous voulez ré-inclure le son de l'extraction vidéo"))
		else:
			self.extraireSon = True
			self.boutExtractionSon.setIcon(QIcon("Icones/sound.png"))
			self.boutExtractionSon.setToolTip(_(u"Pressez le bouton si vous voulez exclure le son de l'extraction vidéo"))
	
	def miseAZeroSelect(self):
		"""On remet à zéro les zones sélectionnées"""
		self.debutEstSelect = False
		self.finEstSelect = False
		self.boutApp.setEnabled(False)
		self.boutMarqFinSelect.setEnabled(False)
		self.boutMarqFinSelect_max.setEnabled(False)
		self.valeurDebut, self.valeurFin = 0, 0
		self.marques = (0,0,1)
		self.visuSelect.repaint()
	
	def marqDebutSelect(self):
		"""Récupération de la valeur du marqueur du début de la sélection"""
		
		# Le début n'a pas été sélectionné ou il a été sélectionné mais pas la fin
		# -> un seul trait sur le QLabel
		if not self.debutEstSelect or (self.debutEstSelect and not self.finEstSelect):
			self.valeurDebut = self.mplayer.temps
			print self.valeurDebut
			self.debutEstSelect = True
			# mplayer est en lecture
			if self.mplayer.estLue:
				self.boutMarqFinSelect.setEnabled(True)
				self.boutMarqFinSelect_max.setEnabled(True)
			# tracer d'un seul trait
			self.marques = (self.valeurDebut,self.valeurDebut,self.mplayer.dureeVideo)
			self.visuSelect.repaint()
		
		# Le début et la fin ont déjà été sélectionnés
		elif self.debutEstSelect and  self.finEstSelect:
			self.valeurDebut = self.mplayer.temps
			print self.valeurDebut
			self.mettreAJourLabel('debut')
	
	def marqFinSelect(self):
		"""Récupération de la valeur du marqueur de la fin de la sélection"""
		self.valeurFin = self.mplayer.temps
		print self.valeurFin
		self.finEstSelect = True
		self.mettreAJourLabel('fin')
	
	def marqDebutSelect_min(self):
		"""La valeur du marqueur du début de la sélection est placé au temps t=0 seconde"""
		
		# Le début n'a pas été sélectionné ou il a été sélectionné mais pas la fin
		# -> un seul trait sur le QLabel
		if not self.debutEstSelect or (self.debutEstSelect and not self.finEstSelect):
			self.valeurDebut = 0
			print self.valeurDebut
			self.debutEstSelect = True
			# mplayer est en lecture
			if self.mplayer.estLue:
				self.boutMarqFinSelect.setEnabled(True)
				self.boutMarqFinSelect_max.setEnabled(True)
			# tracer d'un seul trait
			self.marques = (self.valeurDebut,self.valeurDebut,self.mplayer.dureeVideo)
			self.visuSelect.repaint()
		
		# Le début et la fin ont déjà été sélectionnés
		elif self.debutEstSelect and  self.finEstSelect:
			self.valeurDebut = 0
			print self.valeurDebut
			self.mettreAJourLabel()
	
	def marqFinSelect_max(self):
		"""La valeur du marqueur de la fin de la sélection est placé à la fin de la vidéo"""
		self.valeurFin = self.mplayer.dureeVideo
		print self.valeurFin
		self.finEstSelect = True
		self.mettreAJourLabel()
	
	def mettreAJourLabel(self, debutOuFin=None):
		"""Redessiner le QLabel"""
		
		# si les valeurs de début et de fin sont identiques (possible car notre précision est de un dixième de seconde) alors on remet tout à zéro
		if self.valeurDebut == self.valeurFin:
			self.finEstSelect = False
			self.boutApp.setEnabled(False)
			# tracer d'un seul trait
			self.marques = (self.valeurDebut,self.valeurFin,self.mplayer.dureeVideo)
			self.visuSelect.repaint()
			self.radioSource.setEnabled(False)
			self.radioApercu.setEnabled(False)
		
		# Truisme: la valeur du début de la sélection doit être inférieure à la valeur de la fin
		# sinon les valeurs de début et de fin sont égalisées
		elif self.valeurDebut > self.valeurFin:
			self.radioSource.setEnabled(False)
			self.radioApercu.setEnabled(False)
			if debutOuFin=='debut':
				self.valeurFin = self.valeurDebut
				self.boutApp.setEnabled(False)
				self.marques = (self.valeurDebut,self.valeurFin,self.mplayer.dureeVideo)
				self.visuSelect.repaint()
			
			if debutOuFin=='fin':
				self.valeurDebut = self.valeurFin 
				self.boutApp.setEnabled(False)
				self.marques = (self.valeurDebut,self.valeurFin,self.mplayer.dureeVideo)
				self.visuSelect.repaint()
		# Le cas normal
		else:
			self.marques = (self.valeurDebut,self.valeurFin,self.mplayer.dureeVideo)
			self.visuSelect.repaint()
			self.boutApp.setEnabled(True)
			self.radioSource.setEnabled(True)
			self.radioApercu.setEnabled(True)
		
		print "Bornes de la sélection :", self.valeurDebut, self.valeurFin, type(self.valeurDebut), type(self.valeurFin)
	
	
	def fctRadioSource(self):
		""""Communique le fichier source à mplayer"""
		self.mplayer.listeVideos = [self.ligneEditionSource.text()]
		self.mplayer.debutFin = (0,0)
		self.frameMarque.setEnabled(True)
		self.visuSelect.setEnabled(True)
	
	def fctRadioApercu(self):
		""""Communique le fichier aperçu à mplayer"""
		self.mplayer.listeVideos = [self.ligneEditionSource.text()]
		debut = float("%.1f" %self.valeurDebut)
		fin = float("%.1f" %self.valeurFin)
		self.mplayer.debutFin = (debut,fin)
		self.frameMarque.setEnabled(False)
		self.visuSelect.setEnabled(False)
	
	def fctRadioConvert(self):
		""""Communique le fichier converti à mplayer"""
		self.mplayer.listeVideos = self.fichierSortie
		self.frameMarque.setEnabled(False)
		self.visuSelect.setEnabled(False)
	
	
	def ouvrirSource(self, nomEntree=None):
		"""Récupération du chemin de la vidéo sélectionnée et activation de certains widgets"""
		
		# Récupération du chemin de la vidéo
		chemin = self.base.recupSource(nomEntree)
		if not chemin: return
		print "chemin vidéo d'entrée:", chemin, type(chemin)
		
		# Affichage du chemin + nom de fichier dans la ligne d'édition
		self.ligneEditionSource.setText(chemin)
		
		self.mplayer.setEnabled(True)
		self.mplayer.listeVideos = [chemin]
		self.radioSource.setChecked(True)
		self.radioSource.setEnabled(False)
		self.radioConvert.setEnabled(False)
		
		# les boutons de marquage apparaissent
		self.frameMarque.setEnabled(True)
		
		# Utile lors de la sélection d'une 2ème vidéo et au-delà
		self.miseAZeroSelect()
		
		## on récupère la durée de la vidéo avant son lancement
		#recDonnees_Video=os.popen('mplayer ' + chemin + ' -vo null -ao null -frames 0 -identify "$@" 2>/dev/null').readlines()
		
		#for ligne in recDonnees_Video:
			#print ligne
	
	
	def afficherAide(self):
		""" Boîte de dialogue de l'aide du cadre Animation > Encodage """
		#self.base.afficherAide(_(u"Maitre corbeau sur son arbre perché, tenait dans son bec un fromage..."))
		self.base.afficherAide(_(u"Blablablablablablablablablabla ... blablabla ... blablablabla ... blablabla."))
		'''
		messageAide=QMessageBox(self)
		messageAide.setText(_(u"Blablablabla ... blabla anim_montage_video_decoup_une_vid."))
		messageAide.setWindowTitle(_(u"Aide"))
		messageAide.setIcon(QMessageBox.Information)
		messageAide.exec_()
		'''
	
	
	def appliquer(self):
		"""Découpage de la vidéo"""
		fichierSortie=str(QFileDialog.getSaveFileName(None, _(u"Sauver"), os.path.expanduser(self.base.repSortieProv()),_(u"Tous les fichiers *.*")))
		
		if fichierSortie=="":
			return
		
		fichierEntree = str(self.ligneEditionSource.text())
		tempsDebut = str(self.valeurDebut)
		dureeSelection = str(self.valeurFin - self.valeurDebut)
		
		# Extension du fichier
		fich, ext=os.path.splitext(fichierEntree)
		print "extension :", ext, type(ext)
		
		print "COMMANDE :"
		commande = 'mencoder -ss '+tempsDebut+' -endpos '+dureeSelection+' '+"\""+fichierEntree+"\" -o "+"\""+fichierSortie+ext+"\" -oac copy -ovc copy"
		
		# Le son ne sera pas extrait selon le drapeau
		if not self.extraireSon:
			commande = commande +' -nosound'
		
		print commande
		
		try:
			os.system(commande)
		except:
			messageErrAnEnc=QMessageBox(self)
			messageErrAnEnc.setText(_(u"Un problème est survenu lors de l'exécution de \"mencoder -ss ...\""))
			messageErrAnEnc.setWindowTitle(_(u"Error"))
			messageErrAnEnc.setIcon(QMessageBox.Warning)
			messageErrAnEnc.exec_()
			return
		
		messageSucces=QMessageBox(self)
		messageSucces.setText(_(u"L'extraction a été réalisée avec succès!"))
		messageSucces.setWindowTitle(_(u"Information"))
		messageSucces.setIcon(QMessageBox.Information)
		messageSucces.exec_()
		
		self.fichierSortie = fichierSortie+ext
		self.radioSource.setEnabled(True)
		self.radioConvert.setEnabled(True)
		#os.system('mencoder -ss '+decVidValDeb+' -endpos '+decVidValDuree+' '+"\""+b+"\""+' -ovc copy -o'+"\""+SortieVideoDecVid+"\"")