class classXAudioCopy:

	# Costruttore della classe classXAudioCopy
	def __init__(self):
		# Collega il file XML
		self.builderXAC = Gtk.Builder()
		self.builderXAC.add_from_file(GLADE)
		# Collega i segnali
		self.builderXAC.connect_signals(self)

		# Carica la finestra principale "mainWindow"
		self.mainWindow = self.builderXAC.get_object("mainWindow")
		self.mainWindow.set_title(WINDOW_TITLE)
		self.mainWindow.connect("destroy", lambda on_quit: Gtk.main_quit())

		# Carica la statusbar
		self.status = self.builderXAC.get_object("statusbar")

		# Collega il menu contestuale
		self.popupmenu = self.builderXAC.get_object("popupmenu")

		# Carica la tabella per la lista dei file (TreeView)
		self.FileTable = FileTable(self.builderXAC)

		# Visualizza la finestra principale mainWindow
		self.mainWindow.show()
		self.set_status()

		# Toglie il focus al pulsante cmdOpenFile (TODO: scoprire perché ce l'ha)
		self.mainWindow.set_focus(None)

		# Carica la barra con i tag e la nasconde all'avvio
		self.TagBar = TagBar(self.builderXAC)
		self.TagBar.hide()

		# Aggancia alcuni pulsanti e menu (per renderli sensibili o insensibili)
		self.cmdCD = self.builderXAC.get_object("cmdCD")
		self.menuCD = self.builderXAC.get_object("menuCD")

		self.cmdOpenFile = self.builderXAC.get_object("cmdOpenFile")
		self.menuOpenFile = self.builderXAC.get_object("menuOpenFile")

		self.cmdOpenFolder = self.builderXAC.get_object("cmdOpenFolder")
		self.menuOpenFolder = self.builderXAC.get_object("menuOpenFolder")

		self.cmdPlay = self.builderXAC.get_object("cmdPlay")
		self.menuPlay = self.builderXAC.get_object("menuPlay")
		self.menuPause = self.builderXAC.get_object("menuPause")
		self.popPlay = self.builderXAC.get_object("popPlay")
		self.popPause = self.builderXAC.get_object("popPause")

		self.cmdStop = self.builderXAC.get_object("cmdStop")
		self.menuStop = self.builderXAC.get_object("menuStop")
		self.popStop = self.builderXAC.get_object("popStop")

		self.cmdNext = self.builderXAC.get_object("cmdNext")
		self.menuNext = self.builderXAC.get_object("menuNext")

		self.cmdPrev = self.builderXAC.get_object("cmdPrev")
		self.menuPrev = self.builderXAC.get_object("menuPrev")

		self.cmdRewind = self.builderXAC.get_object("cmdRewind")
		self.cmdForward = self.builderXAC.get_object("cmdForward")

		self.labelTime = self.builderXAC.get_object("labelTime")
		self.scaleTime = self.builderXAC.get_object("scaleTime")

		self.volumebutton = self.builderXAC.get_object("volumebutton")
		self.volumebutton.set_value(0.5)

		self.cmdRemove = self.builderXAC.get_object("cmdRemove")
		self.menuRemove = self.builderXAC.get_object("menuRemove")

		self.cmdPurge = self.builderXAC.get_object("cmdPurge")
		self.menuPurge = self.builderXAC.get_object("menuPurge")

		self.menuSelectAll = self.builderXAC.get_object("menuSelectAll")
		self.menuUnselectAll = self.builderXAC.get_object("menuUnselectAll")

		self.cmdRip = self.builderXAC.get_object("cmdRip")
		self.menuRip = self.builderXAC.get_object("menuRip")

		self.cmdConvert = self.builderXAC.get_object("cmdConvert")
		self.menuConvert = self.builderXAC.get_object("menuConvert")

		self.menuProperty = self.builderXAC.get_object("menuProperty")
		self.menuModify = self.builderXAC.get_object("menuModify")
		self.menuPlaylist = self.builderXAC.get_object("menuPlaylist")
		self.popProperty = self.builderXAC.get_object("popProperty")
		self.popTagger = self.builderXAC.get_object("popTagger")

		# Rende insensibili alcuni menu e pulsanti all'avvio
		self.set_sensitive(False)
		self.cmdRip.set_sensitive(False)
		self.cmdConvert.set_sensitive(False)

		# Carica la progressbar per la conversione e la nasconde all'avvio
		self.progConvert = self.builderXAC.get_object("progressbar")
		self.progConvert.hide()

		# Crea l'oggetto lista dei file
		self.audioFileList = FileList()

		# Istanza del player audio
		self.player = Player(None, self)
		self.player.set_volume(self.volumebutton.get_value())
		self.player_bus = self.player.bus
		self.player_bus.connect("message::eos", self.on_endPlay)
		self.player_bus.connect("message::error", self.on_endError)

		# Carica le preferenze
		self.prefs = Preferences()

	# Funzione che attiva la finestra principale
	def main(self):
		Gtk.main()

	# Funzione che modifica la barra di stato
	def set_status(self, text=None):

		self.status.show()
		con_id = self.status.get_context_id("SB")
		if not text:
			text = "Ready"
			self.mainWindow.set_title(WINDOW_TITLE)
		self.status.push(con_id, text)
		#print text
		while Gtk.events_pending():
			Gtk.main_iteration()

	# Funzione che rende sensibili/insensibili alcuni menu e pulsanti
	def set_sensitive(self, sensitive):

		cmd = [
			self.cmdPlay,
			self.menuPlay,
			self.popPlay,
			self.menuPause,
			self.popPause,
			self.cmdNext,
			self.menuNext,
			self.cmdPrev,
			self.menuPrev,
			self.cmdRemove,
			self.menuRemove,
			self.cmdPurge,
			self.menuPurge,
			self.cmdRewind,
			self.cmdForward,
			self.cmdConvert,
			self.menuConvert,
			self.menuSelectAll,
			self.menuUnselectAll,
			self.menuProperty,
			self.menuModify,
			self.popProperty,
			self.popTagger,
			self.menuPlaylist,
			self.TagBar
			]
		if sensitive:
			for c in cmd:
				c.set_sensitive(True)
		elif not sensitive:
			for c in cmd:
				c.set_sensitive(False)
			self.menuRip.set_sensitive(False)
			self.cmdRip.set_sensitive(False)
			self.cmdStop.set_sensitive(False)
			self.menuStop.set_sensitive(False)
			self.popStop.set_sensitive(False)
			self.scaleTime.set_sensitive(False)

	# Evento per l'uscita dal programma
	def on_Quit(self, *args):
		print "Bye..."
		Gtk.main_quit()

	# Evento per l"apertura di un file
	def on_OpenFile(self, *args):
		self.set_status("Adding files...")
		# Oggetto di classe FileChooser (False se apre un file)
		FC = FileChooser(False)
		self.AddFileList(FC)
		try:
			self.player.stop()
		except:
			pass
		self.cmdPlay.set_stock_id("gtk-media-play")

	# Evento per l"apertura di una cartella
	def on_OpenFolder(self, *args):
		self.set_status("Adding forder...")
		# Oggetto di classe FileChooser (True se apre una cartella)
		FC = FileChooser(True)
		self.AddFileList(FC)
		try:
			self.player.stop()
		except:
			pass
		self.cmdPlay.set_stock_id("gtk-media-play")

	# Evento che apre la finetra informazioni
	def on_About(self, *args):
		# Oggetto di classe AboutDialog
		self.About = AboutDialog()

	# Evento che rimuove gli elementi della tabella slezionati
	def on_Remove(self, *args):
		self.FileTable.remove()
		self.on_Stop()
		self.cmdPlay.set_stock_id("gtk-media-play")
		self.mainWindow.set_title(WINDOW_TITLE)
		if len(self.audioFileList.filelist) == 0:
			self.set_sensitive(False)
			self.cmdConvert.set_sensitive(False)
			self.cmdStop.set_sensitive(False)
			self.menuStop.set_sensitive(False)
		else:
			self.set_sensitive(True)
			self.cmdConvert.set_sensitive(True)

	# Evento che pulisce la tabella
	def on_Purge(self, *args):
		self.set_status("Purge list...")
		self.FileTable.purge()
		self.audioFileList.purge()
		self.TagBar.purge()
		self.TagBar.hide()
		self.cmdOpenFile.set_sensitive(True)
		self.cmdOpenFolder.set_sensitive(True)
		self.set_status()
		self.on_Stop()
		self.cmdPlay.set_stock_id("gtk-media-play")
		self.mainWindow.set_title(WINDOW_TITLE)
		self.set_sensitive(False)
		self.cmdConvert.set_sensitive(False)
		self.cmdRip.set_sensitive(False)
		self.progConvert.hide()

	# Evento che apre la finestra preferenze
	def on_Preferences(self, *args):
		dlgPrefs = PreferencesDialog(self.mainWindow, self.prefs)
		dlgPrefs.show()

	# Evento per la riproduzione di un file
	def on_Play(self, *args):

		print self.cmdPlay.get_stock_id()
		self.cmdStop.set_sensitive(True)
		self.menuStop.set_sensitive(True)
		self.popStop.set_sensitive(True)
		self.scaleTime.set_sensitive(True)

		# Se il pulsante indica "play", riproduce la selezione
		if self.cmdPlay.get_stock_id() == "gtk-media-play":

			# Se il player è pronto, inizia la riproduzione
			if self.player.state == "ready":

				#Carica la lista dei file selezionati
				self.selplay = self.Selection(self.FileTable)
				# Riproduce solo il primo file della lista caricata
				try:
					sel = self.selplay[0]
				except IndexError:
					sel = None
				self.playing_song = sel
				if sel:
					af = sel[0]
					it = sel[1]
					if not self.file_exists(af):
						return
	
					self.FileTable.tvSelection.unselect_all()
					self.FileTable.tvSelection.select_iter(it)
					print "Riproduzione di: ", af.get_uri()

					self.player.play(af)

					if af.get_tag("title") != "Unknown title" and af.get_tag("artist") != "Unknown artist":
						msg = af.get_tag("artist") + " - " + af.get_tag("title")
					elif af.get_uri():
						msg = af.get_filepath()
					self.set_status("Playing " + msg)
					self.mainWindow.set_title(msg)
					self.scaleTime.set_range(0, 1)
					self.scaleTime.set_value(0)

			# Se è in pausa, riprende la riproduzione
			elif self.player.state == "paused":
				self.player.carry_on()

			if self.player.state == "playing":
				self.cmdPlay.set_stock_id("gtk-media-pause")

		# Se il pulsante indica "pause", mette in pausa
		elif self.cmdPlay.get_stock_id() == "gtk-media-pause":
			if self.player.state == "playing":
				self.player.pause()
				if self.player.state == "paused":
					self.cmdPlay.set_stock_id("gtk-media-play")

	# Thread per l'avanzamento del tempo di riproduzione
	def play_thread(self):
		# From http://pygstdocs.berlios.de/pygst-tutorial/seeking.html
		print "PLAY_THREAD"
		play_thread_id = self.player.play_thread_id
		print play_thread_id
		print self.player.play_thread_id
		Gtk.gdk.threads_enter()
		self.labelTime.set_text("00:00 / 00:00")
		Gtk.gdk.threads_leave()

		while play_thread_id == self.player.play_thread_id:
			try:
				time.sleep(0.2)
				if self.player.duration == -1:
					continue
				Gtk.gdk.threads_enter()
				self.labelTime.set_text("00:00 / " + self.player.duration_str)
				Gtk.gdk.threads_leave()
				print "OK 1"
				break
			except:
				print "QUERY_IN_CORSO"
				pass

		time.sleep(0.2)
		while play_thread_id == self.player.play_thread_id:
			pos_int = self.player.player.query_position(gst.FORMAT_TIME, None)[0]
			pos_str = self.player.convert_ns(pos_int)
			if play_thread_id == self.player.play_thread_id:
				Gtk.gdk.threads_enter()
				self.labelTime.set_text(pos_str + " / " + self.player.duration_str)
				self.scaleTime.set_value(float(pos_int)/float(self.player.duration))
				Gtk.gdk.threads_leave()
			time.sleep(0.5)

	# Evento che avanza la barra del tempo
	def on_adjust_bounds(self, *args):
		print "adjust-bound"
		self.player.change_position(self.scaleTime.get_value())

	# Evento per la modifica del volume
	def volume_changed(self, *args):
		try:
			self.player.set_volume(self.volumebutton.get_value())
		except: pass

	# Richiamato quando termina la riproduzione di un brano
	def on_endPlay(self, player_bus, message):
		print "Esecuzione terminata"
		self.set_status()
		self.mainWindow.set_title(WINDOW_TITLE)
		self.cmdStop.set_sensitive(False)
		self.menuStop.set_sensitive(False)
		self.popStop.set_sensitive(False)
		self.scaleTime.set_sensitive(False)
		self.labelTime.set_text("00:00 / 00:00")
		# Passa al brano successivo
		try:
			print "Brano successivo"
			self.on_Next()
		except:
			pass
		#self.scaleTime.set_value(1)

	def on_endError(self, player_bus, message):
		err, debug = message.parse_error()
		print "Error: %s" % err, debug
		self.set_status()
		self.mainWindow.set_title(WINDOW_TITLE)
		self.cmdStop.set_sensitive(False)
		self.menuStop.set_sensitive(False)
		self.popStop.set_sensitive(False)
		self.scaleTime.set_sensitive(False)
		self.labelTime.set_text("00:00 / 00:00")
		#self.scaleTime.set_value(0)

	# Evento per il menu pausa (serve per distinguere l'azione
	# da quello del pulsante play/pause)
	def on_menuPause(self, *args):
		if self.cmdPlay.get_stock_id() == "gtk-media-pause":
			self.on_Play()

	# Evento per il menu play (serve per distinguere l'azione
	# da quello del pulsante play/pause)
	def on_menuPlay(self, *args):
		if self.cmdPlay.get_stock_id() == "gtk-media-play":
			self.on_Play()
		else:
			if self.playing_song == self.Selection(self.FileTable):
				self.on_Play()
				self.on_Play()
			else:
				self.on_Stop()
				self.on_Play()

	# Evento per il doppio click su una riga della tabella
	# e riproduce la canzone clickata
	def on_row_activated(self, *args):
		print "RIGA ATTIVATA"
		try:
			self.player.stop()
			self.cmdPlay.set_stock_id("gtk-media-play")
		except:
			pass
		self.on_Play()

	# Evento per il click sulla tabella dei file
	def on_row_clicked(self, widget, event):

		# Apre il menù contestuale
		if event.button == 3:
			print "TASTO DESTRO"
			if self.Selection(self.FileTable):
				x = int(event.x)
				y = int(event.y)
				time = event.time
				pthinfo = widget.get_path_at_pos(x, y)
				if pthinfo is not None:
					path, col, cellx, celly = pthinfo
					widget.grab_focus()
					widget.set_cursor( path, col, 0)
					self.popupmenu.popup( None, None, None, event.button, time)
					return True
		if event.button == 1:
			print "TASTO SINISTRO"
		if event.type == Gtk.gdk.BUTTON_PRESS:
			print "SINGOLO CLICK"
		elif event.type == Gtk.gdk._2BUTTON_PRESS:
			print "DOPPIO CLICK"
		elif event.type == Gtk.gdk._3BUTTON_PRESS:
			print "TRIPLO CLICK"

	# Evento per la selezione di una riga della tabella
	def on_row_selected(self, *args):
		print "RIGA SELEZIONATA"
		model, pathlist = self.FileTable.tvSelection.get_selected_rows()
		if pathlist:
			rowpath = pathlist[0]
			it = self.FileTable.listStore.get_iter(rowpath)
			for af in self.audioFileList.filelist:
				if str(af.pointer) == model.get_string_from_iter(it):
					print "SELEZIONATO IL FILE: ", af.get_filepath()

	# Evento che ferma la riproduzione
	def on_Stop(self, *args):

		try:
			self.player.stop()
		except: pass
		self.cmdPlay.set_stock_id("gtk-media-play")
		self.set_status()
		self.mainWindow.set_title(WINDOW_TITLE)
		self.cmdStop.set_sensitive(False)
		self.menuStop.set_sensitive(False)
		self.popStop.set_sensitive(False)
		self.scaleTime.set_value(0)
		self.scaleTime.set_sensitive(False)
		self.labelTime.set_text("00:00 / 00:00")


	# Evento che passa a riprodurre la canzone successiva
	def on_Next(self, *args):

		model, pathlist = self.FileTable.tvSelection.get_selected_rows()
		rowpath = pathlist[0]
		self.FileTable.tvSelection.unselect_all()
		self.on_Stop()
		#self.FileTable.tvSelection.select_path(rowpath)
		it = self.FileTable.listStore.get_iter(rowpath)
		root_it = self.FileTable.listStore.get_iter_root()
		next_it = self.FileTable.listStore.iter_next(it)
		if next_it:
			self.FileTable.tvSelection.select_iter(next_it)
			print "on_Next Successivo"
		else:
			try:
				self.FileTable.tvSelection.select_iter(root_it)
				print "on_Next Primo della lista"
			except:
				pass
		self.cmdPlay.set_stock_id("gtk-media-play")
		self.labelTime.set_text("00:00 / 00:00")
		self.on_Play()

	# Evento che passa a riprodurre la canzone precedente
	def on_Prev(self, *args):

		selection = []

		model, pathlist = self.FileTable.tvSelection.get_selected_rows()
		rowpath = pathlist[0]
		self.FileTable.tvSelection.unselect_all()
		self.on_Stop()
		prev_pointer = 0
		prev_it = None
		curr_it = self.FileTable.listStore.get_iter(rowpath)
		for af in self.audioFileList.filelist:
			if str(af.pointer) == model.get_string_from_iter(curr_it):
				prev_pointer = af.pointer - 1
				print "af.pointer: ", af.pointer
				print "prev_pointer: ", prev_pointer
		if prev_pointer > -1:
			self.FileTable.tvSelection.select_all()
			model, pathlist = self.FileTable.tvSelection.get_selected_rows()

			if pathlist:
				iterlist = []
				for rowpath in pathlist:
					try:
						iterlist.append(model.get_iter(rowpath))
					except ValueError:
						pass
				for it in iterlist:
					if str(prev_pointer) == model.get_string_from_iter(it):
						prev_it = it
				if prev_it:
					self.FileTable.tvSelection.unselect_all()
					self.FileTable.tvSelection.select_iter(prev_it)
			else:
				try:
					self.FileTable.tvSelection.select_iter(self.FileTable.listStore.get_iter_root())
				except:
					pass
		self.cmdPlay.set_stock_id("gtk-media-play")
		self.labelTime.set_text("00:00 / 00:00")
		self.on_Play()

	# Evento per l'avanzamento veloce
	def on_Forward(self, *args):

		self.player.forward()

	# Evento per il riavvolgimento veloce
	def on_Rewind(self, *args):

		self.player.rewind()

	# Evento che apre un CD_Audio e carica i tag da freeDB
	# se il server è disponibile
	def on_CD(self, *args):

		self.set_status("Adding Audio CD...")
		self.TagBar.purge()

		self.CDdata = None
		try:
			self.audioCD = CDDBReader()
		except:
			self.set_status("Insert an Audio CD into the drive...")
			self.cmdOpenFile.set_sensitive(True)
			self.cmdOpenFolder.set_sensitive(True)
			self.dlg = WarningDialog(self.mainWindow, NAME + " - Warning", "No disc into the drive. Please insert one...")
			return

		if self.audioCD.is_audio_cd:
			self.audioFileList.purge()
			self.FileTable.purge()
			self.TagBar.show()
			self.cmdPlay.set_stock_id("gtk-media-play")
			self.on_Stop()

			if self.audioCD.query_status == 409:
				self.set_status("No connection to the internet is current available or no server response...")
				self.dlg = WarningDialog(self.mainWindow, NAME + " - Warning","No connection to the internet is current available or no server response...")
				self.TagBar.entry_tag("Unknow album", "Unknow artist", "Unknow year", "Unknow genre")

				for i in range(self.audioCD.disc_id[1]):
					n = "%.02d" %(i + 1)
					af = AudioFile("cdda://" + n, n)
					af.set_tag("track_number", n)
					af.set_tag("title", "Track " + n)
					#af.frame = self.audioCD.disc_id[i+2]
					af.set_filename("Track " + n)
					print af.get_tags_as_dict()
					self.audioFileList.append(af)
					self.set_status("Append " + af.get_filename() + "/" + str(self.audioCD.disc_id[1]))
			else:
				if type(self.audioCD.query_info).__name__ == "list":
					print "E'UNA LISTA"
					cds = []
					for cd in self.audioCD.query_info:
						cds.append([cd["disc_id"], cd["category"], cd["title"]])
					self.CDDBSelection = CDDBSelection(self.mainWindow, cds)
					selected_cd = int(self.CDDBSelection.selected_cd)
					self.audioCD.get_CDDB_tag(self.audioCD.query_status, self.audioCD.query_info[selected_cd])
				else:
					self.audioCD.get_CDDB_tag(self.audioCD.query_status, self.audioCD.query_info)

				self.TagBar.entry_tag(self.audioCD.album, self.audioCD.artist, self.audioCD.year, self.audioCD.cddb_genre)
				self.CDdata = {"album": self.audioCD.album,
							"artist": self.audioCD.artist,
							"year": self.audioCD.year,
							"genre": self.audioCD.cddb_genre
							}
				for song in self.audioCD.song_list:
					af = AudioFile("cdda://" + str("%.02d" %(song["track_number"])), song["track_number"])
					af.set_tag("track_number", "%.02d" %(song["track_number"]))
					af.set_tag("title", song["title"])
					af.set_tag("artist", self.audioCD.artist)
					af.set_tag("album", self.audioCD.album)
					af.set_tag("year", self.audioCD.year)
					af.set_tag("genre", self.audioCD.cddb_genre)
					af.set_filename("Track " + str("%.02d" %(song["track_number"])))
					print af.get_tags_as_dict()
					self.audioFileList.append(af)
					self.set_status("Append " + af.get_filename() + "/" + str(self.audioCD.disc_id[1]))

			# Scrive i file nella tabella
			self.FileTable.append(self.audioFileList)
			self.set_status()
			self.audioCD = None
			self.set_sensitive(True)
			self.cmdRip.set_sensitive(True)

			self.cmdOpenFile.set_sensitive(False)
			self.menuOpenFile.set_sensitive(False)

			self.cmdOpenFolder.set_sensitive(False)
			self.menuOpenFolder.set_sensitive(False)

			self.cmdConvert.set_sensitive(False)
			self.menuConvert.set_sensitive(False)
		else:
			self.audioCD = None
			return

	# Evento che cambia i dati del CD su modifica utente
	def on_entry_changed(self, *args):
		print "CHANGED"
		self.CDdata = {"album": self.TagBar.entryAlbum.get_text(),
						"artist": self.TagBar.entryArtist.get_text(),
						"year": self.TagBar.entryYear.get_text(),
						"genre": self.TagBar.entryGenre.get_text()
						}
		for af in self.audioFileList.filelist:
			af.set_tag("album", self.CDdata["album"])
			af.set_tag("artist", self.CDdata["artist"])
			af.set_tag("year", self.CDdata["year"])
			af.set_tag("genre", self.CDdata["genre"])

		self.FileTable.purge()
		self.FileTable.append(self.audioFileList)

	# Evento che apre la finestra di scelta per il ripping del CD
	def on_Rip(self, *args):

		try:
			from morituri.rip import main as Ripper
		except:
			self.dlg = WarningDialog(self.mainWindow, NAME + " - Warning",'''Morituri is not available.
Please try 'apt-get install morituri' or
visit http://thomas.apestaart.org/morituri/trac/wiki''')
			return

		#Apre la finestra di dialogo con le impostazioni
		dlgRip = RipDialog(self.mainWindow, self.prefs)
		dlgRip.show()

		if not dlgRip.response == Gtk.ResponseType.OK:
			return
		else:
			self.set_status("Ripping Audio CD ...")

			# Posizione temporanea
			import tempfile
			tempdir = tempfile.mkdtemp()

			# Ripping del CD audio in una directory temporanea
			# Argomenti da passare:
			# rip_args = ['cd', 'rip', '--output-directory=' + tempdir, '--track-template=%t - %n', '--profile=wav']
			# In morituri waveenc non funziona. Bisogna lasciare l'uscita di default in flac
			rip_args = ['cd', 'rip', '--output-directory=' + tempdir, '--track-template=%t - %n']
			try:
				# Avvia l'estrazione
				ret = Ripper.main(rip_args)
				ret = 0
			except:
				self.dlg = WarningDialog(self.mainWindow, NAME + " - Warning", "Task exception. Morituri don't work.")
				ret = -1
				self.set_status()
				return
			if ret == 0:
				self.set_status("Ripping completed...")

			# Carica i file da convertire
			walk = os.walk(tempdir)
			convert_filelist = []
			for dirpath, subdir, filenames in walk:
				for f in filenames:
					if f[-5:] == ".flac":
						f = os.path.join(dirpath, f)
						convert_filelist.append(AudioFile("file://" + f))

			#Carica la lista dei file selezionati
			if not bool(int(self.prefs.get_option("save-all-tracks"))):
				# Solo i file selezionati
				self.selconv = self.Selection(self.FileTable)
			else:
				# Tutti i file
				self.FileTable.tvSelection.select_all()
				self.selconv = self.Selection(self.FileTable)
				self.FileTable.tvSelection.unselect_all()

			if self.selconv:
				temp_format = self.prefs.get_option("output-format")
				# Inizializza la coda
				request_queue = Queue.Queue()
				n = 0
				for sel in self.selconv:
					n += 1
					af = sel[0]
					it = sel[1]

					for convert_file in convert_filelist:
						if af.get_tag("track_number") == convert_file.get_filename()[0:2]:
							convert_file.set_tags_as_dict(af.get_tags_as_dict())
							# Salva non compressi
							if not bool(int(self.prefs.get_option("rip-compressed"))) or self.prefs.get_option("output-format") == "wav":
								self.prefs.set_option("output-format", "wav")
								request_queue.put([n, (convert_file, it)])
								self.set_status("Now save uncompressed files...")
							elif bool(int(self.prefs.get_option("rip-compressed"))):
								request_queue.put([n, (convert_file, it)])
								self.set_status("Now save compressed files...")
				self.init = time.time()
				self.progConvert.show()

				# Riempita la coda, lancia il thread dell'encoder
				self.encoder_thread = Converter(self, self.prefs, request_queue)
				self.encoder_thread.start()

				# Svuota la coda per fermare il thread
				for sel in self.selconv:
					request_queue.put(None)
				self.FileTable.tvSelection.unselect_all()
				self.set_status("Done...")

	# Evento per la conversione dei file audio
	def on_Convert(self, *args):

		#Apre la finestra di dialogo con le impostazioni
		dlgCon = ConverterDialog(self.mainWindow, self.prefs)
		dlgCon.show()

		if not dlgCon.response == Gtk.ResponseType.OK:
			return

		#Carica la lista dei file selezionati
		if not bool(int(self.prefs.get_option("save-all-tracks"))):
			# Solo i file selezionati
			self.selconv = self.Selection(self.FileTable)
		else:
			# Tutti i file
			self.FileTable.tvSelection.select_all()
			self.selconv = self.Selection(self.FileTable)
			self.FileTable.tvSelection.unselect_all()

		if self.selconv:
			# Inizializza la coda
			request_queue = Queue.Queue()
			n = 0
			for sel in self.selconv:
				n += 1
				af = sel[0]
				it = sel[1]

				# Status bar
				if af.get_tag("title") != "Unknown title" and af.get_tag("artist") != "Unknown artist":
					self.msg = af.get_tag("artist") + " - " + af.get_tag("title")
				elif af.get_uri():
					self.msg = af.get_filepath()
				self.set_status("Converting " + self.msg + " (file " + str(n) + "/" + str(len(self.selconv)) + ")")

				# Riempie la coda caricando le preferenze
				request_queue.put([n, sel])

			self.init = time.time()
			self.progConvert.show()

			# Riempita la coda, lancia il thread dell'encoder
			self.encoder_thread = Converter(self, self.prefs, request_queue)
			self.encoder_thread.start()

			# Svuota la coda per fermare il thread
			for sel in self.selconv:
				request_queue.put(None)
			
			self.FileTable.tvSelection.unselect_all()			

	# Aggiorna la progressbar durante la conversione
	def on_ProgressBar(self):

		self.progConvert.set_fraction(self.encoder_thread.amount_completed)
		if self.encoder_thread.work_complete:
			self.progConvert.set_fraction(1)
			if self.encoder_thread.queue_complete:
				if bool(int(self.prefs.get_option("playlist"))):
					self.write_playlist(self.encoder_thread.savepath, self.encoder_thread.playlistname, self.encoder_thread.listsongs)
				self.progConvert.set_text("Complete!")
				print "Complete!"
				self.set_status("Done in " + str(round(time.time() - self.init, 2)) + " seconds")
				self.progConvert.set_fraction(1)
		else:
			self.progConvert.set_text("%d%%" % (self.encoder_thread.amount_completed * 100))
			self.set_status("Converting " + self.encoder_thread.msg + \
					" (file " + str(self.encoder_thread.n) + "/" + str(len(self.selconv)) + ")" + \
					" - " + ("%f" % (round(time.time() - self.init, 2)))[:4] + " seconds")
		return not self.encoder_thread.work_complete

	# Crea la playlist dei brani convertiti
	def write_playlist(self, savepath, playlistname, listsongs):

		playlist = open(savepath + "/" + playlistname + ".m3u", "wb")
		playlist.writelines(listsongs)
		playlist.close()

	# Seleziona tutte le righe
	def on_SelectAll(self, *args):

		self.FileTable.tvSelection.select_all()

	# Deseleziona tutte le righe
	def on_UnselectAll(self, *args):

		self.FileTable.tvSelection.unselect_all()

	# Proprietà della canzone
	def on_Property(self, *args):

		#Carica la lista dei file selezionati
		self.selplay = self.Selection(self.FileTable)
		# Riproduce solo il primo file della lista caricata
		try:
			sel = self.selplay[0]
		except IndexError:
			sel = None
		self.playing_song = sel
		if sel:
			af = sel[0]
			it = sel[1]
			self.FileTable.tvSelection.unselect_all()
			self.FileTable.tvSelection.select_iter(it)

			dlgprop = PropertyDialog(self, self.mainWindow, sel)
			dlgprop.show()

	# Modifica i tag
	def on_Tagger(self, *args):

		#Carica la lista dei file selezionati
		self.selplay = self.Selection(self.FileTable)
		# Riproduce solo il primo file della lista caricata
		try:
			sel = self.selplay[0]
		except IndexError:
			sel = None
		if sel:
			af = sel[0]
			it = sel[1]
			self.FileTable.tvSelection.unselect_all()
			self.FileTable.tvSelection.select_iter(it)

		dlgtag = TaggerDialog(self, self.mainWindow, sel)
		dlgtag.show()

		if not dlgtag.response == Gtk.ResponseType.OK:
			return
 
		if dlgtag.save_tags:
			if dlgtag.save_tags_all:
				for af in self.audioFileList.filelist:
					af.write_metadata()
					if dlgtag.id3v2:
						af.write_ID3v2()
			else:
				selection = self.Selection(self.FileTable)
				sel = selection[0]
				sel[0].write_metadata()
				if dlgtag.id3v2:
					sel[0].write_ID3v2()		
				i = self.audioFileList.filelist.index(sel[0])
				self.audioFileList.remove(sel[0].get_uri())
				self.audioFileList.filelist.insert(i, AudioFile(sel[0].get_uri()))

		elif dlgtag.remove_tags:
			if dlgtag.remove_tags_all:
				for af in self.audioFileList.filelist:
					af.remove_metadata()
			else:
				selection = self.Selection(self.FileTable)
				sel = selection[0]
				sel[0].remove_metadata()
				i = self.audioFileList.filelist.index(sel[0])
				self.audioFileList.remove(sel[0].get_uri())
				self.audioFileList.filelist.insert(i, AudioFile(sel[0].get_uri()))

		self.FileTable.purge()
		self.FileTable.append(self.audioFileList)

	# Crea una playlist
	def on_Playlist(self, *args):

		dlgpl = PlaylistDialog(self, self.mainWindow)
		dlgpl.show()

		if not dlgpl.response == Gtk.ResponseType.OK:
			return


	# Restituisce una lista di file audio selezionati
	def Selection(self, FileTable):

		selection = []

		model, pathlist = FileTable.tvSelection.get_selected_rows()
		print "pathlist: ", pathlist
		if not pathlist:
			print "not"
			try:
				pathlist = [(0,)]
				print "pathlist: ", pathlist
			except:
				pass
		if pathlist:
			print "pathlist: ", pathlist
			iterlist = []
			for rowpath in pathlist:
				print "rowpath: ", rowpath
				try:
					iterlist.append(model.get_iter(rowpath))
				except ValueError:
					pass
			print "iterlist: ", iterlist
			for it in iterlist:
				print "riga da riprodurre", model.get_string_from_iter(it)
				for af in self.audioFileList.filelist:
					print "af.pointer: ", af.pointer
					print "model.get_string_from_iter(iter): ", model.get_string_from_iter(it)
					if str(af.pointer) == model.get_string_from_iter(it):
						print "sono uguali"
						selection.append((af, it))
						print "Selection: ", selection
					else:
						print "non sono uguali"
		return selection

	# Funzione che apre il selettore file e carica i file scelti
	def AddFileList(self, FileChooser):

		# Imposta la cartella corrente
		try:
			if os.path.exists(self.prefs.get_option("last-used-folder")):
				FileChooser.set_current_folder(self.prefs.get_option("last-used-folder"))
			else:
				FileChooser.set_current_folder(os.path.expandvars("$HOME"))
			# Eccezione nel caso in cui non sia definita.
			# In tal caso la cartella corrente viene settata sulla HOME.
		except:
			FileChooser.set_current_folder(os.path.expandvars("$HOME"))

		# Seleziona la risposta
		response = FileChooser.run()
		if response == Gtk.ResponseType.OK:

			if FileChooser.is_folder:
				# Se il percorso restituito è una cartella
				# crea una lista con i file audio presenti nella cartella
				# e nelle sue sottocartelle.
				walk = os.walk(FileChooser.get_current_folder())

				# Restituisce una lista con tutti i file
				walk_filelist = []
				for dirpath, subdir, filenames in walk:
					print "dirpath: ", dirpath
					print "dirnames: ", subdir
					for f in filenames:
						f = os.path.join(dirpath, f)
						walk_filelist.append(f)
					print "listone: ", walk_filelist

				# Aggiunge l'uri completo ad ogni file
				furi = []
				for f in walk_filelist:
					for ext in fileext:
						if f[-4:] == ext:
							furi.append("file://" + str(f))
				for l in furi:
					print "fpathList: ", l
				self.audioFileList.add_list(furi)		

			else:
				# Se il percorso restituito è un file o un elenco di file
				filenames = []
				print FileChooser.get_filenames()[0]
				if FileChooser.get_filenames():					
					for f in FileChooser.get_filenames():
						print "f ", FileChooser.get_filenames()
						# Se il percorso restituito è una plaulist "*.m3u"
						if f[-4:] == ".m3u":
							plist = open(f, "rb").readlines()
							for finlist in plist:
								if not "#EXT" in finlist:
									print re.compile("\n").sub("", finlist)
									print "PERCORSO FILE IN PLAYLIST", "file://" + FileChooser.get_current_folder() + "/" + re.compile("\n").sub("", finlist)
									filenames.append("file://" + FileChooser.get_current_folder() + "/" + re.compile("\n").sub("", finlist))
						else:
							filenames.append("file://" + f)
							print filenames
				self.audioFileList.add_list(filenames)
				print "LISTA APPESA ", self.audioFileList.filelist
			# Scrive i file nella tabella
			self.FileTable.append(self.audioFileList)

		elif response == Gtk.ResponseType.CANCEL:
			print 'Closed, no files selected'

		self.prefs.set_option("last-used-folder", FileChooser.get_current_folder())
		FileChooser.hide()
		FileChooser.destroy()
		self.set_status()

		if not self.audioFileList.filelist:
			print "LISTA VUOTA"
			self.set_sensitive(False)
			self.cmdConvert.set_sensitive(False)
		else:
			self.set_sensitive(True)
			self.cmdConvert.set_sensitive(True)

	# Funzione che verifica se il file audio esiste
	def file_exists(self, af):
		if os.path.exists(af.get_filepath()):
			return True
		elif af.get_uri()[:7] == "cdda://":
			return True
		else:
			dlg = WarningDialog(self.mainWindow, NAME + " - Warning", "The file " + af.get_filepath()  + " does not exist in the specified path. Perhaps it was deleted.")
			return False
	def on_CD(self, *args):

		self.set_status("Adding Audio CD...")
		self.TagBar.purge()

		self.CDdata = None
		try:
			self.audioCD = CDDBReader()
		except:
			self.set_status("Insert an Audio CD into the drive...")
			self.cmdOpenFile.set_sensitive(True)
			self.cmdOpenFolder.set_sensitive(True)
			self.dlg = WarningDialog(self.mainWindow, NAME + " - Warning", "No disc into the drive. Please insert one...")
			return

		if self.audioCD.is_audio_cd:
			self.audioFileList.purge()
			self.FileTable.purge()
			self.TagBar.show()
			self.cmdPlay.set_stock_id("gtk-media-play")
			self.on_Stop()

			if self.audioCD.query_status == 409:
				self.set_status("No connection to the internet is current available or no server response...")
				self.dlg = WarningDialog(self.mainWindow, NAME + " - Warning","No connection to the internet is current available or no server response...")
				self.TagBar.entry_tag("Unknow album", "Unknow artist", "Unknow year", "Unknow genre")

				for i in range(self.audioCD.disc_id[1]):
					n = "%.02d" %(i + 1)
					af = AudioFile("cdda://" + n, n)
					af.set_tag("track_number", n)
					af.set_tag("title", "Track " + n)
					#af.frame = self.audioCD.disc_id[i+2]
					af.set_filename("Track " + n)
					print af.get_tags_as_dict()
					self.audioFileList.append(af)
					self.set_status("Append " + af.get_filename() + "/" + str(self.audioCD.disc_id[1]))
			else:
				if type(self.audioCD.query_info).__name__ == "list":
					print "E'UNA LISTA"
					cds = []
					for cd in self.audioCD.query_info:
						cds.append([cd["disc_id"], cd["category"], cd["title"]])
					self.CDDBSelection = CDDBSelection(self.mainWindow, cds)
					selected_cd = int(self.CDDBSelection.selected_cd)
					self.audioCD.get_CDDB_tag(self.audioCD.query_status, self.audioCD.query_info[selected_cd])
				else:
					self.audioCD.get_CDDB_tag(self.audioCD.query_status, self.audioCD.query_info)

				self.TagBar.entry_tag(self.audioCD.album, self.audioCD.artist, self.audioCD.year, self.audioCD.cddb_genre)
				self.CDdata = {"album": self.audioCD.album,
							"artist": self.audioCD.artist,
							"year": self.audioCD.year,
							"genre": self.audioCD.cddb_genre
							}
				for song in self.audioCD.song_list:
					af = AudioFile("cdda://" + str("%.02d" %(song["track_number"])), song["track_number"])
					af.set_tag("track_number", "%.02d" %(song["track_number"]))
					af.set_tag("title", song["title"])
					af.set_tag("artist", self.audioCD.artist)
					af.set_tag("album", self.audioCD.album)
					af.set_tag("year", self.audioCD.year)
					af.set_tag("genre", self.audioCD.cddb_genre)
					af.set_filename("Track " + str("%.02d" %(song["track_number"])))
					print af.get_tags_as_dict()
					self.audioFileList.append(af)
					self.set_status("Append " + af.get_filename() + "/" + str(self.audioCD.disc_id[1]))

			# Scrive i file nella tabella
			self.FileTable.append(self.audioFileList)
			self.set_status()
			self.audioCD = None
			self.set_sensitive(True)
			self.cmdRip.set_sensitive(True)

			self.cmdOpenFile.set_sensitive(False)
			self.menuOpenFile.set_sensitive(False)

			self.cmdOpenFolder.set_sensitive(False)
			self.menuOpenFolder.set_sensitive(False)

			self.cmdConvert.set_sensitive(False)
			self.menuConvert.set_sensitive(False)
		else:
			self.audioCD = None
			return