#!/usr/bin/python
# encoding: utf-8
#
# Copyright (C) 2011 by Coolman & Swiss-MAD
#
# In case of reuse of this source code please do not remove this copyright.
#
#	This program is free software: you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation, either version 3 of the License, or
#	(at your option) any later version.
#
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#
#	For more information on the GNU General Public License see:
#	<http://www.gnu.org/licenses/>.
#
import math
import os
import random
import re

from collections import defaultdict
from time import time
from datetime import datetime
from threading import Thread
from skin import parseColor

from Components.config import *
from Components.GUIComponent import GUIComponent
from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaBlend
from Tools.LoadPixmap import LoadPixmap
from Tools.Directories import fileExists, resolveFilename, SCOPE_CURRENT_SKIN
from skin import parseColor, parseFont, parseSize
from enigma import eListboxPythonMultiContent, eListbox, gFont, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER, eServiceReference, eServiceCenter, ePythonMessagePump, loadPNG, getDesktop
from timer import TimerEntry

from . import _
from EMCFileCache import movieFileCache
from EMCMountPoints import mountPoints
from RecordingsControl import RecordingsControl, getRecording
from DelayedFunction import DelayedFunction
from EMCTasker import emcDebugOut
from VlcPluginInterface import VlcPluginInterfaceList, vlcSrv, vlcDir, vlcFil
from VlcPluginInterface import DEFAULT_VIDEO_PID, DEFAULT_AUDIO_PID, ENIGMA_SERVICE_ID
from operator import itemgetter
from CutListSupport import CutList
from MetaSupport import MetaList
from EitSupport import EitList
from PermanentSort import PermanentSort
from E2Bookmarks import E2Bookmarks
from EMCBookmarks import EMCBookmarks
from ServiceSupport import ServiceCenter
from ThreadQueue import ThreadQueue

try:
	from enigma import eMediaDatabase
	isDreamOS = True
except:
	isDreamOS = False

screen_height = getDesktop(0).size().height()

# Check if image is vti or dream, is needed for build entrys in MovieCenter with picons
try:
	from boxbranding import getImageDistro
	distro = getImageDistro()
	imgVti = 'vti' in distro.lower()
except:
	try:
		from enigma import BT_FIXRATIO
		imgVti = True
	except:
		imgVti = False
try:
	from Components.Renderer.Picon import getPiconName
	newPiconRenderer = True
except:
	newPiconRenderer = False

if imgVti:
	from enigma import BT_SCALE, BT_FIXRATIO as BT_KEEP_ASPECT_RATIO

if newPiconRenderer:
	try:
		from enigma import BT_SCALE, BT_KEEP_ASPECT_RATIO
	except ImportError as ie:
		newPiconRenderer = False
		BT_SCALE = None
		BT_KEEP_ASPECT_RATIO = None

global extAudio, extDvd, extVideo, extPlaylist, extList, extMedia, extBlu
global cmtDir, cmtUp, cmtTrash, cmtLRec, cmtVLC, cmtBME2, cmtBMEMC, virVLC, virAll, virToE, virToD
global vlcSrv, vlcDir, vlcFil
global plyDVB, plyM2TS, plyDVD, plyMP3, plyVLC, plyAll
global sidDVB, sidDVD, sidMP3

# Set definitions

# Media types
extAudio    = frozenset([".ac3", ".dts", ".flac", ".m4a", ".mp2", ".mp3", ".ogg", ".wav", ".wma", ".aac"])
extVideo    = frozenset([".ts", ".trp", ".avi", ".divx", ".f4v", ".flv", ".img", ".ifo", ".iso", ".m2ts", ".m4v", ".mkv", ".mov", ".mp4", ".mpeg", ".mpg", ".mts", ".vob", ".wmv", ".bdmv", ".asf", ".stream", ".webm"])
extPlaylist = frozenset([".m3u", ".e2pls"])#, ".pls"])
extMedia    = extAudio | extVideo | extPlaylist
extDir      = frozenset([""])
extList     = extMedia | extDir

# Additional file types
extTS       = frozenset([".ts", ".trp"])
extM2ts     = frozenset([".m2ts"])
#extDvd      = frozenset([".iso", ".img", ".ifo"])
extIfo      = frozenset([".ifo"])
extIso      = frozenset([".iso", ".img"])
extDvd      = extIfo | extIso
extVLC      = frozenset([vlcFil])
extBlu      = frozenset([".bdmv"])
# blue disk movie
# mimetype("video/x-bluray") ext (".bdmv")

# Player types
plyDVB      = extTS											# ServiceDVB
plyM2TS     = extM2ts											# ServiceM2TS
plyDVD      = extDvd											# ServiceDVD
plyMP3      = extMedia - plyDVB - plyM2TS - plyDVD - extBlu						# ServiceMP3 GStreamer
plyVideo    = extMedia - extAudio
plyVLC      = extVLC											# VLC Plugin
#plyBLU      = extBlu | extIso										# BludiscPlayer Plugin
plyAll      = plyDVB | plyM2TS | plyDVD | plyMP3 | plyVLC | extBlu


# Type definitions

# Service ID types for E2 service identification
sidDVB      = eServiceReference.idDVB									# eServiceFactoryDVB::id   enum { id = 0x1 };
sidDVD      = 4369 											# eServiceFactoryDVD::id   enum { id = 0x1111 };
sidMP3      = 4097											# eServiceFactoryMP3::id   enum { id = 0x1001 };
# For later purpose
sidM2TS     = 3 											# eServiceFactoryM2TS::id  enum { id = 0x3 };
#TODO
#sidXINE = 4112												# eServiceFactoryXine::id  enum { id = 0x1010 };
#additionalExtensions = "4098:m3u 4098:e2pls 4098:pls"

# Grouped service ids
sidsCuts = frozenset([sidDVB, sidDVD])

# Custom types: Used by EMC internally for sorting and type identification

cmtUp      = "0"
cmtTrash   = "1"
cmtLRec    = "2"
cmtBME2    = "BE2"
cmtBMEMC   = "BEMC"
cmtDir     = "D"
cmtVLC     = "V"

substitutelist = [("."," "), ("_"," "), ("-"," "), ("1080p",""), ("720p",""), ("x264",""), ("h264",""), ("1080i",""), ("AC3","")]

# Grouped custom types
virVLC     = frozenset([cmtVLC, vlcSrv, vlcDir])
virAll     = frozenset([cmtBME2, cmtBMEMC, cmtVLC, cmtLRec, cmtTrash, cmtUp, cmtDir, vlcSrv, vlcDir])
virToE     = frozenset([cmtBME2, cmtBMEMC, cmtVLC, cmtLRec, cmtTrash, cmtUp, vlcSrv, vlcDir])

if config.EMC.directories_ontop.value:
	virToD = virToE
else:
	virToD = virAll

#-------------------------------------------------
# func: getPosterPath( path )
#-------------------------------------------------
def getPosterPath(searchPath):
	ret = ""
	paths = []
	exts = [".jpg", ".png", "_md.jpg", "_md.png"]
	searchname = os.path.splitext(searchPath.rstrip('/.'))[0]
	foldercoverconfig = config.EMC.imdb.singlesearch_foldercoverpath.value

	if os.path.isfile(searchPath):
		paths.extend([searchname])									# /dir/mediafolder/mediafile.ext
		basedircover = os.path.dirname(searchname)							# /dir/mediafolder.ext
	else:
		basedircover = searchname									# /dir/mediafolder.ext

	# bluray structures
	if basedircover.lower().endswith("/bdmv"):
		basedircover = basedircover[:-5]
		if basedircover.lower().endswith("/brd"):
			basedircover = basedircover[:-4]
	elif basedircover.lower().endswith("/brd"):
		basedircover = basedircover[:-4]
	# dvd structures
	elif basedircover.lower().endswith("/video_ts"):
		basedircover = basedircover[:-9]
		if basedircover.lower().endswith("/dvd"):
			basedircover = basedircover[:-4]
	elif basedircover.lower().endswith("/dvd"):
		basedircover = basedircover[:-4]

	filedircover = basedircover + os.sep + os.path.basename(basedircover) 					# /dir/mediafolder/mediafolder.ext
	foldercover = basedircover + os.sep + 'folder'								# /dir/mediafolder/folder.ext

	if foldercoverconfig == '1':
		paths.extend([basedircover, foldercover, filedircover])
	elif foldercoverconfig == '2':
		paths.extend([foldercover, basedircover, filedircover])
	else:
		paths.extend([filedircover, foldercover, basedircover])

	for path in paths:
		for ext in exts:
			ret = path + ext
			if os.path.isfile(ret):
				break
			ret = ""
		if ret:
			break
	return ret

#-------------------------------------------------
# func: getNoPosterPath()
#-------------------------------------------------
def getNoPosterPath():
	if screen_height == 1440:
		if config.EMC.use_orig_skin.value:
			return "/usr/lib/enigma2/python/Plugins/Extensions/EnhancedMovieCenter/img_wqhd/no_poster.png"
		else:
			img = resolveFilename(SCOPE_CURRENT_SKIN, 'emc/no_poster.png')
			if fileExists(img):
				return img
			else:
				return "/usr/lib/enigma2/python/Plugins/Extensions/EnhancedMovieCenter/img_wqhd/no_poster.png"
	elif screen_height == 1080:
		if config.EMC.use_orig_skin.value:
			return "/usr/lib/enigma2/python/Plugins/Extensions/EnhancedMovieCenter/img_wqhd/no_poster.png"
		else:
			img = resolveFilename(SCOPE_CURRENT_SKIN, 'emc/no_poster.png')
			if fileExists(img):
				return img
			else:
				return "/usr/lib/enigma2/python/Plugins/Extensions/EnhancedMovieCenter/img_fhd/no_poster.png"
	else:
		if config.EMC.use_orig_skin.value:
			return "/usr/lib/enigma2/python/Plugins/Extensions/EnhancedMovieCenter/img/no_poster.png"
		else:
			img = resolveFilename(SCOPE_CURRENT_SKIN, 'emc/no_poster.png')
			if fileExists(img):
				return img
			else:
				return "/usr/lib/enigma2/python/Plugins/Extensions/EnhancedMovieCenter/img/no_poster.png"

#-------------------------------------------------
# func: readBasicCfgFile( file )
#
# Reads the lines of a file in a list. Empty lines
# or lines beginnig with '#' will be ignored.
#-------------------------------------------------
def readBasicCfgFile(file):
	data = []
	if not os.path.exists(file):
		return data
	f = None
	try:
		f = open(file, "r")
		lines = f.readlines()
		for line in lines:
			line = line.strip()
			if not line:					# no empty lines
				continue
			if line[0:1] == "#":				# no comment lines
				continue
			data.append( line )
	except Exception, e:
		emcDebugOut("[EMC] Exception in readBasicCfgFile: " + str(e))
	finally:
		if f is not None:
			f.close()
	return data

#-------------------------------------------------
# func: getPlayerService(path, name="", ext=None)
#
# Determine the service of a media file
#-------------------------------------------------
def getPlayerService(path, name="", ext=None):
	if ext in plyDVB:
		service = eServiceReference(sidDVB, 0, path)
	elif ext in plyMP3:
		service = eServiceReference(sidMP3, 0, path)
	elif ext in plyDVD:
		service = eServiceReference(sidDVD, 0, path)
		#QUESTION Is the special name handling really necessary
		if service:
			# Copied from dvd player
			if path.lower().endswith("/video_ts") or path.endswith("/"):
				names = service.toString().rsplit("/",3)
				if names[2].startswith("Disk ") or names[2].startswith("DVD "):
					#TEST name = str(names[1]) + " - " + str(names[2])
					name = names[1] + " - " + names[2]
				else:
					name = names[2]
	elif ext in plyM2TS:
		service = eServiceReference(sidM2TS, 0, path)
	else:
		path = path.replace(":","") # because of VLC player
		#service = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + path)
		service = eServiceReference(ENIGMA_SERVICE_ID, 0, path)
		print "[EMC] service valid=", service.valid()
		service.setData(0, DEFAULT_VIDEO_PID)
		service.setData(1, DEFAULT_AUDIO_PID)
	if name:
		service.setName(name)
	return service

def getMovieNameWithoutExt(moviename=""):
	if config.EMC.movie_show_format.value:
		for rem in extVideo:
			rem = rem.replace("."," ")
			if moviename.lower().endswith(rem):
				moviename = moviename[:-len(rem)]
				break
		for rem in extVideo:
			rem = rem.replace(".","")
			if moviename.lower().endswith("["+rem+"]"):
				moviename = moviename[:-len("["+rem+"]")].strip()
				break
	return moviename

def getMovieNameWithoutPhrases(moviename=""):
	# Remove phrases which are encapsulated in [*] or (*) from the movietitle
	moviename = re.sub(r'\[.*\]', "", moviename)
	moviename = re.sub(r'\(.*\)', "", moviename)
	moviename = re.sub(r' S\d\dE\d\d .*', "", moviename)
	for (phrase,sub) in substitutelist:
		moviename = moviename.replace(phrase,sub)
	return moviename

def getProgress(service, length=0, last=0, forceRecalc=False, cuts=None):
	# All calculations are done in seconds
	# The progress of a recording isn't correct, because we only get the actual length not the final
	cuts = None
	progress = 0
	#updlen = length
	if last <= 0:
		# Get last position from cut file
		if cuts is None:
			cuts = CutList( service.getPath() )
		last = cuts.getCutListLast()
	# Check for valid position
	if last > 0 or forceRecalc:
		# Valid position
		# Recalc the movie length to calculate the progress status
		if length <= 0:
			if service:
				esc = eServiceCenter.getInstance()
				info = esc and esc.info(service)
				length = info and info.getLength(service) or 0
			if length <= 0:
				if cuts is None:
					cuts = CutList( service.getPath() )
				length = cuts.getCutListLength()
				if length <= 0:
					# Set default file length if is not calculateable
					# 90 minutes = 90 * 60
					length = 5400
					# We only update the entry if we do not use the default value
				#	updlen = 0
				#else:
				#	updlen = length
			#else:
			#	updlen = length
		if length:
			progress = calculateProgress(last, length)
		else:
			# This should never happen, we always have our default length
			progress = 100
			#emcDebugOut("[MC] getProgress(): Last without any length")
	else:
		# No position implies progress is zero
		progress = 0
	return progress, length

