#!/usr/bin/python
#
# We're using PySide, Nokia's official LGPL bindings.
# You can however easily use PyQt (Riverside Computing's GPL bindings) by commenting these and fixing the appropriate imports.
import sys, os, time, thread
import subprocess
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtMaemo5 import QMaemo5ValueButton
import dbus.mainloop.qt
 
# In Qt, everything is a class.
# We can subclass stuff to do whatever we want - it seems a bit strange at first,
# but it keeps all related functionality in one place, which helps to keep you organised.
#
# We're subclassing 'QWidget' here. QWidget is the base class for all graphical elements in Qt.
# You can do all sorts of cool things like drawing your widget yourself, but we won't get into that.
#
# See also:
#   http://doc.trolltech.com/4.6/qwidget.html

####################
# Global variables #
####################
MediaInfo_guiVersion = "0.0.1-3"
mediainfo_exec = "/opt/mediainfo/mediainfo"
Advanced = False
Home = os.path.expanduser("~")
CommentChar = '#'
OptionChar =  ' '
MediaInfo_gui_CfgDir = Home + '/.config/mediainfo-gui/'
MediaInfo_gui_CfgFile = MediaInfo_gui_CfgDir + 'mediainfo-gui.cfg'
MediaInfoTXT = ""
currPath = ""

def parse_config(self, filename):
	options = {}
	f = open(filename)
	for line in f:
		# First, remove comments:
		if CommentChar in line:
			# split on comment char, keep only the part before
			line, comment = line.split(CommentChar, 1)
		# Second, find lines with an option=value:
		if OptionChar in line:
			# split on option char:
			option, value = line.split(OptionChar, 1)
			# strip spaces:
			option = option.strip()
			value = value.strip()
			# store in dictionary:
			options[option] = value
	f.close()
 	return options

