import xbmcaddon
import xbmcplugin
import xbmc
import xbmcgui
import xbmcvfs
import os, sys
import threading
import json
import urllib
import time

WINDOW = xbmcgui.Window(10000)

import Utils as utils
from ClientInformation import ClientInformation
from PlaybackUtils import PlaybackUtils
from PlayUtils import PlayUtils
from DownloadUtils import DownloadUtils
from ReadEmbyDB import ReadEmbyDB
from API import API
from UserPreferences import UserPreferences


##### Play items via plugin://plugin.video.emby/ #####
def doPlayback(id):
    url = "{server}/mediabrowser/Users/{UserId}/Items/%s?format=json&ImageTypeLimit=1" % id
    result = DownloadUtils().downloadUrl(url)
    item = PlaybackUtils().PLAY(result, setup="default")

#### DO RESET AUTH #####    
def resetAuth():
    # User tried login and failed too many times
    resp = xbmcgui.Dialog().yesno("Warning", "Emby might lock your account if you fail to log in too many times. Proceed anyway?")
    if resp == 1:
        xbmc.log("Reset login attempts.")
        WINDOW.setProperty("Server_status", "Auth")
    else:
        xbmc.executebuiltin('Addon.OpenSettings(plugin.video.emby)')

### ADD ADDITIONAL USERS ###
def addUser():

    doUtils = DownloadUtils()
    clientInfo = ClientInformation()
    currUser = WINDOW.getProperty("currUser")
    deviceId = clientInfo.getMachineId()
    deviceName = clientInfo.getDeviceName()

    # Get session
    url = "{server}/mediabrowser/Sessions?DeviceId=%s" % deviceId
    result = doUtils.downloadUrl(url)
    
    try:
        sessionId = result[0][u'Id']
        additionalUsers = result[0][u'AdditionalUsers']
        # Add user to session
        userlist = {}
        users = []
        url = "{server}/mediabrowser/Users?IsDisabled=false&IsHidden=false"
        result = doUtils.downloadUrl(url)

        # pull the list of users
        for user in result:
            name = user[u'Name']
            userId = user[u'Id']
            if currUser not in name:
                userlist[name] = userId
                users.append(name)

        # Display dialog if there's additional users
        if additionalUsers:

            option = xbmcgui.Dialog().select("Add/Remove user from the session", ["Add user", "Remove user"])
            # Users currently in the session
            additionalUserlist = {}
            additionalUsername = []
            # Users currently in the session
            for user in additionalUsers:
                name = user[u'UserName']
                userId = user[u'UserId']
                additionalUserlist[name] = userId
                additionalUsername.append(name)

            if option == 1:
                # User selected Remove user
                resp = xbmcgui.Dialog().select("Remove user from the session", additionalUsername)
                if resp > -1:
                    selected = additionalUsername[resp]
                    selected_userId = additionalUserlist[selected]
                    url = "{server}/mediabrowser/Sessions/%s/Users/%s" % (sessionId, selected_userId)
                    postdata = {}
                    doUtils.downloadUrl(url, postBody=postdata, type="DELETE")
                    xbmcgui.Dialog().notification("Success!", "%s removed from viewing session" % selected, time=1000)
                    return
                else:
                    return

            elif option == 0:
                # User selected Add user
                for adduser in additionalUsername:
                    try: # Remove from selected already added users. It is possible they are hidden.
                        users.remove(adduser)
                    except: pass

            elif option < 0:
                # User cancelled
                return

        # Subtract any additional users
        xbmc.log("Displaying list of users: %s" % users)
        resp = xbmcgui.Dialog().select("Add user to the session", users)
        # post additional user
        if resp > -1:
            selected = users[resp]
            selected_userId = userlist[selected]
            url = "{server}/mediabrowser/Sessions/%s/Users/%s" % (sessionId, selected_userId)
            postdata = {}
            doUtils.downloadUrl(url, postBody=postdata, type="POST")
            xbmcgui.Dialog().notification("Success!", "%s added to viewing session" % selected, time=1000)

    except:
        xbmc.log("Failed to add user to session.")
        xbmcgui.Dialog().notification("Error", "Unable to add/remove user from the session.", xbmcgui.NOTIFICATION_ERROR)