def getRecordProgress(path):
	# The progress of all recordings is updated
	# - on show dialog
	# - on reload list / change directory / movie home
	# The progress of one recording is updated
	# - if it will be highlighted the list
	# Note: There is no auto update mechanism of the recording progress
	record = getRecording(path)
	if record:
		begin, end, service = record
		last = time() - begin
		length = end - begin
		return calculateProgress(last, length)
	else:
		return 0

def calculateProgress(last, length):
	progress = 0
	if length:
		# Adjust the watched movie length (98% of movie length)
		# else we will never see the 100%
		adjlength = float(length) / 100.0 * 98.0
		# Calculate progress and round up
		progress = int( math.ceil ( float(last) / float(adjlength) * 100.0 ) )
		# Normalize progress
		if progress < 0: progress = 0
		elif progress > 100: progress = 100
	return progress

def toggleProgressService(service, preparePlayback, forceProgress=-1, first=False):
	if service is None:
		return

	# Cut file handling
	path = service.getPath()

	# Only for compatibilty reasons
	# Should be removed anytime
	cuts  = path +".cuts"
	cutsr = path +".cutsr"
	if os.path.exists(cutsr) and not os.path.exists(cuts):
		# Rename file - to catch all old EMC revisions
		try:
			os.rename(cutsr, cuts)
		except Exception, e:
			emcDebugOut("[CUTS] Exception in toggleProgressService: " + str(e))
	# All calculations are done in seconds
	cuts = CutList( path )
	last = cuts.getCutListLast()
	#length = self.getLengthOfService(service)
	progress, length = getProgress(service, length=0, last=last, forceRecalc=True, cuts=cuts)

	if not preparePlayback:
		if first:
			if progress < 100: forceProgress = 50		# force next state 100
			else: forceProgress = 100 							# force next state 0
		if forceProgress > -1:
			progress = forceProgress

		if progress >= 100:
			# 100% -> 0
			# Don't care about preparePlayback, always reset to 0%
			# Save last marker
			cuts.toggleLastCutList(cuts.CUT_TOGGLE_START)
		elif progress <= 0:
			# 0% -> SAVEDLAST or length
			cuts.toggleLastCutList(cuts.CUT_TOGGLE_RESUME)
		else:
			# 1-99% -> length
			cuts.toggleLastCutList(cuts.CUT_TOGGLE_FINISHED)
	else:
		if progress >= 100 or config.EMC.movie_rewind_finished.value is True and progress >= int(config.EMC.movie_finished_percent.value):
			# 100% -> 0 or
			# Start playback and rewind is set and movie progress > finished -> 0
			# Don't save SavedMarker
			cuts.toggleLastCutList(cuts.CUT_TOGGLE_START_FOR_PLAY)
		else:
			# Delete SavedMarker
			cuts.toggleLastCutList(cuts.CUT_TOGGLE_FOR_PLAY)

	return progress

def dirInfo(folder, bsize=False):
	#TODO Improve performance
	count = 0
	size = 0
	structlist = ["video_ts", "bdmv"]
	if config.EMC.cfghide_enable.value:
		hideitemlist = readBasicCfgFile("/etc/enigma2/emc-hide.cfg") or []
	else:
		hideitemlist = []
	extCount = extList - extBlu - extIfo
	if os.path.exists(folder):
		#for m in os.listdir(path):
		for (path, dirs, files) in os.walk(folder):
			for dir in dirs:
				if dir.lower() in structlist:
					count += 1						# add dvd/blustructure movies
					dirs.remove(dir)			# structure's subtree won't be explored
			#count += len(dirs)					# don't count dirs
			for m in files:
				if os.path.splitext(m)[1].lower() in extList:
					count += 1
					if bsize:
						# Only retrieve the file size if it is requested,
						# because it costs a lot of time
						filename = os.path.join(path, m)
						if os.path.exists(filename):
							size += os.path.getsize(filename)
	if size:
		size /= (1024.0 * 1024.0 * 1024.0)
	if folder != cmtTrash:
		movieFileCache.addCountSizeToCache(folder, count, size)
	return count, size

def detectDVDStructure(checkPath):
	if not os.path.isdir(checkPath):
		return None
	elif not config.EMC.scan_linked.value and os.path.islink(checkPath):
		return None
	dvdpath = os.path.join(checkPath, "VIDEO_TS.IFO")
	if fileExists( dvdpath ):
		return dvdpath
	dvdpath = os.path.join(checkPath, "VIDEO_TS/VIDEO_TS.IFO")
	if fileExists( dvdpath ):
		return dvdpath
	dvdpath = os.path.join(checkPath, "DVD/VIDEO_TS/VIDEO_TS.IFO")
	if fileExists( dvdpath ):
		return dvdpath
	return None

def detectMOVStructure(checkPath):
	if not os.path.isdir(checkPath):
		return None
	elif not config.EMC.scan_linked.value and os.path.islink(checkPath):
		return None
	extMovie = extVideo - extBlu
	for ext in extMovie:
		movpath = os.path.join(checkPath, os.path.basename(checkPath)) + ext
		if fileExists( movpath ):
			return movpath
	return None

def detectBLUStructure(checkPath):
	if not os.path.isdir(checkPath):
		return None
	elif not config.EMC.scan_linked.value and os.path.islink(checkPath):
		return None
	blupath = os.path.join(checkPath, "BDMV/index.bdmv")
	if fileExists( blupath ):
		return blupath
	blupath = os.path.join(checkPath, "BRD/BDMV/index.bdmv")
	if fileExists( blupath ):
		return blupath
	return None

def detectBLUISO(checkPath):
	random.seed()
	mountdir = '/tmp/EMCISO' + str(random.getrandbits(16))
	dir, fileext = os.path.splitext(checkPath)
	if fileext =='.iso':
		if not os.path.exists(mountdir):
			os.system('mkdir ' + mountdir)
		else:
			os.system('umount -d -f ' + mountdir)
		os.system('mount -r "' + checkPath + '" ' + mountdir)
		if detectBLUStructure(mountdir):
			os.system('umount -d -f ' + mountdir)
			os.system('rmdir ' + mountdir)
			return True
		os.system('umount -d -f ' + mountdir)
		os.system('rmdir ' + mountdir)
	return False

# muss drinnen bleiben sonst crashed es bei foreColorSelected
def MultiContentEntryProgress(pos = (0, 0), size = (0, 0), percent = None, borderWidth = None, foreColor = None, foreColorSelected = None, backColor = None, backColorSelected = None):
	return (eListboxPythonMultiContent.TYPE_PROGRESS, pos[0], pos[1], size[0], size[1], percent, borderWidth, foreColor, foreColorSelected, backColor, backColorSelected)

THREAD_WORKING = 1
THREAD_FINISHED = 2

class CountSizeWorker(Thread):
	def __init__(self):
		Thread.__init__(self)
		self.__running = False
		self.__messages = ThreadQueue()
		self.__messagePump = ePythonMessagePump()
		self.__list = ThreadQueue()

	def __getMessagePump(self):
		return self.__messagePump
	MessagePump = property(__getMessagePump)

	def __getMessageQueue(self):
		return self.__messages
	Message = property(__getMessageQueue)

	def __getRunning(self):
		return self.__running
	isRunning = property(__getRunning)

	def isListEmpty(self):
		return self.__list.empty()

	def getListLength(self):
		return len(self.__list)

	def Cancel(self):
		self.__running = False

	def add(self, item):
		self.__list.push(item)
		if not self.__running and not self._Thread__started.is_set():
			self.__running = True
#			print'[EMC] CountSizeWorker Start'
			self.start()

	def run(self):
		while not self.__list.empty():
			if not self.__running: break

			item = self.__list.pop()
#			print'[EMC] CountSizeWorker processing: ', item
			result = None

			try:
				result = dirInfo(item, bsize=True)
			except Exception, e:
				print('[EMC] CountSizeWorker result exception:', str(e))

				# Exception finish job with error
				result = str(e)

			if result:
				if self.__running:
					self.__messages.push((2, result))
			else:
				self.__messages.push((1, result))

		self.__messagePump.send(0)
		self.__running = False
		Thread.__init__(self)

countsizeworker = CountSizeWorker()

moviecenterdata = None