class MyMainWindow(QMainWindow):
    def __init__(self, parent=None):# first things first, we need to initialise the Qt parent, otherwise it won't work properly.
        #
	super(MyMainWindow, self).__init__(parent)
        self.setAttribute(Qt.WA_Maemo5StackedWindow)
	global Orientation
	self.setWindowTitle(self.tr("mediainfo-gui"))
	# catch dbus signal for keyboard slider
	dbus.mainloop.qt.DBusQtMainLoop(set_as_default=True)
	bus = dbus.SystemBus()
	bus.add_signal_receiver(self.handle_slide, path='/org/freedesktop/Hal/devices/platform_slide', dbus_interface='org.freedesktop.Hal.Device', signal_name='PropertyModified')
	# Create config dir if needed
	if not os.path.exists(MediaInfo_gui_CfgDir):
		os.mkdir(MediaInfo_gui_CfgDir)
	# Create config files if needed
	if not os.path.isfile(MediaInfo_gui_CfgFile):
		try:
			newConfigFile = open(MediaInfo_gui_CfgFile,"w")
		except:
			QMessageBox.critical(self, "Warning",  "Cannot write " + MediaInfo_gui_CfgFile)
		else:
			newConfigFile.write("orientation auto\n")
			newConfigFile.write("advanced false\n")
			newConfigFile.close()
	else:
		orientationset = False
		advancedset = False
		ConfigFile = open(MediaInfo_gui_CfgFile,"r")
		lines = ConfigFile.readlines()
		for line in lines:
			if 'orientation' in line:
				orientationset = True
			if 'advanced' in line:
				advancedset = True
		ConfigFile.close()
		if not orientationset or not advancedset: 
			ConfigFile = open(MediaInfo_gui_CfgFile,"a")
			if not orientationset:
				ConfigFile.write("orientation auto\n")
			if not advancedset:
				ConfigFile.write("advanced false\n")
			ConfigFile.close()

	self.form_widget = FormWidget(self)
	self.setCentralWidget(self.form_widget)
	###############
	# read config #
	###############
	global OptionChar
	OptionChar = " "
	self.mediainfo_gui_opts = parse_config(self,MediaInfo_gui_CfgFile)
	VersionMediaInfo = mediainfo_exec + " --version" 
        fin,fout = os.popen4(VersionMediaInfo)
        self.AboutMediaInfo = fout.read()
        self.AboutMediaInfo = "Using " + self.AboutMediaInfo.replace('\n','<br>')

	###############
	# Create menu #
	###############
	orientationGroup = QActionGroup(self)
	orientationGroup.setExclusive(True)
	self.landscapeAction = QAction( '&Landscape' ,self)
	self.landscapeAction.setCheckable(True)
	self.portraitAction = QAction( '&Portrait' ,self)
	self.portraitAction.setCheckable(True)
	self.autorotateAction = QAction( '&Autorotate' ,self)
	self.autorotateAction.setCheckable(True)
	orientationGroup.addAction(self.landscapeAction)
	orientationGroup.addAction(self.autorotateAction)
	orientationGroup.addAction(self.portraitAction)
	
	self.advancedAction = QAction( '&Extended info', self)
	self.advancedAction.setCheckable(True)
	if self.mediainfo_gui_opts["advanced"] == "true":
		self.advancedAction.setChecked(True)
	self.orientationAction = QAction( '', self)
	if self.mediainfo_gui_opts["orientation"] == "portrait":
		self.portraitAction.setChecked(True)
		self.setAttribute(Qt.WA_Maemo5PortraitOrientation, True)
	elif self.mediainfo_gui_opts["orientation"] == "landscape":
		self.landscapeAction.setChecked(True)
		self.setAttribute(Qt.WA_Maemo5LandscapeOrientation, True)
	else:
		self.autorotateAction.setChecked(True)
		self.setAttribute(Qt.WA_Maemo5AutoOrientation, True)

	aboutAction = QAction( '&About', self)

	########################
	# create menu from bar #
	########################
	menubar = self.menuBar()
	mainMenu = menubar.addMenu('&MainMenu')
	mainMenu.addActions(orientationGroup.actions())
	mainMenu.addAction(self.advancedAction)
	mainMenu.addAction(aboutAction)

	##################
	# Define actions #
	##################
	self.portraitAction.triggered.connect(self.portraitPushed)
	self.landscapeAction.triggered.connect(self.landscapePushed)
	self.autorotateAction.triggered.connect(self.autorotatePushed)
	self.advancedAction.triggered.connect(self.advancedPushed)
	aboutAction.triggered.connect(self.aboutPushed)

	################################################################
	# set initial orientation to landscape if kb open and portrait #
	################################################################
        kb_state = os.popen('cat /sys/devices/platform/gpio-switch/slide/state').read().strip()
        if kb_state == "open" and self.mediainfo_gui_opts["orientation"] == "portrait":
		self.setAttribute(Qt.WA_Maemo5LandscapeOrientation, True)

    def handle_slide(self,var1,var2):
	currOrientation = self.mediainfo_gui_opts["orientation"]
        kb_state = os.popen('cat /sys/devices/platform/gpio-switch/slide/state').read().strip()
        if kb_state == "open" and currOrientation == "portrait":
		self.setAttribute(Qt.WA_Maemo5LandscapeOrientation, True)
	elif currOrientation == "portrait":
			self.setAttribute(Qt.WA_Maemo5PortraitOrientation, True)
		
    def saveSettings(self):
	if self.advancedAction.isChecked():
		self.mediainfo_gui_opts["advanced"] = "true"
	else: self.mediainfo_gui_opts["advanced"] = "false"
	if self.portraitAction.isChecked():
		self.mediainfo_gui_opts["orientation"] = "portrait"
	if self.landscapeAction.isChecked():
		self.mediainfo_gui_opts["orientation"] = "landscape"
	if self.autorotateAction.isChecked():
		self.mediainfo_gui_opts["orientation"] = "auto"
	try:
		newConfigFile = open(MediaInfo_gui_CfgFile,"w")
		for option in self.mediainfo_gui_opts:
			newConfigFile.write(option + " " + self.mediainfo_gui_opts[option] + "\n")
		newConfigFile.close()
		os.system('run-standalone.sh dbus-send --type=method_call --dest=org.freedesktop.Notifications  \
			/org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteInfoprint \
			string:"Configuration is successfully saved"')
	except:
		os.system('run-standalone.sh dbus-send --type=method_call --dest=org.freedesktop.Notifications  \
			/org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteInfoprint \
			string:"Could NOT save Configuration!"')

    def advancedPushed(self):
	global Advanced
	if self.advancedAction.isChecked():
		Advanced = True
	else:
		Advanced = False
	self.saveSettings()

    def portraitPushed(self):
	if self.mediainfo_gui_opts["orientation"] != "portrait":
		self.setAttribute(Qt.WA_Maemo5PortraitOrientation, True)
		self.saveSettings()
	
    def landscapePushed(self):
	if self.mediainfo_gui_opts["orientation"] != "landscape":
		self.setAttribute(Qt.WA_Maemo5LandscapeOrientation, True)
		self.saveSettings()

    def autorotatePushed(self):
	if self.mediainfo_gui_opts["orientation"] != "auto":
		self.setAttribute(Qt.WA_Maemo5AutoOrientation, True)
		self.saveSettings()

    def aboutPushed(self):
	d = QDialog(self)
	vbox = QVBoxLayout()
	verticalLayout = QVBoxLayout() 
	verticalLayout.addWidget(QLabel("<center><img src=/opt/usr/share/icons/hicolor/64x64/apps/MediaInfo.png /></center>"),0)
	verticalLayout.addWidget(QLabel("<center>Version "+MediaInfo_guiVersion+"</center>"),1)
	verticalLayout.addWidget(QLabel("<center>Created by Arno Dekker (ade)</center>"),2)
	verticalLayout.addWidget(QLabel("<center>"+self.AboutMediaInfo+"</center>"),3)
	vbox.addLayout (verticalLayout)
	d.setLayout(vbox)
	d.show()