# THEME MUSIC/VIDEOS
def getThemeMedia():

    doUtils = DownloadUtils()
    playUtils = PlayUtils()
    
    currUser = WINDOW.getProperty('currUser')
    server = WINDOW.getProperty('server%s' % currUser)
    playback = None

    library = xbmc.translatePath("special://profile/addon_data/plugin.video.emby/library/").decode('utf-8')

    # Choose playback method
    resp = xbmcgui.Dialog().select("Choose playback method for your themes", ["Direct Play", "Direct Stream"])
    if resp == 0:
        # Direct Play
        playback = "DirectPlay"
    elif resp == 1:
        # Direct Stream
        playback = "DirectStream"
    else:return

    # Set custom path for user
    tvtunes_path = xbmc.translatePath("special://profile/addon_data/script.tvtunes/").decode('utf-8')
    if xbmcvfs.exists(tvtunes_path):
        tvtunes = xbmcaddon.Addon(id="script.tvtunes")
        tvtunes.setSetting('custom_path_enable', "true")
        tvtunes.setSetting('custom_path', library)
        xbmc.log("TV Tunes custom path is enabled and set.")
    else:
        # if it does not exist this will not work so warn user, often they need to edit the settings first for it to be created.
        dialog = xbmcgui.Dialog()
        dialog.ok('Warning', 'The settings file does not exist in tvtunes. Go to the tvtunes addon and change a setting, then come back and re-run')
        return
        

    # Create library directory
    if not xbmcvfs.exists(library):
        xbmcvfs.mkdir(library)

    # Get every user view Id
    userViews = []
    url = "{server}/mediabrowser/Users/{UserId}/Items?format=json"
    result = doUtils.downloadUrl(url)
    
    for view in result[u'Items']:
        userviewId = view[u'Id']
        userViews.append(userviewId)


    # Get Ids with Theme Videos
    itemIds = {}
    for view in userViews:
        url = "{server}/mediabrowser/Users/{UserId}/Items?HasThemeVideo=True&ParentId=%s&format=json" % view
        result = doUtils.downloadUrl(url)
        if result[u'TotalRecordCount'] != 0:
            for item in result[u'Items']:
                itemId = item[u'Id']
                folderName = item[u'Name']
                folderName = utils.normalize_string(folderName.encode('utf-8'))
                itemIds[itemId] = folderName

    # Get paths for theme videos
    for itemId in itemIds:
        nfo_path = xbmc.translatePath("special://profile/addon_data/plugin.video.emby/library/%s/" % itemIds[itemId])
        # Create folders for each content
        if not xbmcvfs.exists(nfo_path):
            xbmcvfs.mkdir(nfo_path)
        # Where to put the nfos
        nfo_path = "%s%s" % (nfo_path, "tvtunes.nfo")

        url = "{server}/mediabrowser/Items/%s/ThemeVideos?format=json" % itemId
        result = doUtils.downloadUrl(url)

        # Create nfo and write themes to it
        nfo_file = open(nfo_path, 'w')
        pathstowrite = ""
        # May be more than one theme
        for theme in result[u'Items']:  
            if playback == "DirectPlay":
                playurl = playUtils.directPlay(theme)
            else:
                playurl = playUtils.directStream(result, server, theme[u'Id'], "ThemeVideo")
            pathstowrite += ('<file>%s</file>' % playurl.encode('utf-8'))
        
        # Check if the item has theme songs and add them   
        url = "{server}/mediabrowser/Items/%s/ThemeSongs?format=json" % itemId
        result = doUtils.downloadUrl(url)

        # May be more than one theme
        for theme in result[u'Items']:  
            if playback == "DirectPlay":
                playurl = playUtils.directPlay(theme)
            else:
                playurl = playUtils.directStream(result, server, theme[u'Id'], "Audio")
            pathstowrite += ('<file>%s</file>' % playurl.encode('utf-8'))

        nfo_file.write(
            '<tvtunes>%s</tvtunes>' % pathstowrite
        )
        # Close nfo file
        nfo_file.close()

    # Get Ids with Theme songs
    musicitemIds = {}
    for view in userViews:
        url = "{server}/mediabrowser/Users/{UserId}/Items?HasThemeSong=True&ParentId=%s&format=json" % view
        result = doUtils.downloadUrl(url)
        if result[u'TotalRecordCount'] != 0:
            for item in result[u'Items']:
                itemId = item[u'Id']
                folderName = item[u'Name']
                folderName = utils.normalize_string(folderName.encode('utf-8'))
                musicitemIds[itemId] = folderName

    # Get paths
    for itemId in musicitemIds:
        
        # if the item was already processed with video themes back out
        if itemId in itemIds:
            continue
        
        nfo_path = xbmc.translatePath("special://profile/addon_data/plugin.video.emby/library/%s/" % musicitemIds[itemId])
        # Create folders for each content
        if not xbmcvfs.exists(nfo_path):
            xbmcvfs.mkdir(nfo_path)
        # Where to put the nfos
        nfo_path = "%s%s" % (nfo_path, "tvtunes.nfo")
        
        url = "{server}/mediabrowser/Items/%s/ThemeSongs?format=json" % itemId
        result = doUtils.downloadUrl(url)

        # Create nfo and write themes to it
        nfo_file = open(nfo_path, 'w')
        pathstowrite = ""
        # May be more than one theme
        for theme in result[u'Items']:  
            if playback == "DirectPlay":
                playurl = playUtils.directPlay(theme)
            else:
                playurl = playUtils.directStream(result, server, theme[u'Id'], "Audio")
            pathstowrite += ('<file>%s</file>' % playurl.encode('utf-8'))

        nfo_file.write(
            '<tvtunes>%s</tvtunes>' % pathstowrite
        )
        # Close nfo file
        nfo_file.close()