class MovieCenterData(VlcPluginInterfaceList, PermanentSort, E2Bookmarks, EMCBookmarks):

	def __init__(self):
		VlcPluginInterfaceList.__init__(self)
		PermanentSort.__init__(self)

		self.currentPath = config.EMC.movie_homepath.value

		self.list = []
		from Plugins.Extensions.EnhancedMovieCenter.plugin import sort_modes
		self.actualSort = sort_modes.get( config.EMC.moviecenter_sort.value )[1]
		self.returnSort = None
		self.selectionList = None

		self.recControl = RecordingsControl(self.recStateChange)

		self.currentSelectionCount = 0
		self.highlightsMov = []
		self.highlightsDel = []
		self.highlightsCpy = []
		self.hideitemlist = readBasicCfgFile("/etc/enigma2/emc-hide.cfg") or []
		self.nostructscan = readBasicCfgFile("/etc/enigma2/emc-noscan.cfg") or []
		self.topdirlist = readBasicCfgFile("/etc/enigma2/emc-topdir.cfg") or []

		config.EMC.cfghide_enable.addNotifier(self.changedCfgHideEnable, initial_call = False, immediate_feedback = True)

	def getList(self):
		return self.list

	def getListEntry(self, index):
		return self.list[index]

	def getTypeOfIndex(self, index):
		return self.list[index][7]

	def getSorting(self):
		# Return the actual sorting mode
		return self.actualSort

	def resetSorting(self):
		from Plugins.Extensions.EnhancedMovieCenter.plugin import sort_modes
		self.actualSort = sort_modes.get( config.EMC.moviecenter_sort.value )[1]

	def isEqualPermanentSort(self):
		isperm = False
		perm = self.getPermanentSort(self.currentPath)
		if perm is not None:
			isperm = self.actualSort == perm
		# Return if the current sorting mode is set as / equal the permanent one
		return isperm

	def doListSort(self, sortlist):
		# This will find all unsortable items
		# But is not as fast as the second implementation
		# If [2] = date = None then it is a directory or special folder entry
		# tmplist = [i for i in sortlist if i[7] in virAll]
		if config.EMC.directories_ontop.value:
			virToD = virToE
		else:
			virToD = virAll
		if config.EMC.cfgtopdir_enable.value:
			topdirlist = self.topdirlist
			tmplist = [i for i in sortlist if i[7] in virToD or i[3] in topdirlist]
		else:
			tmplist = [i for i in sortlist if i[7] in virToD]
		# Extract list items to be sorted
		sortlist = [i for i in sortlist if i not in tmplist]
		# Always sort via extension and sorttitle and never reversed
		tmplist.sort( key=lambda x: (x[7],x[1]) )

		# Sort list, same algorithm for both implementations
		# Using itemgetter is slightly faster but not as flexible
		#  from operator import itemgetter: (key=itemgetter(x))
		#  Then the list has to be flat
		#   no sub tuples are possible
		#   no negotiation is possible
		# Faster if separate? sortlist.reverse()
		# Tuple: (service, sorttitle, date, title, path, selectionnumber, length, ext, cutnr, sorteventtitle, eventtitle, piconpath, sortyear, sortmonth, sortday, sorthour, sortmin)
		mode, order = self.actualSort
		if mode is None:
			mode = self.actualSort[0]
		if order is None:
			order = self.actualSort[1]

		movie_metaload = config.EMC.movie_metaload.value
		if mode == "D":	# Date sort
			if not order:
				if movie_metaload:
					sortlist.sort( key=lambda x: (-x[12],-x[13],-x[14],-x[15],-x[16],x[1],x[9],-x[8]) )
				else:
					sortlist.sort( key=lambda x: (-x[12],-x[13],-x[14],-x[15],-x[16],x[1],-x[8]) )
			else:
				if movie_metaload:
					sortlist.sort( key=lambda x: (x[12],x[13],x[14],x[15],x[16], x[1], x[9], x[8]), reverse=True )
				else:
					sortlist.sort( key=lambda x: (x[12],x[13],x[14],x[15],x[16], x[1], x[8]), reverse=True )

		elif mode == "A":	# Alpha sort
			if not order:
				sortlist.sort( key=lambda x: (x[1],x[12],x[13],x[14],x[15],x[16],x[8]) )
			else:
				sortlist.sort( key=lambda x: (x[1],-x[12],-x[13],-x[14],-x[15],-x[16],-x[8]) )

		elif mode == "ADN":	# Alpha sort with new date, newest first
			if not order:
				sortlist.sort( key=lambda x: (x[1],-x[12],-x[13],-x[14],-x[15],-x[16],x[8]) )
			else:
				sortlist.sort( key=lambda x: (x[1],x[12],x[13],x[14],x[15],x[16],-x[8]) )

		elif mode == "AM":	# Alpha sort with meta
			if not order:
				sortlist.sort( key=lambda x: (x[1],x[9],x[12],x[13],x[14],x[15],x[16],x[8]) )
			else:
				sortlist.sort( key=lambda x: (x[1],x[9],-x[12],-x[13],-x[14],-x[15],-x[16],-x[8]) )

		elif mode == "AMDN":	# Alpha sort with meta and new date, newest first
			if not order:
				sortlist.sort( key=lambda x: (x[1],x[9],-x[12],-x[13],-x[14],-x[15],-x[16],x[8]) )
			else:
				sortlist.sort( key=lambda x: (x[1],x[9],x[12],x[13],x[14],x[15],x[16],-x[8]) )

		elif mode == "P":	# Progress
			if not order:
				sortlist.sort( key=lambda x: ( getProgress(x[0], x[6]) ) ) #,x[2],x[8]) )
			else:
				sortlist.sort( key=lambda x: ( getProgress(x[0], x[6]) ) ) # ,x[2],-x[8]) )

		# Combine lists
		if order:
			#TODO TEST later with green button solution
			sortlist.reverse()
		#	tmplist += sortlist
		#	return tmplist.reverse()
		#else:
		return tmplist + sortlist

	def updateLength(self, service, length):
		# Update entry in list... so next time we don't need to recalc
		idx = self.getIndexOfService(service)
		if idx >= 0:
			x = self.list[idx]
			if x[6] != length:
				l = list(x)
				l[6] = length
				self.list[idx] = tuple(l)

	def serviceBusy(self, service):
		return service in self.highlightsMov or service in self.highlightsDel or service in self.highlightsCpy

	def serviceMoving(self, service):
		return service and service in self.highlightsMov

	def serviceDeleting(self, service):
		return service and service in self.highlightsDel

	def serviceCopying(self, service):
		return service and service in self.highlightsCpy

	def __len__(self):
		return len(self.list)

	def resetSelection(self):
		self.selectionList = None
		self.currentSelectionCount = 0

	def getFilePathOfService(self, service):
		if service:
			for entry in self.list:
				if entry[0] == service:
					return entry[4]
		return ""

	def getNameOfService(self, service):
		if service:
			for entry in self.list:
				if entry[0] == service:
					return entry[3]
		return ""

	def getLengthOfService(self, service):
		if service:
			for entry in self.list:
				if entry[0] == service:
					return entry[6]
		return 0

	def getIndexOfService(self, service):
		if service:
			idx = 0
			for entry in self.list:
				if entry[0] == service:
					return idx
				idx += 1
		return -1

	def getServiceOfIndex(self, index):
		return self.list[index] and self.list[index][0]

	def createDirListRecursive(self, path, useCache = True):
		dirstack, subdirlist, subfilelist, filelist = [], [], [], []

		dappend = dirstack.append
		fextend = filelist.extend
		pathreal = os.path.realpath
		pathislink = os.path.islink
		pathsplitext = os.path.splitext

		# walk through entire tree below current path. Might take a bit long on huge disks...
		dirstack.append( path )

		# Search files through all given paths
		for directory in dirstack:

			# Avoid trashcan subdirectories
			if directory.find( config.EMC.movie_trashcan_path.value ) == -1:

				# Get entries
				subdirlist, subfilelist = self.createDirList(directory, useCache)

				# Found new directories to search within, use only their path
				for d, name, ext in subdirlist:
					# Resolve symbolic links and get the real path
					d = pathreal( d )

					# Avoid duplicate directories and ignore links
					if d not in dirstack and not pathislink( d ):
						dappend( d )

				# Store the media files
				fextend( subfilelist )

		del dappend
		del fextend
		del pathreal
		del pathislink
		del pathsplitext
		# We don't want any folders
		return [], filelist

	def __createDirList(self, path):
		subdirlist, filelist = [], []
		dvdStruct = None
		pathname, ext = "", ""

		# Improve performance and avoid dots
		movie_trashpath = config.EMC.movie_trashcan_enable.value and os.path.realpath(config.EMC.movie_trashcan_path.value)
		check_dvdstruct = config.EMC.check_dvdstruct.value \
							and not (config.EMC.cfgscan_suppress.value and path in self.nostructscan)
		check_moviestruct = config.EMC.check_moviestruct.value \
							and not (config.EMC.cfgscan_suppress.value and path in self.nostructscan)
		check_blustruct = config.EMC.check_blustruct.value \
							and not (config.EMC.cfgscan_suppress.value and path in self.nostructscan)

		hideitemlist = config.EMC.cfghide_enable.value and self.hideitemlist

		localExtList = extList - extBlu - extDir

		dappend = subdirlist.append
		fappend = filelist.append
		splitext = os.path.splitext
		pathjoin = os.path.join
		OSErrorMessage = _("OSError - please reload list (EMC menu)")

		if os.path.exists(path):

			# Get directory listing
			walk_dirs = []
			walk_files = []
			try:
				walk_listdir = os.listdir(path)
			except OSError:
				walk_listdir = [OSErrorMessage]
			for walk_name in walk_listdir:
				if movieFileCache.isDir(os.path.join(path, walk_name)):
					walk_dirs.append(walk_name)
				else:
					walk_files.append(walk_name)
			for root, dirs, files in [(path,walk_dirs,walk_files)]:

				for file in files:

					# This will decrease the function execution time massively
					ext = splitext(file)[1].lower()

					if ext not in localExtList:
						continue

					pathname = pathjoin(path, file)

					# Filter dead links
					if movieFileCache.isFile(pathname) or (file == OSErrorMessage):

						# Symlink media file
						if movieFileCache.isLink(pathname) and not config.EMC.symlinks_show.value:
							continue

						# Media file found
						fappend( (pathname, file, ext) )

				for dir in dirs:

					pathname = pathjoin(path, dir)

					# Filter dead links
					if movieFileCache.isDir(pathname):
						if check_dvdstruct:
							dvdStruct = detectDVDStructure(pathname)
							if dvdStruct:
								# DVD Structure found
								pathname = os.path.dirname(dvdStruct)
								ext = splitext(dvdStruct)[1].lower()
								fappend( (pathname, dir, ext) )
								continue
						if check_moviestruct:
							movStruct = detectMOVStructure(pathname)
							if movStruct:
								# Movie Structure found
								ext = splitext(movStruct)[1].lower()
								fappend( (movStruct, dir, ext) )
								continue
						if check_blustruct:
							bluStruct = detectBLUStructure(pathname)
							if bluStruct:
								# Bluray Structure found
								pathname = os.path.dirname(bluStruct)
								ext = splitext(bluStruct)[1].lower()
								fappend( (pathname, dir, ext) )
								continue
						if config.EMC.directories_show.value:
							if not movie_trashpath or movieFileCache.realpath(pathname).find( movie_trashpath ) == -1:
								# Symlink folder found
								if movieFileCache.isLink(pathname) and not config.EMC.symlinks_show.value:
									continue
								# Folder found
								dappend( (pathname, dir, cmtDir) )
				# We only want the topdir
				break

		del dappend
		del fappend
		del splitext
		del pathjoin
		return subdirlist, filelist

	def reloadDirList(self, path):
		return self.createDirList(path, False)

	def createDirList(self, path, useCache = True):
		subdirlist, filelist = [], []
		if useCache and movieFileCache.IsPathInCache(path):
			subdirlist, filelist = movieFileCache.getCacheForPath(path)
		else:
			subdirlist, filelist = self.__createDirList(path)
			movieFileCache.addPathToCache(path, subdirlist, filelist, self)
		return subdirlist, filelist

	def createLatestRecordingsList(self):
		# Make currentPath more flexible
		#MAYBE: What about using current folder for latest recording lookup?
		dirstack, subdirlist, filelist, subfilelist, newfilelist = [], [], [], [], []

		dappend = dirstack.append
		fextend = filelist.extend
		nfextend = newfilelist.extend
		pathreal = os.path.realpath
		pathislink = os.path.islink
		pathsplitext = os.path.splitext

		# walk through entire tree below movie home. Might take a bit long on huge disks...
		# think about breaking at 2nd level,
		# but include folders used in timers, auto timers and bookmarks
		dirstack.append( config.EMC.movie_homepath.value )

		# Search files through all given paths
		for directory in dirstack:

			# first we check entrys in "emc-noscan.cfg",
			# to load the list faster and dont wakeup any devices
			if not ((config.EMC.latest_recordings_noscan.value or config.EMC.dir_info_usenoscan.value) and self.checkNoScanPath(directory)):

				# Avoid trashcan subdirectories
				if directory.find( config.EMC.movie_trashcan_path.value ) == -1:

					# Get entries
					subdirlist, subfilelist = self.createDirList(directory, False)

					# Found new directories to search within, use only their path
					for d, name, ext in subdirlist:
						# Resolve symbolic links and get the real path
						d = pathreal( d )

						# Avoid duplicate directories and ignore links
						if d not in dirstack and not pathislink( d ):
							dappend( d )

					# Store the media files
					fextend( [ (p,f,e) for p,f,e in subfilelist if e in extTS ] )

		val = int(config.EMC.latest_recordings_limit.value)
		if val != -1:
			if imgVti:			# is needed for vti, "val" is 1-365 in days
				val = val * 86400
			for path, name, ext in filelist:
				fdate = self.checkDate(path)
				nowDate = time()         # time from now in seconds, 86400 is one day
				if fdate >= nowDate - val:
					nfextend( [ (path, name, ext) ] )

		del dappend
		del fextend
		del nfextend
		del pathreal
		del pathislink
		del pathsplitext

		# Sorting is done through our default sorting algorithm
		if val != -1:
			return newfilelist
		else:
			return filelist

	def checkNoScanPath(self, path):
		check = False
		device = mountPoints.getMountPointDeviceCached(path)
		for line in self.nostructscan:
			if (line in path) or (line in device):
				check = True
				break
		return check

	def checkDate(self, path, dirDate=False):
		date = 0
		year, month, day, hour, min = "", "", "", "", ""
		try:
			if path and os.path.exists(path):
				getdate = os.stat(path)
				if dirDate:
					from time import strftime, localtime
					year = strftime('%Y', localtime(getdate[8]))
					month = strftime('%m', localtime(getdate[8]))
					day = strftime('%d', localtime(getdate[8]))
					hour = strftime('%H', localtime(getdate[8]))
					min = strftime('%M', localtime(getdate[8]))
				else:
					date = getdate[8]
		except Exception, e:
			emcDebugOut("[EMC] Exception in checkDate: " + str(e))
		if dirDate:
			return year, month, day, hour, min
		else:
			return date

	def createFileInfo(self, pathname):
		# Create info for new record
		p = os.path.basename(pathname)
		ext = os.path.splitext(p)[1].lower()
		return [ (pathname, p, ext) ]

	def createCustomList(self, currentPath, trashcan=True, extend=True):
		customlist = []
		path, name = "", ""
		append = customlist.append
		pathjoin = os.path.join
		pathreal = os.path.realpath

		currentPath = pathreal(currentPath)

		if currentPath != "" and currentPath != pathreal(config.EMC.movie_pathlimit.value):
			append( (	pathjoin(currentPath, ".."),
								"..",
								cmtUp) )

		if extend:
			# Insert these entries always at last
			if currentPath == pathreal(config.EMC.movie_homepath.value):
				if trashcan and config.EMC.movie_trashcan_enable.value and config.EMC.movie_trashcan_show.value:
					append( (	config.EMC.movie_trashcan_path.value,
										_(os.path.basename(config.EMC.movie_trashcan_path.value)) or _("trashcan"),
										cmtTrash) )

				if config.EMC.latest_recordings.value:
					append( (	pathjoin(currentPath, "Latest Recordings"),
										_("Latest Recordings"),
										cmtLRec) )

				if config.EMC.vlc.value and os.path.exists("/usr/lib/enigma2/python/Plugins/Extensions/VlcPlayer"):
					append( (	pathjoin(currentPath, "VLC servers"),
										"VLC servers",
										cmtVLC) )

				if config.EMC.bookmarks.value == "Both" or config.EMC.bookmarks.value == "E2":
					bookmarks = self.getE2Bookmarks()
					if bookmarks:
						for bookmark in bookmarks:
							append( (	bookmark,
												os.path.basename(bookmark) or bookmark,
												cmtBME2 ) )

				if config.EMC.bookmarks.value == "Both" or config.EMC.bookmarks.value == "EMC":
					bookmarks = self.getEMCBookmarks()
					if bookmarks:
						for bookmark in bookmarks:
							append( (	bookmark,
												os.path.basename(bookmark),
												cmtBMEMC ) )

		del append
		del pathjoin
		return customlist

	def reloadInternal(self, currentPath, simulate=False, recursive=False):
		#TODO add parameter reset list sort
		emcDebugOut("[EMC] LOAD PATH: " + str(currentPath))
		customlist, subdirlist, filelist, tmplist = [], [], [], []
		resetlist = True
		nextSort = None

		if config.EMC.remote_recordings.value:
			# get a list of current remote recordings
			self.recControl.recFilesRead()

		# Create listings
		if movieFileCache.isDir(currentPath):
			# Found directory

			# Read subdirectories and filenames
			if not recursive:
				subdirlist, filelist = self.createDirList(currentPath, True)
			else:
				subdirlist, filelist = self.createDirListRecursive(currentPath, True)

			if not simulate:
				customlist = self.createCustomList(currentPath)

		elif movieFileCache.isFile(currentPath):
			# Found file

			filelist = self.createFileInfo(currentPath)
			resetlist = False
			currentPath = None

		else:
			# Found virtual directory

			if currentPath.endswith("VLC servers"):
				emcDebugOut("[EMC] VLC Server")
				subdirlist = self.createVlcServerList(currentPath)
				customlist = self.createCustomList(currentPath, extend=False)

			elif currentPath.find("VLC servers")>-1:
				emcDebugOut("[EMC] VLC Files")
				subdirlist, filelist = self.createVlcFileList(currentPath)

			elif currentPath.endswith("Latest Recordings"):
				emcDebugOut("[EMC] Latest Recordings")
				filelist = self.createLatestRecordingsList()
				customlist = self.createCustomList(currentPath, extend=False)
				# Set date descending as next sort mode
				nextSort = ("D",False)

			else:
				# No changes done
				return False

		# Local variables
		movie_hide_mov = config.EMC.movie_hide_mov.value
		movie_hide_del = config.EMC.movie_hide_del.value
		movie_show_cutnr = config.EMC.movie_show_cutnr.value
		movie_show_format = config.EMC.movie_show_format.value
		title_replace_special_chars = config.EMC.replace_specialchars.value

		# Avoid dots
		append = tmplist.append
		pathexists = os.path.exists
		pathsplitext = os.path.splitext
		hideitemlist = config.EMC.cfghide_enable.value and self.hideitemlist

		service = None
		title, sorttitle = "", ""
		date = datetime.fromtimestamp(0)
		cutnr = ""
		metastring, eitstring = "", ""
		sorteventtitle, eventtitle = "", ""
		piconpath = ""
		sortyear, sortmonth, sortday, sorthour, sortmin = "", "", "", "", ""

		# Add custom entries and sub directories to the list
		customlist += subdirlist
		if customlist is not None:
			for path, filename, ext in customlist:
				if hideitemlist:
					if filename in hideitemlist or (filename[0:1] == "." and filename[0:2] != ".." and ".*" in hideitemlist):
						continue
				sorttitle = ""
				title = filename

				# Replace special chars with spaces
				if title_replace_special_chars:
					title = title.replace("_"," ")
					title = title.replace("."," ")

				# Very bad but there can be both encodings
				# E2 recordings are always in utf8
				# User files can be in cp1252
				#TODO Is there no other way?
				try:
					title.decode('utf-8')
				except UnicodeDecodeError:
					try:
						title = title.decode("cp1252").encode("utf-8")
					except UnicodeDecodeError:
						title = title.decode("iso-8859-1").encode("utf-8")

				service = getPlayerService(path, title)

				sorttitle = title.lower()

				if date is None:
					date = datetime.fromtimestamp(0)

				# we get now the real date for folders
				# so we can sort this, if they are in the list, not at top
				if path.endswith("Latest Recordings") or path.endswith("VLC servers"):
					pass
				else:
					if title not in self.topdirlist:
						newDate = None
						if config.EMC.files_cache.value:
							newDate = movieFileCache.getDateInfoFromCacheForPath(path)
						if newDate is None:
							newDate = newDate or self.checkDate(path, True)
						sortyear = newDate[0]
						sortmonth = newDate[1]
						sortday = newDate[2]
						sorthour = newDate[3]
						sortmin = newDate[4]
				append((service, sorttitle, date, title, path, 0, 0, ext, 0, sorteventtitle, eventtitle, piconpath, int(sortyear or 0), int(sortmonth or 0), int(sortday or 0), int(sorthour or 0), int(sortmin or 0)))

		# Add file entries to the list
		if filelist is not None:
			#TODO extract the function to retrieve the correct title
			movie_metaload = config.EMC.movie_metaload.value
			movie_eitload = config.EMC.movie_eitload.value
			for path, filename, ext in filelist:
				# Filename, Title, Date, Sortingkeys handling
				# First we extract as much as possible informations from the filename
				service = None
				title, date, cutnr = "", "", ""
				length = 0
				#TODO metalength, eitlength and priority handling
				metastring, eitstring = "", ""
				#metadate, eitdate = "", ""
				sorttitle = ""
				#sortdate = ""
				#sortkeyalpha, sortkeydate = "", ""
				sorteventtitle = ""
				eventtitle = ""
				piconpath = ""
				sortyear, sortmonth, sortday, sorthour, sortmin = "", "", "", "", ""
				isExtHDDSleeping = config.EMC.limit_fileops_noscan.value and mountPoints.isExtHDDSleeping(str(currentPath),self)

				# Remove extension
				if not ext:
					# Avoid splitext it is very slow compared to a slice
					title, ext = pathsplitext(filename)
				else:
					#TODO Should not be necessary
					# If there is an ext filename is already the shortname without the extension
					#title = filename[:-len(ext)]
					title = pathsplitext(filename)[0]

				# Get cut number
				if title[-4:-3] == "_" and title[-3:].isdigit():
					cutnr = title[-3:]
					title = title[:-4]

				# Replace special chars with spaces
				if title_replace_special_chars:
					title = title.replace("_"," ")
					title = title.replace("."," ")

				# Derived from RecordTimer
				# This is everywhere so test it first
				if title[0:8].isdigit():
					if not title[8:9].isdigit() and title[9:13].isdigit():
						# Default: filename = YYYYMMDD TIME - service_name
						date = title[0:13]									# "YYYYMMDD TIME - " -> "YYYYMMDD TIME"
						title = title[16:]									# skips "YYYYMMDD TIME - "

						# Standard: filename = YYYYMMDD TIME - service_name - name
						# Long Composition: filename = YYYYMMDD TIME - service_name - name - description
						# Standard: filename = YYYYMMDD TIME - service_name - name
						# Skip service_name, extract name
						split = title.find(" - ")
						if split > 0: title = title[3+split:]

					elif title[8:11] == " - ":
						# Short Composition: filename = YYYYMMDD - name
						date = title[0:8] + " 2000"			# "YYYYMMDD" + " " + DUMMY_TIME
						title = title[11:]									# skips "YYYYMMDD - "

					if date:
						dtime = int(date[9:13] or 2000)
						date = int(date[0:8] or 0)
						try:
							date = datetime(date/10000, date%10000/100, date%100, dtime/100, dtime%100)
						except ValueError, e:
							date = datetime.fromtimestamp(0)

				# If the user wants it, extract information from the meta and eit files
				# But it is very slow

				if movie_metaload and not isExtHDDSleeping:
					# read title from META
					meta = MetaList(path)
					if meta:
						metastring = meta.getMetaName()
						if config.EMC.movie_metaload_all.value == "title":
							eventtitle = meta.getMetaTitle()
						if not eventtitle and config.EMC.movie_metaload_all.value == "everything":
							eventtitle = meta.getMetaDescription()
						if not date:
							date = meta.getMetaDate()
						# Improve performance and avoid calculation of movie length
						length = meta.getMetaLength()

				if not metastring and movie_eitload and not isExtHDDSleeping:
						# read title from EIT
						eit = EitList(path)
						if eit:
							eitstring = eit.getEitName()
							if not date:
								date = eit.getEitDate()
							if not length:
								length = eit.getEitLengthInSeconds()
				# get piconpath
				if config.EMC.movie_picons.value and not isExtHDDSleeping:
					meta = MetaList(path)
					metaref = meta.getMetaServiceReference()
					if config.EMC.movie_picons_path_own.value:
						pos = metaref.rfind(':')
						if pos != -1:
							metaref = metaref[:pos].rstrip(':').replace(':', '_')
					# now we need to check if picon-file exists
					if newPiconRenderer:
						if config.EMC.movie_picons_path_own.value:
							picon = config.EMC.movie_picons_path.value + "/" + metaref + '.png'
						else:
							picon = getPiconName(metaref)
					else:
						picon = config.EMC.movie_picons_path.value + "/" + metaref + '.png'
					if fileExists(picon):
						piconpath = picon

				# Priority and fallback handling

				# Set title priority here
				# Fallback is the filename
				title = metastring or eitstring or title or filename

				# Very bad but there can be both encodings
				# E2 recordings are always in utf8
				# User files can be in cp1252
				#TODO Is there no other way?
				try:
					title.decode('utf-8')
				except UnicodeDecodeError:
					try:
						title = title.decode("cp1252").encode("utf-8")
					except UnicodeDecodeError:
						title = title.decode("iso-8859-1").encode("utf-8")

				# Set date priority here
				# Fallback get date from filesystem, but it is very slow
				if config.EMC.files_cache.value and not date:
					date = movieFileCache.getDateInfoFromCacheForPath(path)
					if date is not None:
						date = datetime.fromtimestamp(date)
				if not date:
					date = pathexists(path) and datetime.fromtimestamp( self.checkDate(path) ) or None
				if date is None:
					date = datetime.fromtimestamp(0)

				# Create sortkeys
				#if not sortdate: sortdate = date and date.strftime( "%Y%m%d %H%M" ) or ""
				sorttitle = title.lower()
				sorteventtitle = eventtitle.lower()
				#sortkeyalpha = sorttitle + ("%03d") % int(cutnr or 0) + sortdate
				#sortkeydate = sortdate + sorttitle + ("%03d") % ( 999 - int(cutnr or 0) )

				# combine information regarding the emc config
				if movie_show_cutnr:
					if not cutnr == "":
						title += " "+cutnr

				if movie_show_format:
					title += " ["+ext[1:] + "]"

				# Get player service and set formatted title
				service = getPlayerService(path, title, ext)

				# Bad workaround to get all information into our Service Source
				service.date = date
				# get a better date to sort with other values
				try:
					sdate = str(date)
					sdate = sdate.split(' ', -1)
					if len(sdate) >= 1:
						stime = sdate[1].split(':', -1)
						sorthour = stime[0]
						sortmin = stime[1]
					sdate = sdate[0].split('-', -1)
					sortyear = sdate[0]
					sortmonth = sdate[1]
					sortday = sdate[2]
				except Exception, e:
					emcDebugOut("[EMC] Exception in get new date-sort values: " + str(e) + "\n" + "trying with this date: " + str(date))

				# Check config settings
				#TODO These checks should be done earlier but there we don't have the service yet
				if (movie_hide_mov and self.serviceMoving(service)) \
					or (movie_hide_del and self.serviceDeleting(service)):
					continue
				append((service, sorttitle, date, title, path, 0, length, ext, int(cutnr or 0), sorteventtitle, eventtitle, piconpath, int(sortyear or 0), int(sortmonth or 0), int(sortday or 0), int(sorthour or 0), int(sortmin or 0)))

		# Cleanup before continue
		del append
		del pathexists
		del pathsplitext

		if not simulate:
			# If we are here, there is no way back
			self.currentSelectionCount = 0
			self.selectionList = None

			if currentPath is not None:
				self.currentPath = currentPath

				# Lookup for a permanent sorting mode
				perm = self.getPermanentSort(currentPath)
				if perm:
					# Backup the actual sorting mode
					if self.returnSort is None:
						self.returnSort = self.actualSort
					self.actualSort = perm

				elif self.returnSort:
					# Restore sorting mode
					self.actualSort = self.returnSort
					self.returnSort = None

				if nextSort:
					# Backup the actual sorting mode
					if self.returnSort is None:
						self.returnSort = self.actualSort
					# Set new sorting mode
					self.actualSort = nextSort

			if resetlist:
				self.list = []
			else:
				tmplist = self.list + tmplist

			self.list = self.doListSort( tmplist )
			return self.list

		else:
			# Simulate only
			return self.doListSort( tmplist )

	def globalReload(self, arg):
		try:
			global moviecenter
			if moviecenter:
				moviecenter.reload( arg )
		except: pass

	def globalRefresh(self):
		try:
			global moviecenter
			if moviecenter:
				moviecenter.refreshList()
		except: pass

	def recStateChange(self, timer):
		if timer:
			path = os.path.dirname(timer.Filename)
			if os.path.realpath(path) == os.path.realpath(self.currentPath):
				# EMC shows the directory which contains the recording
				if not isDreamOS:
					filename = timer.Filename + ".ts"
				else:
					filename = timer.Filename
				if timer.state == TimerEntry.StateRunning:
					if not self.list:
						# Empty list it will be better to reload it complete
						# Maybe EMC was never started before
						emcDebugOut("[MC] Timer started - full reload")
						DelayedFunction(500, self.globalReload, self.currentPath)
					else:
						# We have to add the new recording
						emcDebugOut("[MC] Timer started - add recording")
						# Timer filname is without extension
						DelayedFunction(500, self.globalReload, filename)
				elif timer.state == TimerEntry.StateEnded:
					#MAYBE Just refresh the ended record
					# But it is fast enough
					emcDebugOut("[MC] Timer ended")
					DelayedFunction(500, self.globalRefresh)
					# [Cutlist.Workaround] Initiate the Merge
					DelayedFunction(500, self.mergeCutListAfterRecording, filename)

	def changedCfgHideEnable(self, addNotifierDummy=None):
		config.EMC.needsreload.value = True

	def mergeCutListAfterRecording(self, path):
		emcDebugOut("[Cutlist.Workaround] MovieCenter.mergeCutListAfterRecording: " + str(path))
		cuts = CutList( path )
		cuts.updateFromCuesheet()

	def getNextService(self, service):
		#IDEA: Optionally loop over all
		#TODO calculate the correct title
		idx = self.getIndexOfService(service)
		if self.list[idx][7] in extMedia:
			# Cursor marks a movie
			length = len(self.list)
			for i in xrange(length):
				entry = self.list[ (i+idx)%length ]
				if entry and entry[7] in plyAll:
					# Entry is no directory
					service = entry[0]
					if not self.serviceBusy(service):
						yield service
		elif self.list[idx][7] == cmtDir:
			# Cursor marks a directory
			#IDEA: Optionally play also the following movielist items (folders and movies)
			path = self.list[idx][4]
			# Don't play movies from the trash folder or ".."
			if os.path.realpath(path) != os.path.realpath(config.EMC.movie_trashcan_path.value) and path != "..":
				#TODO Reuse the reload and createdirlist function
					# Then the files are sorted and played in their correct order
					# So we don't have the whole dir and file recognition handling twice
					# Simulate reload:	tmplist = self.reload(path, True)
				for root, dirs, files in os.walk(path): #,False):
					if dirs:
						for dir in dirs:
							pathname = os.path.join(root, dir)
							dvdStruct = detectDVDStructure( pathname )
							if dvdStruct:
								pathname = os.path.dirname(dvdStruct)
								ext = os.path.splitext(dvdStruct)[1].lower()
								service = getPlayerService(pathname, dir, ext)
								if not self.serviceBusy(service):
									yield service
					if files:
						for name in files:
							ext = os.path.splitext(name)[1].lower()
							if ext in extMedia:
								pathname = os.path.join(root, name)
								#TODO get formatted Name
								service = getPlayerService(pathname, name, ext)
								if not self.serviceBusy(service):
									yield service

	def getRandomService(self, service):
		#IDEA: Optionally loop over all
		#TODO calculate the correct title
		idx = self.getIndexOfService(service)
		if self.list[idx][7] in extMedia:
			# Cursor marks a movie
			length = len(self.list)
			shuffle = range(length)
			random.shuffle( shuffle )
			for i in shuffle:
				entry = self.list[i]
				if entry and entry[7] in plyAll:
					# Entry is no directory
					service = entry[0]
					if not self.serviceBusy(service):
						yield service
		elif self.list[idx][7] == cmtDir:
			# Cursor marks a directory
			#IDEA: Optionally play also the following movielist items (folders and movies)
			path = self.list[idx][4]
			# Don't play movies from the trash folder or ".."
			if os.path.realpath(path) != os.path.realpath(config.EMC.movie_trashcan_path.value) and path != "..":
				#IDEA Is there a way to reuse the reload or createdirlist function
					#TODO Then the files are sorted and played in their correct order
					# So we don't have the whole dir and file recognition handling twice
					# Simulate reload:	tmplist = self.reload(path, True)
				entries = []
				for root, dirs, files in os.walk(path):
					for dir in dirs:
						entries.append( os.path.join(root, dir) )
					for file in files:
						entries.append( os.path.join(root, file) )

				if entries:
					length = len(entries)
					shuffle = range(length)
					random.shuffle( shuffle )
					for i in shuffle:
						entry = entries[i]
						pathname = os.path.join(root, entry)
						ext = os.path.splitext(pathname)[1]
						if ext in plyAll:
							# Entry is playable
							service = getPlayerService(pathname, entry, ext)
							if not self.serviceBusy(service):
								yield service

						elif os.path.isdir(pathname):
							dvdStruct = detectDVDStructure( pathname )
							if dvdStruct:
								path = os.path.dirname(dvdStruct)
								ext = os.path.splitext(dvdStruct)[1].lower()
								service = getPlayerService(path, entry, ext)
								if not self.serviceBusy(service):
									yield service

	def removeServiceInternal(self, service):
		if service:
			for l in self.list[:]:
				if l[0] == service:
					self.list.remove(l)
					break
			return self.doListSort(self.list)

	def removeServiceOfTypeInternal(self, service, type):
		if service:
			for l in self.list[:]:
				if l[0] == service and l[7] == type:
					self.list.remove(l)
					break
			return self.doListSort(self.list)

	def setSortingModeInternal(self, mode, order):
		self.returnSort = None

		if mode is None:
			mode = self.actualSort[0]
		if order is None:
			order = self.actualSort[1]

		self.actualSort = (mode, order)

		self.list = self.doListSort(self.list)
		return self.list

	def toggleSelectionInternal(self, entry, index, overrideNum, invalidateFunction=None):
		if self.selectionList == None:
			self.selectionList = []
		newselnum = entry[5]	# init with old selection number
		if overrideNum == None:
			if self.serviceBusy(entry[0]): return	# no toggle if file being operated on
			# basic selection toggle
			if newselnum == 0:
				# was not selected
				self.currentSelectionCount += 1
				newselnum = self.currentSelectionCount
				self.selectionList.append(entry[0]) # append service
			else:
				# was selected, reset selection number and decrease all that had been selected after this
				newselnum = 0
				self.currentSelectionCount -= 1
				count = 0
				if entry is not None:
					if entry[0] in self.selectionList:
						self.selectionList.remove(entry[0]) # remove service
				for i in self.list:
					if i[5] > entry[5]:
						l = list(i)
						l[5] = i[5]-1
						self.list[count] = tuple(l)
						invalidateFunction and invalidateFunction(count) # force redraw
					count += 1
		else:
			newselnum = overrideNum * (newselnum == 0)
		l = list(entry)
		l[5] = newselnum
		self.list[index] = tuple(l)
		invalidateFunction and invalidateFunction(index) # force redraw of the modified item

	def highlightServiceInternal(self, enable, mode, service):
		if enable:
			if mode == "move":
				self.highlightsMov.append(service)
			elif mode == "del":
				self.highlightsDel.append(service)
			elif mode == "copy":
				self.highlightsCpy.append(service)
		elif service:
			# Reset the length to force progress recalculation
			self.updateLength(service, 0)
			if mode == "move":
				if service in self.highlightsMov:
					self.highlightsMov.remove(service)
			elif mode == "del":
				if service in self.highlightsDel:
					self.highlightsDel.remove(service)
			elif mode == "copy":
				if service in self.highlightsCpy:
					self.highlightsCpy.remove(service)