class FormWidget(QWidget):
    def __init__(self, parent):
	super(FormWidget, self).__init__(parent)

	# Now we start getting into building our interface. The first thing we need to learn about are layouts.
	# Layouts tell Qt where to put widgets, and how they fit with other widgets.
	# Unlike Gtk+, Qt layouts are *not* widgets - important difference to keep in mind.
	#
	# There are many types of layouts (from the complex, like QGridLayout) 
	# to the simple, like what we're using here.
	# See also:
	#   http://doc.trolltech.com/4.6/qlayout.html
	#   http://doc.trolltech.com/4.6/qvboxlayout.html
        # Layout
        grid = QGridLayout()
        infoTXT = "<h2><u>MediaInfo-gui</u></h2><p><p>" \
		"<img src=/opt/usr/share/icons/hicolor/64x64/apps/MediaInfo.png /><p>" \
		"MediaInfo is a convenient unified display of the most relevant technical and tag data for video and audio files.<p>" \
		'<FONT FACE= "Courier New"><a href="http://mediainfo.sourceforge.net/">Visit mediainfo homepage</a><br>'
        headerLabel = QLabel(infoTXT)
        headerLabel.setStyleSheet(
        "QLabel { font:bold; }"
                )
        headerLabel.setAlignment(Qt.AlignCenter | Qt.AlignLeft)
	headerLabel.setWordWrap(True)
        headerLabel.setOpenExternalLinks(True)
        self.mediafileButton = QPushButton("Select media file",self)
        grid.addWidget(headerLabel,0,0)
        grid.addWidget(self.mediafileButton,1,0)
	self.connect(self.mediafileButton, SIGNAL("clicked()"),self.fileButtonPressed)
        self.setLayout(grid)

    def fileButtonPressed(self):
	widget = fileWindow(self)
	widget.show()
	