def userPreferences():
    doUtils = DownloadUtils()
    addonSettings = xbmcaddon.Addon(id='plugin.video.emby')
    userPreferencesPage = UserPreferences("script-emby-kodi-UserPreferences.xml", addonSettings.getAddonInfo('path'), "default", "1080i")
    url = "{server}/mediabrowser/Users/{UserId}" 
    result = doUtils.downloadUrl(url)
    configuration = result[u'Configuration']
    userPreferencesPage.setConfiguration(configuration)
    userPreferencesPage.setName(result[u'Name'])
    userPreferencesPage.setImage(API().getUserArtwork(result,"Primary"))
    
    userPreferencesPage.doModal()
    if userPreferencesPage.isSave():
        url = "{server}/mediabrowser/Users/{UserId}/Configuration"
        postdata = userPreferencesPage.getConfiguration()
        doUtils.downloadUrl(url, postBody=postdata, type="POST")

##### BROWSE EMBY CHANNELS #####    
def BrowseChannels(id, folderid=None):
    
    _addon_id   =   int(sys.argv[1])
    _addon_url  =   sys.argv[0]
    
    xbmcplugin.setContent(int(sys.argv[1]), 'files')
    if folderid:
        url = "{server}/mediabrowser/Channels/" + id + "/Items?userid={UserId}&folderid=" + folderid + "&format=json"
    else:
        if id == "0": # id 0 is the root channels folder
            url = "{server}/mediabrowser/Channels?{UserId}&format=json"
        else:
            url = "{server}/mediabrowser/Channels/" + id + "/Items?userid={UserId}&format=json"

    results = DownloadUtils().downloadUrl(url)
    if results:
        result = results.get("Items")
        if(result == None):
            result = []

        item_count = len(result)
        current_item = 1;
            
        for item in result:
            id=str(item.get("Id")).encode('utf-8')
            type=item.get("Type").encode('utf-8')
            
            
            if(item.get("Name") != None):
                tempTitle = item.get("Name")
                tempTitle=tempTitle.encode('utf-8')
            else:
                tempTitle = "Missing Title"
                
            if type=="ChannelFolderItem":
                isFolder = True
            else:
                isFolder = False
            item_type = str(type).encode('utf-8')
            
            if(item.get("ChannelId") != None):
               channelId = str(item.get("ChannelId")).encode('utf-8')
            
            channelName = ''   
            if(item.get("ChannelName") != None):
               channelName = item.get("ChannelName").encode('utf-8')   
               
            if(item.get("PremiereDate") != None):
                premieredatelist = (item.get("PremiereDate")).split("T")
                premieredate = premieredatelist[0]
            else:
                premieredate = ""
            
            #mediaStreams=API().getMediaStreams(item, True)
                    
            #people = API().getPeople(item)
            
            # Process Genres
            genre = API().getGenre(item)
                    
            # Process UserData
            userData = item.get("UserData")
            PlaybackPositionTicks = '100'
            overlay = "0"
            favorite = "False"
            seekTime = 0
            if(userData != None):
                if userData.get("Played") != True:
                    overlay = "7"
                    watched = "true"
                else:
                    overlay = "6"
                    watched = "false"
                if userData.get("IsFavorite") == True:
                    overlay = "5"
                    favorite = "True"
                else:
                    favorite = "False"
                if userData.get("PlaybackPositionTicks") != None:
                    PlaybackPositionTicks = str(userData.get("PlaybackPositionTicks"))
                    reasonableTicks = int(userData.get("PlaybackPositionTicks")) / 1000
                    seekTime = reasonableTicks / 10000
            
            playCount = 0
            if(userData != None and userData.get("Played") == True):
                playCount = 1
            # Populate the details list
            details={'title'        : tempTitle,
                     'channelname'  : channelName,
                     'plot'         : item.get("Overview"),
                     'Overlay'      : overlay,
                     'playcount'    : str(playCount)}
            
            if item.get("Type") == "ChannelVideoItem":
                xbmcplugin.setContent(_addon_id, 'movies')
            elif item.get("Type") == "ChannelAudioItem":
                xbmcplugin.setContent(_addon_id, 'songs')

            # Populate the extraData list
            extraData={'thumb'        : API().getArtwork(item, "Primary")  ,
                       'fanart_image' : API().getArtwork(item, "Backdrop") ,
                       'poster'       : API().getArtwork(item, "poster") , 
                       'tvshow.poster': API().getArtwork(item, "tvshow.poster") ,
                       'banner'       : API().getArtwork(item, "Banner") ,
                       'clearlogo'    : API().getArtwork(item, "Logo") ,
                       'discart'      : API().getArtwork(item, "Disc") ,
                       'clearart'     : API().getArtwork(item, "Art") ,
                       'landscape'    : API().getArtwork(item, "Thumb") ,
                       'id'           : id ,
                       'rating'       : item.get("CommunityRating"),
                       'year'         : item.get("ProductionYear"),
                       'premieredate' : premieredate,
                       'genre'        : genre,
                       'playcount'    : str(playCount),
                       'itemtype'     : item_type}
                       
            if extraData['thumb'] == '':
                extraData['thumb'] = extraData['fanart_image']
                
            liz = xbmcgui.ListItem(tempTitle)

            artTypes=['poster', 'tvshow.poster', 'fanart_image', 'clearlogo', 'discart', 'banner', 'clearart', 'landscape', 'small_poster', 'tiny_poster', 'medium_poster','small_fanartimage', 'medium_fanartimage', 'medium_landscape', 'fanart_noindicators']
            
            for artType in artTypes:
                imagePath=str(extraData.get(artType,''))
                liz=PlaybackUtils().setArt(liz,artType, imagePath)
            
            liz.setThumbnailImage(API().getArtwork(item, "Primary"))
            liz.setIconImage('DefaultTVShows.png')
            #liz.setInfo( type="Video", infoLabels={ "Rating": item.get("CommunityRating") })
            #liz.setInfo( type="Video", infoLabels={ "Plot": item.get("Overview") })
            
            if type=="Channel":
                file = _addon_url + "?id=%s&mode=channels"%id
                xbmcplugin.addDirectoryItem(handle=_addon_id, url=file, listitem=liz, isFolder=True)
            
            elif isFolder == True:
                file = _addon_url + "?id=%s&mode=channelsfolder&folderid=%s" %(channelId, id)
                xbmcplugin.addDirectoryItem(handle=_addon_id, url=file, listitem=liz, isFolder=True)
            else:
                file = _addon_url + "?id=%s&mode=play"%id
                liz.setProperty('IsPlayable', 'true')
                xbmcplugin.addDirectoryItem(handle=_addon_id, url=file, listitem=liz)

    xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))