def loadPix(name):
	if screen_height == 1440:
		plugindir = '/usr/lib/enigma2/python/Plugins/Extensions/EnhancedMovieCenter/img_wqhd/'
		if config.EMC.use_orig_skin.value:
			pic = LoadPixmap(cached=True, path=plugindir+name)
			return pic
		else:
			if fileExists(resolveFilename(SCOPE_CURRENT_SKIN, 'emc/'+name)):
				pic = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, 'emc/'+name))
			else:
				pic = LoadPixmap(cached=True, path=plugindir+name)
			return pic
	elif screen_height == 1080:
		plugindir = '/usr/lib/enigma2/python/Plugins/Extensions/EnhancedMovieCenter/img_fhd/'
		if config.EMC.use_orig_skin.value:
			pic = LoadPixmap(cached=True, path=plugindir+name)
			return pic
		else:
			if fileExists(resolveFilename(SCOPE_CURRENT_SKIN, 'emc/'+name)):
				pic = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, 'emc/'+name))
			else:
				pic = LoadPixmap(cached=True, path=plugindir+name)
			return pic
	else:
		plugindir = '/usr/lib/enigma2/python/Plugins/Extensions/EnhancedMovieCenter/img/'
		if config.EMC.use_orig_skin.value:
			pic = LoadPixmap(cached=True, path=plugindir+name)
			return pic
		else:
			if fileExists(resolveFilename(SCOPE_CURRENT_SKIN, 'emc/'+name)):
				pic = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, 'emc/'+name))
			else:
				pic = LoadPixmap(cached=True, path=plugindir+name)
			return pic