class fileWindow(QWidget):
    def __init__(self,parent):
	super(fileWindow, self).__init__(parent)
	self.wg = QDialog(self)
	self.wg.resize(398, 692)
	sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding)
	sizePolicy.setHorizontalStretch(0)
	sizePolicy.setVerticalStretch(0)
	sizePolicy.setHeightForWidth(self.wg.sizePolicy().hasHeightForWidth())
	self.wg.setSizePolicy(sizePolicy)

	self.wg.setWindowTitle("Choose mediafile")
	# folderbutton up
	folderButton_up = QPushButton(self.wg)
	folderButton_up.setIcon(QIcon.fromTheme("filemanager_folder_up"))
	folderButton_up.setMinimumSize(QSize(74,70))
	folderButton_up.setMaximumSize(QSize(74,70))
	# folder display
	self.folderButton = QMaemo5ValueButton(self.wg)
	self.folderButton.setIcon(QIcon.fromTheme("general_folder"))
	self.folderButton.setMinimumSize(QSize(0,70))
	# file list
	self.listWidget = QListWidget(self.wg)
	sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
	sizePolicy.setHeightForWidth(self.listWidget.sizePolicy().hasHeightForWidth())
	self.listWidget.setSizePolicy(sizePolicy)
        self.listWidget.setMinimumSize(QSize(200, 0))
        self.listWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.listWidget.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.listWidget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
	# add to grid
	self.grid = QGridLayout(self.wg)
	self.grid.addWidget(folderButton_up,0,0,1,1)
	self.grid.addWidget(self.folderButton,0,1,1,1)
	self.grid.addWidget(self.listWidget, 2, 0, 1, 2)
	# actions
	self.connect(QApplication.desktop(), SIGNAL("resized(int)"), self.orientationChanged)
	self.connect(folderButton_up, SIGNAL("clicked()"),self.on_folderButton_up_clicked)
	self.connect(self.listWidget, SIGNAL("itemClicked(QListWidgetItem *)"), self.on_listWidget_itemClicked)

	# set initial path
	if not currPath:
		path = "/home/user/MyDocs"
	else:
		path = currPath
	fileInfo = QFileInfo(path)
	self.folderButton.setText( fileInfo.fileName() )
	if path == "/":
		self.folderButton.setText( "/" )
		self.folderButton.setValueText( "" )
	self.FillBrowser(path)
	self.wg.show()

    def orientationChanged(self):
	screenGeometry = QApplication.desktop().screenGeometry()
	if screenGeometry.width() < screenGeometry.height():
		# portrait
		self.wg.resize(398, 692)

    def FillBrowser (self,Directory):
	global currPath
	currPath = Directory
	self.folderButton.setText( QFileInfo(Directory).fileName() )
	self.folderButton.setValueText(Directory)
	if Directory == "/":
		self.folderButton.setText("/")
		self.folderButton.setValueText("")
	self.listWidget.clear()

	# sort dirs/files case-insensitive
	dirs = sorted([d for d in os.listdir(Directory) if os.path.isdir(Directory + os.path.sep + d)])
	dirs.sort(key=lambda y: y.lower())
	filelist = sorted([f for f in os.listdir(Directory) if os.path.isfile(Directory + os.path.sep + f)])
	filelist.sort(key=lambda y: y.lower())
	dirs.extend(filelist)

	# add revelant ones to the list
	teller = 0
	for fileName in dirs:
		teller += 1
		f=os.path.join(Directory, fileName)
		if fileName == "." or fileName == "..":
			continue
		elif os.path.isdir(f):
			item1 = QListWidgetItem( self.listWidget )
			item1.setText(fileName)
			
			if fileName == ".videos":
				item1.setIcon(QIcon.fromTheme("filemanager_video_folder"))
			elif fileName == ".sounds":
				item1.setIcon(QIcon.fromTheme("filemanager_audio_folder"))
			elif fileName == "DCIM":
				item1.setIcon(QIcon.fromTheme("filemanager_camera_folder"))
			elif fileName == ".documents":
				item1.setIcon(QIcon.fromTheme("filemanager_document_folder"))
			elif fileName == ".images":
				item1.setIcon(QIcon.fromTheme("filemanager_image_folder"))
			else:
				item1.setIcon(QIcon.fromTheme("general_folder"))
			self.listWidget.insertItem( teller, item1 )
		elif os.path.isfile(f):
			if fileName.lower().endswith(('.wav','.mp3','.flac','.aac','.ogg','.wma','.ogm','.mp2' \
				,'.ac3','.dts','.ape','.mac','.au','.iff','.w64','.pvf','.xi','.sds','.avr','.ra','rm')):
				item1 = QListWidgetItem( self.listWidget )
				item1.setText(fileName)
				item1.setIcon(QIcon.fromTheme("general_audio_file"))
				self.listWidget.insertItem( teller, item1 )
			if fileName.lower().endswith(('.mkv','.mpg','.avi','.mpeg','.mp4','.wmv','.divx','.mov', \
				'm2ts','ts','flv','.mka','.mks','.mpv','.m1v','.mv2','.ifo','.asf')):
				item1 = QListWidgetItem( self.listWidget )
				item1.setText(fileName)
				item1.setIcon(QIcon.fromTheme("general_video_file"))
				self.listWidget.insertItem( teller, item1 )
			if fileName.lower().endswith(('.jpg','.jpeg','.bmp','.png','.gif')):
				item1 = QListWidgetItem( self.listWidget )
				item1.setText(fileName)
				item1.setIcon(QIcon.fromTheme("general_image"))
				self.listWidget.insertItem( teller, item1 )

	if self.listWidget.count() > 0:
		self.listWidget.scrollToItem(self.listWidget.item(0))

    def on_folderButton_up_clicked(self):
	if  currPath == "/":
		return
	nPath = os.path.dirname(os.path.dirname(currPath+'/'))
	if nPath == "":
		nPath = "/"
	self.FillBrowser( nPath )
	
    def on_listWidget_itemClicked(self,item):
	global MediaInfoTXT
	global MediaInfoTXT
	temp = currPath
	if temp != "/":
		temp = temp + "/"
	temp =temp + item.text()

	if os.path.isfile(temp):
                self.wg.close()
		os.system('run-standalone.sh dbus-send --type=method_call --dest=org.freedesktop.Notifications  \
			/org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteInfoprint \
			string:"Collecting information..."')
		if Advanced:
			MediaInfo_show = mediainfo_exec + " --Output=HTML --Full " + "'"+temp+"'"
		else:
			MediaInfo_show = mediainfo_exec + " --Output=HTML " + "'"+temp+"'"
		# print MediaInfo_show
		fin,fout = os.popen4(MediaInfo_show)
		MediaInfoTXT = fout.read()
		MediaInfoTXT = MediaInfoTXT.replace(currPath+'/',"")
		a = AboutWindow(self)
		a.show()
	elif os.path.isdir(temp):
        	self.FillBrowser(temp)