##### GET NEXTUP EPISODES FOR TAGNAME #####    
def getNextUpEpisodes(tagname,limit):
    count=0

    #if the addon is called with nextup parameter, we return the nextepisodes list of the given tagname
    xbmcplugin.setContent(int(sys.argv[1]), 'episodes')
    # First we get a list of all the in-progress TV shows - filtered by tag
    json_query_string = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": { "sort": { "order": "descending", "method": "lastplayed" }, "filter": {"and": [{"operator":"true", "field":"inprogress", "value":""}, {"operator": "contains", "field": "tag", "value": "%s"}]}, "properties": [ "title", "studio", "mpaa", "file", "art" ]  }, "id": "libTvShows"}' %tagname)
    
    json_result = json.loads(json_query_string)
    # If we found any, find the oldest unwatched show for each one.
    if json_result.has_key('result') and json_result['result'].has_key('tvshows'):
        for item in json_result['result']['tvshows']:

            # If Ignore Specials is true only choose episodes from seasons greater than 0.
            if utils.settings("ignoreSpecialsNextEpisodes")=="true":
                json_query2 = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": { "tvshowid": %d, "sort": {"method":"episode"}, "filter": {"and": [ {"field": "playcount", "operator": "lessthan", "value":"1"}, {"field": "season", "operator": "greaterthan", "value": "0"} ]}, "properties": [ "title", "playcount", "season", "episode", "showtitle", "plot", "file", "rating", "resume", "tvshowid", "art", "streamdetails", "firstaired", "runtime", "writer", "dateadded", "lastplayed" ], "limits":{"end":1}}, "id": "1"}' %item['tvshowid'])
            else:
                json_query2 = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": { "tvshowid": %d, "sort": {"method":"episode"}, "filter": {"field": "playcount", "operator": "lessthan", "value":"1"}, "properties": [ "title", "playcount", "season", "episode", "showtitle", "plot", "file", "rating", "resume", "tvshowid", "art", "streamdetails", "firstaired", "runtime", "writer", "dateadded", "lastplayed" ], "limits":{"end":1}}, "id": "1"}' %item['tvshowid'])

            if json_query2:
                json_query2 = json.loads(json_query2)
                if json_query2.has_key('result') and json_query2['result'].has_key('episodes'):
                    for item in json_query2['result']['episodes']:
                        liz = createListItem(item)
                        xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=item['file'], listitem=liz)
                        count +=1
            if count == limit:
                break
    xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))