moviecenter = None

class MovieCenter(GUIComponent):

	def __getattr__(self, name):
		global moviecenterdata
		if moviecenterdata is None:
			moviecenterdata = MovieCenterData()
		return getattr(moviecenterdata, name)

	#def __setattr__(self, name, value):
	#	global moviecenterdata
	#	if moviecenterdata is None:
	#		moviecenterdata = MovieCenterData()
	#	setattr(moviecenterdata, name, value)

	def __init__(self):
		GUIComponent.__init__(self)

		global moviecenter
		moviecenter = self

		screen_height = getDesktop(0).size().height()

		self.startWorker = False

		self.serviceHandler = ServiceCenter.getInstance()

		self.CoolFont = parseFont("Regular;20", ((1,1),(1,1)))
		self.CoolSelectFont = parseFont("Regular;20", ((1,1),(1,1)))
		self.CoolDateFont = parseFont("Regular;20", ((1,1),(1,1)))

		#IDEA self.CoolIconPos
		self.CoolMoviePos = 100
		self.CoolMovieHPos = 0
		self.CoolMovieSize = 490
		self.CoolFolderSize = 550
		self.CoolTitleColor = 0
		self.CoolDatePos = -1
		self.CoolDateHPos = 0
		self.CoolDateWidth = 115
		self.CoolDateColor = 0
		self.CoolHighlightColor = 0
		self.CoolProgressPos = -1
		self.CoolProgressHPos = 0
		self.CoolBarPos = -1
		self.CoolBarHPos = 8
		self.CoolIconHPos = 2
		# we have now reached a point, where we need a
		# general change in buildMovieCenterEntry for that
		# for example:
		# we can make now all values like that
		# so it gives more possibilities for skinners, but needs real changes then !
		# self.CoolIconPos = parsePosition("5,2", ((1,1),(1,1)))
		# self.CoolIconSize = parseSize("24,24", ((1,1),(1,1)))
		self.CoolIconPos = 5
		self.CoolIconSize = parseSize("24,24", ((1,1),(1,1)))

		self.CoolSelNumTxtWidth = 26

		self.CoolBarSize = parseSize("55,10", ((1,1),(1,1)))
		self.CoolBarSizeSa = parseSize("55,10", ((1,1),(1,1)))

		self.CoolMoviePiconPos = -1
		self.CoolMoviePiconSize = -1
		self.CoolPiconPos = -1
		self.CoolPiconHPos = -1
		self.CoolPiconWidth = -1
		self.CoolPiconHeight = -1
		self.CoolCSWidth = 110
		self.CoolCSPos = -1
		self.CoolDirInfoWidth = -1

		self.DefaultColor = 0xFFFFFF
		self.TitleColor = 0xFFFFFF
		self.DateColor = 0xFFFFFF
		self.BackColor = None
		self.BackColorSel = None
		self.FrontColorSel = parseColor(config.EMC.color_highlight.value).argb()
		self.UnwatchedColor = parseColor(config.EMC.color_unwatched.value).argb()
		self.WatchingColor = parseColor(config.EMC.color_watching.value).argb()
		self.FinishedColor = parseColor(config.EMC.color_finished.value).argb()
		self.RecordingColor = parseColor(config.EMC.color_recording.value).argb()
		#IDEA self.CutColor

		self.l = eListboxPythonMultiContent()
		self.l.setFont(0, gFont("Regular", 22))
		self.l.setFont(1, self.CoolFont)
		self.l.setFont(2, gFont("Regular", 20))
		self.l.setFont(3, self.CoolSelectFont)
		self.l.setFont(4, self.CoolDateFont)
		self.l.setBuildFunc(self.buildMovieCenterEntry)
		self.l.setItemHeight(28)

		self.pic_back            = loadPix('back.png')
		self.pic_directory       = loadPix('dir.png')
		self.pic_directory_locked= loadPix('dir_locked.png')
		self.pic_directory_search= loadPix('dir_search.png')
		self.pic_movie_default   = loadPix('movie_default.png')
		self.pic_movie_unwatched = loadPix('movie_unwatched.png')
		self.pic_movie_watching  = loadPix('movie_watching.png')
		self.pic_movie_finished  = loadPix('movie_finished.png')
		self.pic_movie_rec       = loadPix('movie_rec.png')
		self.pic_movie_recrem    = loadPix('movie_recrem.png')
		self.pic_movie_cut       = loadPix('movie_cut.png')
		self.pic_e2bookmark      = loadPix('e2bookmark.png')
		self.pic_emcbookmark     = loadPix('emcbookmark.png')
		self.pic_trashcan        = loadPix('trashcan.png')
		self.pic_trashcan_full   = loadPix('trashcan_full.png')
		self.pic_mp3             = loadPix('music.png')
		self.pic_dvd_default     = loadPix('dvd_default.png')
		self.pic_dvd_watching    = loadPix('dvd_watching.png')
		self.pic_dvd_finished    = loadPix('dvd_finished.png')
		self.pic_brd_default     = loadPix('brd_default.png')
		# TODO: Progress.value for blue structure
		#self.pic_brd_watching    = loadPix('brd_watching.png')
		#self.pic_brd_finished    = loadPix('brd_finished.png')
		self.pic_playlist        = loadPix('playlist.png')
		self.pic_vlc             = loadPix('vlc.png')
		self.pic_vlc_dir         = loadPix('vlcdir.png')
		self.pic_link            = loadPix('link.png')
		self.pic_latest          = loadPix('virtual.png')
		self.pic_col_dir         = loadPix('coldir.png')

		self.onSelectionChanged = []

		self.l.setList( self.getList() )

	def applySkin(self, desktop, parent):
		attribs = []
		if self.skinAttributes is not None:
			for (attrib, value) in self.skinAttributes:
				if attrib == "CoolFont":
					self.CoolFont = parseFont(value, ((1,1),(1,1)))
					self.l.setFont(1, self.CoolFont)
				elif attrib == "CoolSelectFont":
					self.CoolSelectFont = parseFont(value, ((1,1),(1,1)))
					self.l.setFont(3, self.CoolSelectFont)
				elif attrib == "CoolDateFont":
					self.CoolDateFont = parseFont(value, ((1,1),(1,1)))
					self.l.setFont(4, self.CoolDateFont)
				elif attrib == "CoolDirPos":
					pass

				elif attrib == "CoolMoviePos":
					self.CoolMoviePos = int(value)
				elif attrib == "CoolMovieHPos":
					self.CoolMovieHPos = int(value)
				elif attrib == "CoolMovieSize":
					self.CoolMovieSize = int(value)
				elif attrib == "CoolMoviePiconPos":
					self.CoolMoviePiconPos = int(value)
				elif attrib == "CoolMoviePiconSize":
					self.CoolMoviePiconSize = int(value)
				elif attrib == "CoolIconHPos":
					self.CoolIconHPos = int(value)
				elif attrib == "CoolIconPos":
					self.CoolIconPos = int(value)
				elif attrib == "CoolIconSize":
					self.CoolIconSize = parseSize(value, ((1,1),(1,1)))

				elif attrib == "CoolFolderSize":
					self.CoolFolderSize = int(value)
				elif attrib == "CoolTitleColor":
					self.CoolTitleColor = int(value)
				elif attrib == "CoolDatePos":
					self.CoolDatePos = int(value)
				elif attrib == "CoolDateHPos":
					self.CoolDateHPos = int(value)
				elif attrib == "CoolDateWidth":
					self.CoolDateWidth = int(value)
				elif attrib == "CoolDateColor":
					self.CoolDateColor = int(value)
				elif attrib == "CoolHighlightColor":
					self.CoolHighlightColor = int(value)
				elif attrib == "CoolTimePos":
					pass

				elif attrib == "CoolCSWidth":
					self.CoolCSWidth = int(value)
				elif attrib == "CoolCSPos":
					self.CoolCSPos = int(value)
				elif attrib == "CoolDirInfoWidth":
					self.CoolDirInfoWidth = int(value)
				elif attrib == "CoolSelNumTxtWidth":
					self.CoolSelNumTxtWidth = int(value)
				elif attrib == "CoolProgressPos":
					self.CoolProgressPos = int(value)
				elif attrib == "CoolProgressHPos":
					self.CoolProgressHPos = int(value)
				elif attrib == "CoolBarPos":
					self.CoolBarPos = int(value)
				elif attrib == "CoolBarHPos":
					self.CoolBarHPos = int(value)
				elif attrib == "CoolBarSize":
					self.CoolBarSize = parseSize(value, ((1,1),(1,1)))
				elif attrib == "CoolBarSizeSa":
					self.CoolBarSizeSa = parseSize(value, ((1,1),(1,1)))
				elif attrib == "CoolPiconPos":
					self.CoolPiconPos = int(value)
				elif attrib == "CoolPiconHPos":
					self.CoolPiconHPos = int(value)
				elif attrib == "CoolPiconWidth":
					self.CoolPiconWidth = int(value)
				elif attrib == "CoolPiconHeight":
					self.CoolPiconHeight = int(value)
				elif attrib == "TitleColor":
					self.TitleColor = parseColor(value).argb()
				elif attrib == "DateColor":
					self.DateColor = parseColor(value).argb()
				elif attrib == "DefaultColor":
					self.DefaultColor = parseColor(value).argb()
				elif attrib == "BackColor":
					self.BackColor = parseColor(value).argb()
				elif attrib == "BackColorSel":
					self.BackColorSel = parseColor(value).argb()
				elif attrib == "FrontColorSel":
					self.FrontColorSel = parseColor(value).argb()
				elif attrib == "UnwatchedColor":
					self.UnwatchedColor = parseColor(value).argb()
				elif attrib == "WatchingColor":
					self.WatchingColor = parseColor(value).argb()
				elif attrib == "FinishedColor":
					self.FinishedColor = parseColor(value).argb()
				elif attrib == "RecordingColor":
					self.RecordingColor = parseColor(value).argb()
				else:
					attribs.append((attrib, value))
		self.skinAttributes = attribs
		return GUIComponent.applySkin(self, desktop, parent)

	def selectionChanged(self):
		for f in self.onSelectionChanged:
			try:
				f()
			except Exception, e:
				emcDebugOut("[MC] External observer exception: \n" + str(e))

	def buildMovieCenterEntry(self, service, sorttitle, date, title, path, selnum, length, ext, cutnr, sorteventtitle, eventtitle, piconpath, *args):
		#TODO remove before release
		try:
			offset = 0
			progressWidth = 65
			globalHeight = 80
			progress = 0
			pixmap = None
			datepic = None
			color = None
			datetext = ""

			res = [ None ]
			append = res.append

			isLink = movieFileCache.isLink(path)
			isExtHDDSleeping = config.EMC.limit_fileops_noscan.value and mountPoints.isExtHDDSleeping(path,self)
			#usedFont = int(config.EMC.skin_able.value)
			if int(config.EMC.skin_able.value):
				usedFont = 1
				usedDateFont = 4
			else:
				usedFont = 0
				usedDateFont = 2

			#TODOret print "EMC ret bldSer " +str(service.toString())

			if ext in plyAll:
				colortitle = None
				colordate = None
				colorhighlight = None
				selnumtxt = None

				bluiso = False
				checkIso = config.EMC.check_blustruct_iso.value
				if checkIso:
					if ext in extIso:
						if detectBLUISO(service.getPath()):
							bluiso = True

				# Playable files
				latest = date and (datetime.today()-date).days < 1

				# Check for recording only if date is within the last day
				if latest and self.recControl.isRecording(path):
					datetext = "-- REC --"
					pixmap = self.pic_movie_rec
					color = self.RecordingColor
					# Recordings status shows always the progress of the recording,
					# Never the progress of the cut list marker to avoid misunderstandings
					progress = service and getRecordProgress(path) or 0

				elif latest and config.EMC.remote_recordings.value and self.recControl.isRemoteRecording(path):
					datetext = "-- rec --"
					pixmap = self.pic_movie_recrem
					color = self.RecordingColor

				#IDEA elif config.EMC.check_movie_cutting.value:
				elif self.recControl.isCutting(path):
					datetext = "-- CUT --"
					pixmap = self.pic_movie_cut
					color = self.RecordingColor

				elif ext in plyVLC:
					datetext = "   VLC   "
					pixmap = self.pic_vlc
					color = self.DefaultColor

				else:
					# Media file
					if config.EMC.movie_date_format.value:
						datetext = date.strftime( config.EMC.movie_date_format.value )

					if config.EMC.movie_progress.value and not isExtHDDSleeping:
						# Calculate progress and state
						progress, updlen = getProgress(service, length) or 0
						if updlen:
							self.updateLength(service, updlen)
						movieUnwatched = config.EMC.movie_progress.value and progress < int(config.EMC.movie_watching_percent.value)
						movieWatching  = config.EMC.movie_progress.value and progress >= int(config.EMC.movie_watching_percent.value) and progress < int(config.EMC.movie_finished_percent.value)
						movieFinished  = config.EMC.movie_progress.value and progress >= int(config.EMC.movie_finished_percent.value)
					else:
						progress = 0
						movieUnwatched = False
						movieWatching = False
						movieFinished = False

					# Icon
					if config.EMC.movie_icons.value:
						# video
						if ext in extVideo and ext not in extDvd and ext not in extBlu:
							if movieUnwatched:
								if config.EMC.mark_latest_files.value and latest:
									pixmap = self.pic_latest
								else:
									pixmap = self.pic_movie_unwatched
							elif movieWatching:
								pixmap = self.pic_movie_watching
							elif movieFinished:
								pixmap = self.pic_movie_finished
							else:
								pixmap = self.pic_movie_default
						# audio
						elif ext in extAudio:
							pixmap = self.pic_mp3
						# dvd iso/structure
						elif ext in extDvd and not bluiso:
							if movieWatching:
								pixmap = self.pic_dvd_watching
							elif movieFinished:
								pixmap = self.pic_dvd_finished
							else:
								pixmap = self.pic_dvd_default
						# blue iso/structure
						elif ext in extBlu or bluiso:
							pixmap = self.pic_brd_default
							# TODO: Progress.value for blue iso/structure
							#if movieWatching:
							#	pixmap = self.pic_brd_watching
							#elif movieFinished:
							#	pixmap = self.pic_brd_finished
							#else:
							#	pixmap = self.pic_brd_default

						# playlists
						elif ext in extPlaylist:
							pixmap = self.pic_playlist
						# all others
						else:
							pixmap = self.pic_movie_default

					# Color
					if movieUnwatched:
						color = self.UnwatchedColor
					elif movieWatching:
						color = self.WatchingColor
					elif movieFinished:
						color = self.FinishedColor
					else:
						color = self.DefaultColor

				colortitle = color
				colordate = color
				#colorhighlight = color
				if color == self.WatchingColor or color == self.FinishedColor or color == self.RecordingColor:
					colorhighlight = color
				else:
					colorhighlight = self.FrontColorSel

				# Get entry selection number
				if service in self.highlightsMov: selnumtxt = "-->"
				elif service in self.highlightsDel: selnumtxt = "X"
				elif service in self.highlightsCpy: selnumtxt = "+"
				elif selnum > 0: selnumtxt = "%02d" % selnum

				if selnumtxt is None:
					if config.EMC.movie_icons.value:
						# hide symlink arrow
						if isLink and config.EMC.link_icons.value:
							selPic = self.pic_link
						else:
							selPic = pixmap
						if not config.EMC.skin_able.value:
							append(MultiContentEntryPixmapAlphaBlend(pos=(5,2), size=(24,24), png=selPic, **{}))
							offset = 35
						else:
							append(MultiContentEntryPixmapAlphaBlend(pos=(self.CoolIconPos,self.CoolIconHPos), size=(self.CoolIconSize.width(),self.CoolIconSize.height()), png=selPic, **{}))
							offset = self.CoolIconPos + self.CoolIconSize.width() + 5
					else:
						offset = 5
				else:
					if not config.EMC.skin_able.value:
						append(MultiContentEntryText(pos=(0, self.CoolMovieHPos), size=(self.CoolSelNumTxtWidth, globalHeight), font=3, flags=RT_HALIGN_CENTER, text=selnumtxt))
						offset += 5 + self.CoolSelNumTxtWidth + 4
					else:
						append(MultiContentEntryText(pos=(self.CoolIconPos, self.CoolMovieHPos), size=(self.CoolSelNumTxtWidth, globalHeight), font=3, flags=RT_HALIGN_CENTER, text=selnumtxt))
						offset += 5 + self.CoolSelNumTxtWidth + 4

				movie_metaload = config.EMC.movie_metaload.value
				if not config.EMC.skin_able.value:

					# TODO: Progress.value for blue structure
					if not ext in extBlu and not bluiso:
						if config.EMC.movie_progress.value == "PB":
							append(MultiContentEntryProgress(pos=(offset, self.CoolBarHPos), size = (self.CoolBarSize.width(), self.CoolBarSize.height()), percent = progress, borderWidth = 1, foreColor = color, foreColorSelected=colorhighlight, backColor = self.BackColor, backColorSelected = None))
							offset += self.CoolBarSize.width() + 10

						elif config.EMC.movie_progress.value == "P":
							append(MultiContentEntryText(pos=(offset, 0), size=(progressWidth, globalHeight), font=usedFont, flags=RT_HALIGN_CENTER, text="%d%%" % (progress), color = color, color_sel = colorhighlight, backcolor = self.BackColor, backcolor_sel = self.BackColorSel))
							offset += progressWidth + 5

					if config.EMC.movie_date_format.value:
						if config.EMC.movie_date_format.value == "%d.%m.%Y %H:%M":
							self.CoolDateWidth = 160
						elif config.EMC.movie_date_format.value == "%Y/%m/%d %H:%M":
							self.CoolDateWidth = 162
						else:
							self.CoolDateWidth = 115
						append(MultiContentEntryText(pos=(self.l.getItemSize().width() - self.CoolDateWidth, self.CoolDateHPos), size=(self.CoolDateWidth, globalHeight), font=usedDateFont, color = colordate, color_sel = colorhighlight, backcolor = self.BackColor, backcolor_sel = self.BackColorSel, flags=RT_HALIGN_CENTER, text=datetext))

					# Media files left side not skin_able
					if movie_metaload:
						if eventtitle != "":
							title = title + " | " + eventtitle

					# Picons only for .ts-files
					textX = offset
					textY = 2
					textSizeY = globalHeight
					if ext in extTS:
						if config.EMC.movie_picons.value:
							piconPos = config.EMC.movie_picons_pos.value
							if piconpath:
								picon = loadPNG(piconpath)
								piconH = self.l.getItemSize().height() - 6
								piconW = round(piconH * 1.666)
								piconY = 3
								if piconPos == "nr":
									if config.EMC.movie_date_format.value != "":
										piconX = self.l.getItemSize().width() - self.CoolDateWidth - piconW - 5
										textSizeX = self.l.getItemSize().width() - textX - self.CoolDateWidth - piconW - 15
									else:
										piconX = self.l.getItemSize().width() - piconW - 5
										textSizeX = self.l.getItemSize().width() - textX - 15 - piconW
								else:
									if config.EMC.movie_date_format.value != "":
										piconX = offset
										textX += piconW + 5
										textSizeX = self.l.getItemSize().width() - textX - self.CoolDateWidth - 10
									else:
										piconX = offset
										textX += piconW + 5
										textSizeX = self.l.getItemSize().width() - textX - 5
								# Special way for vti-images, directly over "eListboxPythonMultiContent", they have no "flags=..", only "options=.."
								if newPiconRenderer or imgVti:
									append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, piconX, piconY, piconW, piconH, picon, None, None, BT_SCALE | BT_KEEP_ASPECT_RATIO))
								else:
									append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, piconX, piconY, piconW, piconH, picon, None, None))

								append(MultiContentEntryText(pos=(textX, textY), size=(textSizeX, textSizeY), font=usedFont, flags=RT_HALIGN_LEFT, text=title, color = colortitle, color_sel = colorhighlight, backcolor = self.BackColor, backcolor_sel = self.BackColorSel))
							else:
								if piconPos == "nr":
									if config.EMC.movie_date_format.value != "":
										textSizeX = self.l.getItemSize().width() - textX - self.CoolDateWidth - 10
									else:
										textSizeX = self.l.getItemSize().width() - textX - 5
								else:
									if config.EMC.movie_date_format.value != "":
										textSizeX = self.l.getItemSize().width() - textX - self.CoolDateWidth - 10
									else:
										textSizeX = self.l.getItemSize().width() - textX - 5
								append(MultiContentEntryText(pos=(textX, textY), size=(textSizeX, textSizeY), font=usedFont, flags=RT_HALIGN_LEFT, text=title, color = colortitle, color_sel = colorhighlight, backcolor = self.BackColor, backcolor_sel = self.BackColorSel))
						else:
							if config.EMC.movie_date_format.value != "":
								textSizeX = self.l.getItemSize().width() - textX - self.CoolDateWidth - 10
							else:
								textSizeX = self.l.getItemSize().width() - textX - 5
							append(MultiContentEntryText(pos=(textX, textY), size=(textSizeX, textSizeY), font=usedFont, flags=RT_HALIGN_LEFT, text=title, color = colortitle, color_sel = colorhighlight, backcolor = self.BackColor, backcolor_sel = self.BackColorSel))
					else:
						if config.EMC.movie_date_format.value != "":
							textSizeX = self.l.getItemSize().width() - textX - self.CoolDateWidth - 10
						else:
							textSizeX = self.l.getItemSize().width() - textX - 5
						append(MultiContentEntryText(pos=(textX, textY), size=(textSizeX, textSizeY), font=usedFont, flags=RT_HALIGN_LEFT, text=title, color = colortitle, color_sel = colorhighlight, backcolor = self.BackColor, backcolor_sel = self.BackColorSel))

				else:
					# Skin can overwrite show column date, progress and progressbar
					# Show Icon always depends on EMC config

					# Skin color overwrite handling
					if self.CoolTitleColor == 0:
						colortitle = self.TitleColor
					if self.CoolDateColor == 0:
						colordate = self.DateColor
					if self.CoolHighlightColor == 0:
						colorhighlight = self.FrontColorSel

					# If no date format is specified, the date column is switched off
					#print "EMC skinable date " + str(config.EMC.movie_date_format.value)
					if config.EMC.movie_date_format.value:
						CoolDatePos = self.CoolDatePos
					else:
						CoolDatePos = -1

					#If show movie progress is off, the progress columns are switched off
					#print "EMC skinable prog " + str(config.EMC.movie_progress.value)
					if config.EMC.movie_progress.value == "PB":
						CoolBarPos = self.CoolBarPos
					else:
						CoolBarPos = -1
					if config.EMC.movie_progress.value == "P":
						CoolProgressPos = self.CoolProgressPos
					else:
						CoolProgressPos = -1

					# TODO: Progress.value for blue structure
					if ext in extBlu or bluiso:
						CoolProgressPos = -1
						CoolBarPos = -1

					if CoolBarPos != -1:
						if config.EMC.movie_icons.value:
							append(MultiContentEntryProgress(pos=(CoolBarPos, self.CoolBarHPos -2), size = (self.CoolBarSizeSa.width(), self.CoolBarSizeSa.height()), percent = progress, borderWidth = 1, foreColor = color, foreColorSelected=colorhighlight, backColor = self.BackColor, backColorSelected = None))
						else:
							if self.CoolBarPos < self.CoolMoviePos:
								iconsub = self.CoolIconSize.width()
							else:
								iconsub = 0
							append(MultiContentEntryProgress(pos=(CoolBarPos - iconsub, self.CoolBarHPos -2), size = (self.CoolBarSizeSa.width(), self.CoolBarSizeSa.height()), percent = progress, borderWidth = 1, foreColor = color, foreColorSelected=colorhighlight, backColor = self.BackColor, backColorSelected = None))
					if CoolProgressPos != -1:
						if config.EMC.movie_icons.value:
							append(MultiContentEntryText(pos=(CoolProgressPos, self.CoolMovieHPos), size=(progressWidth, globalHeight), font=usedFont, flags=RT_HALIGN_LEFT, text="%d%%" % (progress), color = colortitle, color_sel = colorhighlight))
						else:
							if self.CoolProgressPos < self.CoolMoviePos:
								iconsub = self.CoolIconSize.width()
							else:
								iconsub = 0
							append(MultiContentEntryText(pos=(CoolProgressPos - iconsub, self.CoolMovieHPos), size=(progressWidth, globalHeight), font=usedFont, flags=RT_HALIGN_LEFT, text="%d%%" % (progress), color = colortitle, color_sel = colorhighlight))
					if CoolDatePos != -1:
						if config.EMC.movie_date_position.value == '1':
							halign = RT_HALIGN_RIGHT
						elif config.EMC.movie_date_position.value == '2':
							halign = RT_HALIGN_LEFT
						else:
							halign = RT_HALIGN_CENTER
						append(MultiContentEntryText(pos=(CoolDatePos, self.CoolDateHPos), size=(self.CoolDateWidth, globalHeight), font=usedDateFont, text=datetext, color = colordate, color_sel = colorhighlight, flags=halign))

					# Media files left side
					if movie_metaload:
						if eventtitle != "":
							title = title + " | " + eventtitle

					# show picons only, if we have piconpath
					if config.EMC.movie_picons.value:
						if piconpath:
							CoolPiconPos = self.CoolPiconPos
							CoolMoviePiconPos = self.CoolMoviePiconPos
						else:
							CoolPiconPos = -1
							CoolMoviePiconPos = -1
					else:
						CoolPiconPos = -1
						CoolMoviePiconPos = -1

					progressval = config.EMC.movie_progress.value
					if ext in extTS:
						if CoolPiconPos != -1 and CoolMoviePiconPos != -1:
							picon = loadPNG(piconpath)
							if self.CoolPiconHeight == -1:
								self.CoolPiconHeight = self.l.getItemSize().height() - 6
							if self.CoolPiconHPos == -1:
								self.CoolPiconHPos = 2
							if self.CoolPiconWidth == -1:
								self.CoolPiconWidth = 110
							# Special way for vti-images, directly over "eListboxPythonMultiContent", they have no "flags=..", only "options=.."
							if newPiconRenderer or imgVti:
								progresssub = 0
								numsub = 0
								if config.EMC.movie_icons.value:
									if progressval == "MC" or progressval == "":
										if self.CoolBarPos < CoolPiconPos:
											progresssub = self.CoolBarSizeSa.width() + 5
								else:
									if selnumtxt is None:
										numsub = self.CoolIconSize.width()
									if progressval == "MC" or progressval == "":
										if self.CoolBarPos < CoolPiconPos:
											progresssub = self.CoolBarSizeSa.width()
								append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, CoolPiconPos - numsub - progresssub, self.CoolPiconHPos, self.CoolPiconWidth, self.CoolPiconHeight, picon, None, None, BT_SCALE | BT_KEEP_ASPECT_RATIO))
							else:
								progresssub = 0
								numsub = 0
								if config.EMC.movie_icons.value:
									if progressval == "MC" or progressval == "":
										if self.CoolBarPos < CoolPiconPos:
											progresssub = self.CoolBarSizeSa.width() + 5
								else:
									if selnumtxt is None:
										numsub = self.CoolIconSize.width()
									if progressval == "MC" or progressval == "":
										if self.CoolBarPos < CoolPiconPos:
											progresssub = self.CoolBarSizeSa.width()
								append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, CoolPiconPos - numsub - progresssub, self.CoolPiconHPos, self.CoolPiconWidth, self.CoolPiconHeight, picon, None, None))

							progresssub = 0
							progressadd = 0
							numsub = 0
							if config.EMC.movie_icons.value:
								if progressval == "MC" or progressval == "":
									progressadd = self.CoolBarSizeSa.width()
									if self.CoolBarPos < self.CoolMoviePiconPos:
										progresssub = self.CoolBarSizeSa.width() + 5
							else:
								if selnumtxt is None:
									numsub = self.CoolIconSize.width()
								if progressval == "MC" or progressval == "":
									progressadd = self.CoolBarSizeSa.width()
									if self.CoolBarPos < self.CoolMoviePiconPos:
										progresssub = self.CoolBarSizeSa.width()
							append(MultiContentEntryText(pos=(self.CoolMoviePiconPos - numsub - progresssub, self.CoolMovieHPos), size=(self.CoolMoviePiconSize + numsub + progressadd, globalHeight), font=usedFont, flags=RT_HALIGN_LEFT, text=title, color = colortitle, color_sel = colorhighlight))
						else:
							progresssub = 0
							progressadd = 0
							numsub = 0
							if config.EMC.movie_icons.value:
								if progressval == "MC" or progressval == "":
									progressadd = self.CoolBarSizeSa.width()
									if self.CoolBarPos < self.CoolMoviePos:
										progresssub = self.CoolBarSizeSa.width() + 10
							else:
								if selnumtxt is None:
									numsub = self.CoolIconSize.width()
								if progressval == "MC" or progressval == "":
									progressadd = self.CoolBarSizeSa.width()
									if self.CoolBarPos <= self.CoolMoviePos:
										progresssub = self.CoolBarSizeSa.width()
							append(MultiContentEntryText(pos=(self.CoolMoviePos - numsub - progresssub, self.CoolMovieHPos), size=(self.CoolMovieSize + numsub + progressadd, globalHeight), font=usedFont, flags=RT_HALIGN_LEFT, text=title, color = colortitle, color_sel = colorhighlight))
					else:
						progresssub = 0
						progressadd = 0
						numsub = 0
						if config.EMC.movie_icons.value:
							if progressval == "MC" or progressval == "":
								progressadd = self.CoolBarSizeSa.width()
								if self.CoolBarPos < self.CoolMoviePos:
									progresssub = self.CoolBarSizeSa.width() + 10
						else:
							if selnumtxt is None:
								numsub = self.CoolIconSize.width()
							if progressval == "MC" or progressval == "":
								progressadd = self.CoolBarSizeSa.width()
								if self.CoolBarPos < self.CoolMoviePos:
									progresssub = self.CoolBarSizeSa.width()
						append(MultiContentEntryText(pos=(self.CoolMoviePos - numsub - progresssub, self.CoolMovieHPos), size=(self.CoolMovieSize + numsub + progressadd, globalHeight), font=usedFont, flags=RT_HALIGN_LEFT, text=title, color = colortitle, color_sel = colorhighlight))

			else:
				# Directory and vlc directories

				#TODO Is there any way to combine it for both files and directories?
				#TODO Color not used yet for folders color = self.DefaultColor
				#TODO config.EMC.movie_icons.value not used here // try: line ~1827
				#TODO Skin config.EMC.skin_able.value not used here
				#TODO config.EMC.movie_date_format.value not used here

				if ext == cmtVLC:
					pixmap = self.pic_vlc
					datepic = None
					if config.EMC.directories_info.value == "D":
						datetext = _("VLC")

				elif ext == vlcSrv:
					pixmap = self.pic_vlc
					datepic = None
					if config.EMC.directories_info.value == "D":
						datetext = _("VLC-Server")

				elif ext == vlcDir:
					pixmap = self.pic_vlc_dir
					datepic = None
					if config.EMC.directories_info.value == "D":
						datetext = _("VLC-Dir")

				elif ext == cmtLRec:
					pixmap = self.pic_latest
					datepic = None
					if config.EMC.directories_info.value == "D":
						datetext = _("Latest")

				elif ext == cmtUp:
					pixmap = self.pic_back
					datepic = None
					if config.EMC.directories_info.value == "D":
						datetext = _("Up")

				elif ext == cmtBME2:
					pixmap = self.pic_e2bookmark
					datepic = None
					if config.EMC.directories_info.value == "D":
						datetext = _("Bookmark")

				elif ext == cmtBMEMC:
					pixmap = self.pic_emcbookmark
					datepic = None
					if config.EMC.directories_info.value == "D":
						datetext = _("Bookmark")

				elif ext == cmtTrash:
					if config.EMC.movie_trashcan_enable.value:
						(count, size, datetext, datepic, dummy_pixmap) = self.getValues_startWorker(path,config.EMC.movie_trashcan_info.value,datetext,datepic,pixmap,isLink,True,title)
						if count:
							# Trashcan contains garbage
							pixmap = self.pic_trashcan_full
						else:
							# Trashcan is empty
							pixmap = self.pic_trashcan
					else:
						pixmap = self.pic_trashcan

				elif ext == cmtDir:
					if not isExtHDDSleeping:
						if os.path.isfile(path + "/dir.lock"):
							pixmap = self.pic_directory_locked
						else:
							pixmap = self.pic_directory
					else:
						pixmap = self.pic_directory

					if config.EMC.directories_ontop.value and title not in self.topdirlist:
						pixmap = self.pic_col_dir

					(count, size, datetext, datepic, pixmap) = self.getValues_startWorker(path,config.EMC.directories_info.value,datetext,datepic,pixmap,isLink,False,title)

				else:
					# Should never happen
					pixmap = self.pic_directory
					datepic = None
					if config.EMC.directories_info.value == 'D':
						datetext = _("UNKNOWN")

				# Is there any way to combine it for both files and directories?
				# it is, but not with this hole code
				if config.EMC.movie_icons.value:
					# hide symlink arrow
					if isLink and config.EMC.link_icons.value:
						dirPic = self.pic_link
					else:
						dirPic = pixmap
					if not config.EMC.skin_able.value:
						append(MultiContentEntryPixmapAlphaBlend(pos=(5,2), size=(24,24), png=dirPic, **{}))
					else:
						append(MultiContentEntryPixmapAlphaBlend(pos=(self.CoolIconPos,self.CoolIconHPos), size=(self.CoolIconSize.width(),self.CoolIconSize.height()), png=dirPic, **{}))

				# Directory left side
				if not config.EMC.skin_able.value:
					dirTitleSize = (self.CoolFolderSize, globalHeight)   # this is not realy mutable ?!
					if config.EMC.movie_icons.value:
						dirTitlePos = (35, 2)
					else:
						dirTitlePos = (5, 2)
				else:
					if config.EMC.movie_icons.value:
						dirTitlePos = (self.CoolIconPos + self.CoolIconSize.width() + 5, self.CoolMovieHPos)
						dirTitleSize = (self.CoolFolderSize, globalHeight)
					else:
						dirTitlePos = (5, self.CoolMovieHPos)
						dirTitleSize = (self.CoolFolderSize + self.CoolIconSize.width(), globalHeight)
				append(MultiContentEntryText(pos=dirTitlePos, size=dirTitleSize, font=usedFont, flags=RT_HALIGN_LEFT, text=title))

				# TODO: Directory left side - skin able
				#append(MultiContentEntryText(pos=(self.CoolMoviePos, 0), size=(self.CoolFolderSize, globalHeight), font=usedFont, flags=RT_HALIGN_LEFT, text=title))
				# Directory right side
				if screen_height == 1440:
					if not config.EMC.skin_able.value:
						CoolCSWidth = int(self.CoolCSWidth * 2)
					else:
						if self.CoolDirInfoWidth != -1:
							CoolCSWidth = self.CoolDirInfoWidth
						else:
							CoolCSWidth = int(self.CoolCSWidth * 1.5)
				elif screen_height == 1080:
					if not config.EMC.skin_able.value:
						CoolCSWidth = int(self.CoolCSWidth * 1.5)
					else:
						if self.CoolDirInfoWidth != -1:
							CoolCSWidth = self.CoolDirInfoWidth
						else:
							CoolCSWidth = int(self.CoolCSWidth * 1.5)
				else:
					if not config.EMC.skin_able.value:
						CoolCSWidth = self.CoolCSWidth
					else:
						if self.CoolDirInfoWidth != -1:
							CoolCSWidth = self.CoolDirInfoWidth
						else:
							CoolCSWidth = self.CoolCSWidth
				listW = self.l.getItemSize().width()
				posH = dirTitlePos[0] + dirTitleSize[0] + 5
				if not config.EMC.skin_able.value or self.CoolCSPos == -1 or posH + CoolCSWidth > listW:
					posH = listW - CoolCSWidth
				else:
					posH = self.CoolCSPos
				if config.EMC.count_size_position.value == "1":
					halign = RT_HALIGN_RIGHT
				elif config.EMC.count_size_position.value == '2':
					halign = RT_HALIGN_LEFT
				else:
					halign = RT_HALIGN_CENTER
				val = config.EMC.directories_info.value
				if val == "C" or val == "CS" or val == "S":
					if datetext != "":
						append(MultiContentEntryText(pos=(posH, self.CoolDateHPos), size=(CoolCSWidth, globalHeight), font=usedDateFont, flags=halign, text=datetext))
					else:
						useIcon = config.EMC.count_size_default_icon.value
						if useIcon:
							if datepic is not None:
								datepicH = self.l.getItemSize().height() - 6
								datepicW = self.pic_directory_search.size().width()
								datepicY = 3
								append(MultiContentEntryPixmapAlphaBlend(pos=(listW - datepicW, datepicY), size=(datepicW, datepicH), png=self.pic_directory_search, **{}))
						else:
							if datepic is not None:
								count = config.EMC.count_default_text.value
								countsize = config.EMC.count_size_default_text.value
								size = config.EMC.size_default_text.value
								if val == "C":
									datetext = count
								elif val == "CS":
									datetext = countsize
								elif val == "S":
									datetext = size
							append(MultiContentEntryText(pos=(posH, self.CoolDateHPos), size=(CoolCSWidth, globalHeight), font=usedDateFont, flags=halign, text=datetext))
				else:
					append(MultiContentEntryText(pos=(posH, self.CoolDateHPos), size=(CoolCSWidth, globalHeight), font=usedDateFont, flags=halign, text=datetext))
			del append
			return res
		except Exception, e:
			emcDebugOut("[EMCMS] build exception:\n" + str(e))

	def getValues_startWorker(self,path,config_EMC_info_value,datetext,datepic,pixmap,isLink,is_trashcan,title):
		count, size = 0, 0
		self.CoolCSWidth = 110
		getValues = movieFileCache.getCountSizeFromCache(path)
		if config_EMC_info_value:
			if config_EMC_info_value == "C":
				if getValues is not None:
					count, size = getValues
					if self.startWorker:
						self.addCountsizeworker(path)
					datetext = "( %d )" % (count)
				else:
					self.addCountsizeworker(path)
					datetext = ""
					datepic = self.pic_directory_search
			elif config_EMC_info_value == "CS":
				if getValues is not None:
					count, size = getValues
					if self.startWorker:
						self.addCountsizeworker(path)
					if size >= 1000:
						size /= 1024.0
						datetext = "( %d / %.0f TB )" % (count, size)
					else:
						datetext = "( %d / %.0f GB )" % (count, size)
					self.CoolCSWidth = 180
				else:
					self.addCountsizeworker(path)
					datetext = ""
					datepic = self.pic_directory_search
			elif config_EMC_info_value == "S":
				if getValues is not None:
					count, size = getValues
					if self.startWorker:
						self.addCountsizeworker(path)
					if size >= 100:
						datetext = "( %.2f TB )" % (size/1024.0)
					else:
						datetext = "( %.2f GB )" % (size)
				else:
					self.addCountsizeworker(path)
					datetext = ""
					datepic = self.pic_directory_search
			elif config_EMC_info_value == "D":
				if is_trashcan:
					datetext = _("Trashcan")
					if getValues is not None:
						count, size = getValues
						if self.startWorker:
							self.addCountsizeworker(path)
					else:
						self.addCountsizeworker(path)
				else:
					if config.EMC.directories_size_skin.value:
						if getValues is not None:
							if self.startWorker:
								self.addCountsizeworker(path)
						else:
							self.addCountsizeworker(path)
					datetext = _("Directory")
					if isLink:
						datetext = _("Link")
					if config.EMC.directories_ontop.value and title not in self.topdirlist:
						datetext = _("Collection")
			else:
				# Should never happen
				pixmap = self.pic_directory
				if is_trashcan:
					datetext = _("Trashcan")
				else:
					datetext = _("Directory")
		elif is_trashcan:
			if getValues is not None:
				count, size = getValues
				if self.startWorker:
					self.addCountsizeworker(path)
			else:
				self.addCountsizeworker(path)
		else: # config_EMC_info_value == ""
			if config.EMC.directories_size_skin.value:
				if getValues is not None:
					if self.startWorker:
						self.addCountsizeworker(path)
				else:
					self.addCountsizeworker(path)

		return (count, size, datetext, datepic, pixmap)

	def addCountsizeworker(self,path):
		if config.EMC.dir_info_usenoscan.value:
			if self.checkNoScanPath(self.currentPath): #always scan sub-dirs of active no-scan dir
				countsizeworker.add(path)
			elif not self.checkNoScanPath(path):
				countsizeworker.add(path)
		else:
			countsizeworker.add(path)

	def getCurrent(self):
		l = self.l.getCurrentSelection()
		return l and l[0]

	def getCurrentIndex(self):
		return self.instance.getCurrentIndex()

	def getCurrentEvent(self):
		l = self.l.getCurrentSelection()
		if l and l[0]:
			info = self.serviceHandler.info(l[0])
			return info and info.getEvent(l[0])

	def getCurrentE2Event(self):
		l = self.l.getCurrentSelection()
		if l and l[0]:
			service = l[0]
			esc = eServiceCenter.getInstance()
			info = esc and esc.info(service)
			return info and info.getEvent(l[0])

	GUI_WIDGET = eListbox

	def postWidgetCreate(self, instance):
		instance.setWrapAround(True)
		instance.setContent(self.l)
		try:
			self.selectionChanged_conn = instance.selectionChanged.connect(self.selectionChanged)
		except:
			instance.selectionChanged.get().append(self.selectionChanged)

	def preWidgetRemove(self, instance):
		instance.setContent(None)
		self.selectionChanged_conn = None

	def removeService(self, service):
		if service:
			list = self.removeServiceInternal(service)
			self.l.setList( list )

	def removeServiceOfType(self, service, type):
		if service:
			list = self.removeServiceOfTypeInternal(service, type)
			self.l.setList( list )

	def __len__(self):
		return len(self.getList())

	def makeSelectionList(self, currentIfEmpty=True):
		selList = []
		if self.currentSelectionCount == 0 and currentIfEmpty:
			# if no selections made, select the current cursor position
			single = self.l.getCurrentSelection()
			if single:
				selList.append(single[0])
		else:
			selList = self.selectionList
		return selList

	def unselectService(self, service):
		if service:
			if self.selectionList:
				if service in self.selectionList:
					# Service is in selection - unselect it
					self.toggleSelection(service)
				else:
					self.invalidateService(service)
			else:
				self.invalidateService(service)

	def invalidateCurrent(self):
		self.l.invalidateEntry(self.getCurrentIndex())

	def invalidateService(self, service):
		idx = self.getIndexOfService(service)
		if idx < 0: return
		self.l.invalidateEntry( idx ) # force redraw of the item

	def refreshList(self, worker=False):
		# Just invalidate the whole list to force rebuild the entries
		# Updates the progress of all entries
		#IDEA Extend the list and mark the recordings
		# so we don't have to go through the whole list
		#TEST Performance for recordings only updating
		#     Separate function for updating recordings only
		#     Check for recording only if date is within the last day
		#for entry in self.list:
		#	if self.recControl.isRecording(entry[4]):
		#		self.invalidateService(entry[0])
		self.startWorker = worker
		self.l.invalidate()

	def reload(self, currentPath, simulate=False, recursive=False):
		list = self.reloadInternal(currentPath, simulate, recursive)
		self.l.setList( list )
		return list

	def moveUp(self):
		self.startWorker = False
		self.instance.moveSelection(self.instance.moveUp)

	def moveDown(self):
		self.startWorker = False
		self.instance.moveSelection(self.instance.moveDown)

	def pageUp(self):
		self.startWorker = False
		self.instance.moveSelection(self.instance.pageUp)

	def pageDown(self):
		self.startWorker = False
		self.instance.moveSelection(self.instance.pageDown)

	def moveTop(self):
		self.startWorker = False
		self.instance.moveSelection(self.instance.moveTop)

	def moveEnd(self):
		self.startWorker = False
		self.instance.moveSelection(self.instance.moveEnd)

	def moveToIndex(self, index):
		self.instance.moveSelectionTo(index)

	def moveToService(self, service):
		if service:
			index = self.getIndexOfService(service)
			if index:
				self.instance.moveSelectionTo(index)

	def currentSelIsPlayable(self):
		try:	return self.getTypeOfIndex(self.getCurrentIndex()) in extMedia
		except:	return False

	def currentSelIsDirectory(self):
		try:	return self.getTypeOfIndex(self.getCurrentIndex()) == cmtDir
		except:	return False

	def currentSelIsVirtual(self):
		try:	return self.getTypeOfIndex(self.getCurrentIndex()) in virAll
		except:	return False

	def currentSelIsE2Bookmark(self):
		try:	return self.getTypeOfIndex(self.getCurrentIndex()) == cmtBME2
		except:	return False

	def currentSelIsEMCBookmark(self):
		try:	return self.getTypeOfIndex(self.getCurrentIndex()) == cmtBMEMC
		except:	return False

	def indexIsDirectory(self, index):
		try:	return self.getTypeOfIndex(index) == cmtDir
		except:	return False

	def indexIsPlayable(self, index):
		try:	return self.getTypeOfIndex(index) in extMedia
		except:	return False

	def getCurrentSelDir(self):
		self.startWorker = True
		try: return self.getListEntry(self.getCurrentIndex())[4]
		except: return False

	def getCurrentSelName(self):
		try: return self.getListEntry(self.getCurrentIndex())[3]
		except: return "none"

	def highlightService(self, enable, mode, service):
		if enable:
			self.unselectService(service)
			self.highlightServiceInternal(enable, mode, service)
		elif service:
			self.highlightServiceInternal(enable, mode, service)

	def toggleSelection(self, service=None, index=-1, overrideNum=None):
		entry = None
		if service is None:
			if index == -1:
				if self.l.getCurrentSelection() is None: return
				index = self.getCurrentIndex()
			entry = self.list[index]
		else:
			index = 0
			for e in self.list:
				if e[0] == service:
					entry = e
					break
				index += 1
		if entry is None: return

		# We have entry, index, overrideNum
		if not self.indexIsPlayable(index): return
		self.toggleSelectionInternal(entry, index, overrideNum, self.l.invalidateEntry)

	def toggleSortingMode(self):
		from Plugins.Extensions.EnhancedMovieCenter.plugin import sort_modes
		#sorts = list( set( [sort for sort, desc in sort_choices] ) )
		sorts = [ v[1] for v in sort_modes.values() ]
		#print sorts
		# Toggle the mode
		mode, order = self.actualSort
		# Get all sorting modes as a list of unique ids
		modes = list( set( [m for m, o in sorts] ) )
		#print modes
		if mode in modes:
			# Get next sorting mode
			idx = modes.index(mode)
			mode = modes[ (idx+1) % len(modes) ]
		else:
			# Fallback
			mode = modes[ 0 ]
		self.setSortingMode(mode, order)

	def toggleSortingOrder(self):
		mode, order = self.actualSort
		self.setSortingMode(mode, not order)

	def setSortingMode(self, mode=None, order=None):
		list = self.setSortingModeInternal(mode, order)
		self.l.setList( list )

	def toggleProgress(self, service):
		if service is None:
			first = False
			forceProgress = -1
			current = self.getCurrent()
			if current is not None:
				# Force copy of selectedlist
				selectedlist = self.makeSelectionList()[:]
				if len(selectedlist)>1:
					first = True
				for service in selectedlist:
					progress = toggleProgressService(service, False, forceProgress, first)
					self.invalidateService(service)
					#DelayedFunction(1000, self.invalidateService, service)
					first = False
					#if not preparePlayback:
					forceProgress = progress
		else:
			toggleProgressService(service, preparePlayback)
			self.invalidateService(service)
			#DelayedFunction(1000, self.invalidateService, service)

	def getNextSelectedService(self, current, selectedlist=None):
		curSerRef = None
		if current is None:
			curSerRef = None
		elif not self.list:
			# Selectedlist is empty
			curSerRef = None
		elif selectedlist is None:
			# Selectedlist is empty
			curSerRef = current
		elif current is not None and current not in selectedlist:
			# Current is not within the selectedlist
			curSerRef = current
		else:
			# Current is within the selectedlist
			last_idx = len(self.list) - 1
			len_sel = len(selectedlist)
			first_sel_idx = last_idx
			last_sel_idx = 0

			# Get first and last selected item indexes
			for sel in selectedlist:
				idx = self.getIndexOfService(sel)
				if idx < 0: idx = 0
				if idx < first_sel_idx: first_sel_idx = idx
				if idx > last_sel_idx:  last_sel_idx = idx

			# Calculate previous and next item indexes
			prev_idx = first_sel_idx - 1
			next_idx = last_sel_idx + 1
			len_fitola = last_sel_idx - first_sel_idx + 1

			# Check if there is a not selected item between the first and last selected item
			if len_fitola > len_sel:
				for entry in self.list[first_sel_idx:last_sel_idx]:
					if entry[0] not in selectedlist:
						# Return first entry which is not in selectedlist
						curSerRef = entry[0]
						break
			# Check if next calculated item index is within the movie list
			elif next_idx <= last_idx:
				# Select item behind selectedlist
				curSerRef = self.getServiceOfIndex(next_idx)
			# Check if previous calculated item index is within the movie list
			elif prev_idx >= 0:
				# Select item before selectedlist
				curSerRef = self.getServiceOfIndex(prev_idx)
			else:
				# The whole list must be selected
				# First and last item is selected
				# Recheck and find first not selected item
				for entry in self.list:
					if entry[0] not in selectedlist:
						# Return first entry which is not in selectedlist
						curSerRef = entry[0]
						break
		return curSerRef