class AboutWindow(QMainWindow):
    def __init__(self, parent):
        QMainWindow.__init__(self, parent)
        self.setWindowTitle("file info")
        self.setAttribute(Qt.WA_Maemo5StackedWindow)
        self.setAttribute(Qt.WA_DeleteOnClose)
        area = QScrollArea()
        area.setWidgetResizable(True)
        area.setEnabled(True)

        lay = QVBoxLayout()
        lay.addWidget(area)
        wg = QWidget()
        area.setWidget(wg)
        self.setCentralWidget(area)
        #wg.resize(792,550);
	sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
	sizePolicy.setHeightForWidth(wg.sizePolicy().hasHeightForWidth())
	wg.setSizePolicy(sizePolicy)
        grid = QGridLayout(wg)
        wg.show()
        area.show()
        self.setLayout(grid)
        self.label = QLabel(self)
	self.label.setWordWrap(True)
        AboutTxt = "<font style='color: black'" 
	AboutTxt = AboutTxt + MediaInfoTXT
        self.label.setText(AboutTxt)
#        self.label.setAlignment(Qt.AlignCenter | Qt.AlignLeft)
        self.label.setStyleSheet("QWidget {background-color: white }")
        grid.addWidget(self.label)


if __name__ == '__main__':
    # QApplication controls things relating to a Qt application, like the main loop.
    # You should always instantiate it before using any QtGui related stuff.
    # See also:
    #   http://doc.trolltech.com/4.6/qapplication.html
    app = QApplication(sys.argv)
 
    # Create an instance (calling __init__, too, of course) of our window subclassing QWidget
    w = MyMainWindow()

    # Show our window
    w.show()
 
    # Main event loop of Qt. This won't return until the program exits.
    app.exec_()
    sys.exit()