def getInProgressEpisodes(tagname,limit):
    count = 0
    #if the addon is called with inprogressepisodes parameter, we return the inprogressepisodes list of the given tagname
    xbmcplugin.setContent(int(sys.argv[1]), 'episodes')
    # First we get a list of all the in-progress TV shows - filtered by tag
    json_query_string = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": { "sort": { "order": "descending", "method": "lastplayed" }, "filter": {"and": [{"operator":"true", "field":"inprogress", "value":""}, {"operator": "contains", "field": "tag", "value": "%s"}]}, "properties": [ "title", "studio", "mpaa", "file", "art" ]  }, "id": "libTvShows"}' %tagname)
    json_result = json.loads(json_query_string)
    # If we found any, find all in progress episodes for each one.
    if json_result.has_key('result') and json_result['result'].has_key('tvshows'):
        for item in json_result['result']['tvshows']:
            json_query2 = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": { "tvshowid": %d, "sort": {"method":"episode"}, "filter": {"field": "inprogress", "operator": "true", "value":""}, "properties": [ "title", "playcount", "season", "episode", "showtitle", "plot", "file", "rating", "resume", "tvshowid", "art", "cast", "streamdetails", "firstaired", "runtime", "writer", "dateadded", "lastplayed" ]}, "id": "1"}' %item['tvshowid'])

            if json_query2:
                json_query2 = json.loads(json_query2)
                if json_query2.has_key('result') and json_query2['result'].has_key('episodes'):
                    for item in json_query2['result']['episodes']:
                        liz = createListItem(item)
                        xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=item['file'], listitem=liz)
                        count +=1
            if count == limit:
                break
    xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))

def getRecentEpisodes(tagname,limit):
    #if the addon is called with recentepisodes parameter, we return the recentepisodes list of the given tagname
    xbmcplugin.setContent(int(sys.argv[1]), 'episodes')
    # First we get a list of all the TV shows - filtered by tag
    json_query_string = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": { "sort": { "order": "descending", "method": "dateadded" }, "properties": [ "title","sorttitle" ], "filter": {"operator": "contains", "field": "tag", "value": "%s"} }, "id": "libTvShows"}' %tagname)    
    json_result = json.loads(json_query_string)
    
    # If we found any, put all tv show id's in a list
    if json_result.has_key('result') and json_result['result'].has_key('tvshows'):
        alltvshowIds = list()
        for tvshow in json_result['result']['tvshows']:
            alltvshowIds.append(tvshow["tvshowid"])
        alltvshowIds = set(alltvshowIds)
        
        #get all recently added episodes
        json_query2 = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": { "sort": {"order": "descending", "method": "dateadded"}, "filter": {"field": "playcount", "operator": "lessthan", "value":"1"}, "properties": [ "title", "playcount", "season", "episode", "showtitle", "plot", "file", "rating", "resume", "tvshowid", "art", "streamdetails", "firstaired", "runtime", "cast", "writer", "dateadded", "lastplayed" ]}, "limits":{"end":%d}, "id": "1"}' %limit)
        count = 0
        if json_query2:
            json_query2 = json.loads(json_query2)
            if json_query2.has_key('result') and json_query2['result'].has_key('episodes'):
                for item in json_query2['result']['episodes']:
                    if item["tvshowid"] in alltvshowIds:
                        liz = createListItem(item)
                        xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=item['file'], listitem=liz)
                        count += 1
                    if count == limit:
                        break
    xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
    
def createListItem(item):
       
    liz = xbmcgui.ListItem(item['title'])
    liz.setInfo( type="Video", infoLabels={ "Title": item['title'] })
    liz.setProperty('IsPlayable', 'true')
    liz.setInfo( type="Video", infoLabels={ "duration": str(item['runtime']/60) })
    
    if "episode" in item:
        episode = "%.2d" % float(item['episode'])
        liz.setInfo( type="Video", infoLabels={ "Episode": item['episode'] })
    
    if "season" in item:
        season = "%.2d" % float(item['season'])
        liz.setInfo( type="Video", infoLabels={ "Season": item['season'] })
        
    if season and episode:
        episodeno = "s%se%s" %(season,episode)
        liz.setProperty("episodeno", episodeno)
        
    if "firstaired" in item:
        liz.setInfo( type="Video", infoLabels={ "Premiered": item['firstaired'] })
    
    plot = item['plot']
    liz.setInfo( type="Video", infoLabels={ "Plot": plot })
    
    if "showtitle" in item:
        liz.setInfo( type="Video", infoLabels={ "TVshowTitle": item['showtitle'] })
    
    if "rating" in item:
        liz.setInfo( type="Video", infoLabels={ "Rating": str(round(float(item['rating']),1)) })
    liz.setInfo( type="Video", infoLabels={ "Playcount": item['playcount'] })
    if "director" in item:
        liz.setInfo( type="Video", infoLabels={ "Director": " / ".join(item['director']) })
    if "writer" in item:
        liz.setInfo( type="Video", infoLabels={ "Writer": " / ".join(item['writer']) })
        
    if "cast" in item:
        listCast = []
        listCastAndRole = []
        for castmember in item["cast"]:
            listCast.append( castmember["name"] )
            listCastAndRole.append( (castmember["name"], castmember["role"]) ) 
        cast = [listCast, listCastAndRole]
        liz.setInfo( type="Video", infoLabels={ "Cast": cast[0] })
        liz.setInfo( type="Video", infoLabels={ "CastAndRole": cast[1] })
    
    liz.setProperty("resumetime", str(item['resume']['position']))
    liz.setProperty("totaltime", str(item['resume']['total']))
    liz.setArt(item['art'])
    liz.setThumbnailImage(item['art'].get('thumb',''))
    liz.setIconImage('DefaultTVShows.png')
    liz.setProperty("dbid", str(item['episodeid']))
    liz.setProperty("fanart_image", item['art'].get('tvshow.fanart',''))
    for key, value in item['streamdetails'].iteritems():
        for stream in value:
            liz.addStreamInfo( key, stream )
    
    return liz
    
##### GET EXTRAFANART FOR LISTITEM #####
def getExtraFanArt():
    itemPath = ""
    embyId = ""
    
    #get extrafanart for listitem - this will only be used for skins that actually call the listitem's path + fanart dir... 
    try:
        #only do this if the listitem has actually changed
        itemPath = xbmc.getInfoLabel("ListItem.FileNameAndPath")
            
        if not itemPath:
            itemPath = xbmc.getInfoLabel("ListItem.Path")
        
        if ("/tvshows/" in itemPath or "/musicvideos/" in itemPath or "/movies/" in itemPath):
            embyId = itemPath.split("/")[-2]
            
            utils.logMsg("%s %s" % ("Emby addon", "getExtraFanArt"), "requesting extraFanArt for Id: " + embyId, 1)

            #we need to store the images locally for this to work because of the caching system in xbmc
            fanartDir = xbmc.translatePath("special://thumbnails/emby/" + embyId + "/")
            
            if not xbmcvfs.exists(fanartDir):
                #download the images to the cache directory
                xbmcvfs.mkdir(fanartDir)
                item = ReadEmbyDB().getFullItem(embyId)
                if item != None:
                    if item.has_key("BackdropImageTags"):
                        if(len(item["BackdropImageTags"]) > 0):
                            WINDOW = xbmcgui.Window(10000)
                            username = WINDOW.getProperty('currUser')
                            server = WINDOW.getProperty('server%s' % username)
                            totalbackdrops = len(item["BackdropImageTags"])
                            count = 0
                            for backdrop in item["BackdropImageTags"]: 
                                backgroundUrl = "%s/mediabrowser/Items/%s/Images/Backdrop/%s/?MaxWidth=10000&MaxHeight=10000&Format=original&Tag=%s&EnableImageEnhancers=false" % (server, embyId, str(count), backdrop)
                                count += 1
                                fanartFile = os.path.join(fanartDir,"fanart" + backdrop + ".jpg")
                                li = xbmcgui.ListItem(backdrop, path=fanartFile)
                                xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=fanartFile, listitem=li)
                                xbmcvfs.copy(backgroundUrl,fanartFile) 
                
            else:
                #use existing cached images
                dirs, files = xbmcvfs.listdir(fanartDir)
                count = 1
                for file in files:
                    count +=1
                    li = xbmcgui.ListItem(file, path=os.path.join(fanartDir,file))
                    xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=os.path.join(fanartDir,file), listitem=li)
    except Exception as e:
        utils.logMsg("%s %s" % ("Emby addon", "Error in getExtraFanArt"), str(e), 1)
        pass
    
    #always do endofdirectory to prevent errors in the logs
    xbmcplugin.endOfDirectory(int(sys.argv[1]))

def addDirectoryItem(label, path, folder=True):
    li = xbmcgui.ListItem(label, path=path)
    li.setThumbnailImage("special://home/addons/plugin.video.emby/icon.png")
    li.setArt({"fanart":"special://home/addons/plugin.video.emby/fanart.jpg"})
    li.setArt({"landscape":"special://home/addons/plugin.video.emby/fanart.jpg"})
    xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]), url=path, listitem=li, isFolder=folder)    
    
# if the addon is called without parameters we show the listing...    
def doMainListing():
    
    xbmcplugin.setContent(int(sys.argv[1]), 'files')    
    #get emby nodes from the window props
    embyProperty = WINDOW.getProperty("Emby.nodes.total")
    if embyProperty:
        totalNodes = int(embyProperty)
        for i in range(totalNodes):
            path = WINDOW.getProperty("Emby.nodes.%s.index" %str(i))
            if not path:
                path = WINDOW.getProperty("Emby.nodes.%s.content" %str(i))
            label = WINDOW.getProperty("Emby.nodes.%s.title" %str(i))
            if path:
                addDirectoryItem(label, path)
    
    # some extra entries for settings and stuff. TODO --> localize the labels
    addDirectoryItem("Settings", "plugin://plugin.video.emby/?mode=settings")
    addDirectoryItem("Perform manual sync", "plugin://plugin.video.emby/?mode=manualsync")
    addDirectoryItem("Add user to session", "plugin://plugin.video.emby/?mode=adduser")
    addDirectoryItem("Configure user preferences", "plugin://plugin.video.emby/?mode=userprefs")
    addDirectoryItem("Perform local database reset (full resync)", "plugin://plugin.video.emby/?mode=reset")
    addDirectoryItem("Cache all images to Kodi texture cache (advanced)", "plugin://plugin.video.emby/?mode=texturecache")
    addDirectoryItem("Sync Emby Theme Media to Kodi", "plugin://plugin.video.emby/?mode=thememedia")
    
    xbmcplugin.endOfDirectory(int(sys.argv[1]))