# coding=utf-8
import os, sys, datetime, unicodedata, re
import xbmc, xbmcgui, xbmcvfs, xbmcaddon
import xml.etree.ElementTree as xmltree
from xml.sax.saxutils import escape as escapeXML
import copy
import ast
from traceback import print_exc
from unicodeutils import try_decode

if sys.version_info < (2, 7):
    import simplejson
else:
    import json as simplejson

__addon__        = xbmcaddon.Addon()
__addonid__      = sys.modules[ "__main__" ].__addonid__
__addonversion__ = __addon__.getAddonInfo('version')
__xbmcversion__  = xbmc.getInfoLabel( "System.BuildVersion" ).split(".")[0]
__datapath__     = os.path.join( xbmc.translatePath( "special://profile/addon_data/" ).decode('utf-8'), __addonid__ ).encode('utf-8')
__masterpath__     = os.path.join( xbmc.translatePath( "special://masterprofile/addon_data/" ).decode('utf-8'), __addonid__ ).encode('utf-8')
__skin__         = xbmc.translatePath( "special://skin/" )    
__language__     = __addon__.getLocalizedString

import datafunctions, template
DATA = datafunctions.DataFunctions()
import hashlib, hashlist

def log(txt):
    if __addon__.getSetting( "enable_logging" ) == "true":
        if isinstance (txt,str):
            txt = txt.decode('utf-8')
        message = u'%s: %s' % (__addonid__, txt)
        xbmc.log(msg=message.encode('utf-8'), level=xbmc.LOGDEBUG)
    
class XMLFunctions():
    def __init__(self):
        self.MAINWIDGET = {}
        self.MAINBACKGROUND = {}
        self.MAINPROPERTIES = {}
        self.hasSettings = False
        self.widgetCount = 1

        self.skinDir = xbmc.translatePath( "special://skin" )
        
        self.checkForShorctcuts = []
        
    def buildMenu( self, mainmenuID, groups, numLevels, buildMode, options, minitems, weEnabledSystemDebug = False, weEnabledScriptDebug = False ): 
        # Entry point for building includes.xml files
        if xbmcgui.Window( 10000 ).getProperty( "skinshortcuts-isrunning" ) == "True":
            return
        
        xbmcgui.Window( 10000 ).setProperty( "skinshortcuts-isrunning", "True" )
 
        # Get a list of profiles
        fav_file = xbmc.translatePath( 'special://userdata/profiles.xml' ).decode("utf-8")
        tree = None
        if xbmcvfs.exists( fav_file ):
            f = xbmcvfs.File( fav_file )
            tree = xmltree.fromstring( f.read() )
        
        profilelist = []
        if tree is not None:
            profiles = tree.findall( "profile" )
            for profile in profiles:
                name = profile.find( "name" ).text.encode( "utf-8" )
                dir = profile.find( "directory" ).text.encode( "utf-8" )
                log( "Profile found: " + name + " (" + dir + ")" )
                # Localise the directory
                if "://" in dir:
                    dir = xbmc.translatePath( dir ).decode( "utf-8" )
                else:
                    # Base if off of the master profile
                    dir = xbmc.translatePath( os.path.join( "special://masterprofile", dir ) ).decode( "utf-8" )
                profilelist.append( [ dir, "StringCompare(System.ProfileName," + name.decode( "utf-8" ) + ")", name.decode( "utf-8" ) ] )
                
        else:
            profilelist = [["special://masterprofile", None]]
 
        if self.shouldwerun( profilelist ) 
== False:
            log( "Menu is up to date" )
            xbmcgui.Window( 10000 ).clearProperty( "skinshortcuts-isrunning" )
            return

        progress = None
        # Create a progress dialog
        progress = xbmcgui.DialogProgressBG()
        progress.create(__addon__.getAddonInfo( "name" ), __language__( 32049 ) )
        progress.update( 0 )
        
        # Write the menus
        try:
            self.writexml( profilelist, main
menuID, groups, numLevels, buildMode, progress, options, minitems )
            complete = True
        except:
            log( "Failed to write menu" )
            print_exc()
            complete = False
        
        # Mark that we're no longer running, clear the progress dialog
        xbmcgui.Window( 10000 ).clearProperty( "skinshortcuts-isrunning" )
        progress.close()
        
        if complete == True:
            # Menu is built, reload the skin
            xbmc.executebuiltin( "XBMC.ReloadSkin()" )
        else:
            # Menu couldn't be built - generate a debug log
        
            # If we enabled debug logging
            if weEnabledSystemDebug or weEnabledScriptDebug:
                # Disable any logging we enabled
                if weEnabledSystemDebug:
                    json_query = xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "id": 0, "method":"Settings.setSettingValue", "params": {"setting":"debug.showloginfo", "value":false} } ' )
                if weEnabledScriptDebug:
                    __addon__.setSetting( "enable_logging", "false" )
                    
                # Offer to upload a debug log
                if xbmc.getCondVisibility( "System.HasAddon( script.xbmc.debug.log )" ):
                    ret = xbmcgui.Dialog().yesno( __addon__.getAddonInfo( "name" ), __language__( 32092 ), __language__( 32093 ) )
                    if ret:
                        xbmc.executebuiltin( "RunScript(script.xbmc.debug.log)" )
                else:
                    xbmcgui.Dialog().ok( __addon__.getAddonInfo( "name" ), __language__( 32092 ), __language__( 32094 ) )
                    
            else:
                # Enable any debug logging needed                        
                json_query = xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "id": 0, "method": "Settings.getSettings" }')
                json_query = unicode(json_query, 'utf-8', errors='ignore')
                json_response = simplejson.loads(json_query)
                
                enabledSystemDebug = False
                enabledScriptDebug = False

                if json_response.has_key('result') and json_response['result'].has_key('settings') and json_response['result']['settings'] is not None:
                    for item in json_response['result']['settings']:
                        if item["id"] == "debug.showloginfo":
                            if item["value"] == False:
                                json_query = xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "id": 0, "method":"Settings.setSettingValue", "params": {"setting":"debug.showloginfo", "value":true} } ' )
                                enabledSystemDebug = True

                if __addon__.getSetting( "enable_logging" ) != "true":
                    __addon__.setSetting( "enable_logging", "true" )
                    enabledScriptDebug = True
                    
                if enabledSystemDebug or enabledScriptDebug:
                    # We enabled one or more of the debug options, re-run this function
                    self.buildMenu( mainmenuID, groups, numLevels, buildMode, options, minitems, enabledSystemDebug, enabledScriptDebug )
                else:
                    # Offer to upload a debug log
                    if xbmc.getCondVisibility( "System.HasAddon( script.xbmc.debug.log )" ):
                        ret = xbmcgui.Dialog().yesno( __addon__.getAddonInfo( "name" ), __language__( 32092 ), __language__( 32093 ) )
                        if ret:
                            xbmc.executebuiltin( "RunScript(script.xbmc.debug.log)" )
                    else:
                        xbmcgui.Dialog().ok( __addon__.getAddonInfo( "name" ), __language__( 32092 ), __language__( 32094 ) )
        
    def shouldwerun( self, profilelist ):
        try:
            property = xbmcgui.Window( 10000 ).getProperty( "skinshortcuts-reloadmainmenu" )
            xbmcgui.Window( 10000 ).clearProperty( "skinshortcuts-reloadmainmenu" )
            if property == "True":
                log( "Menu has been edited")
                return True
        except:
            pass
            
        # Get the skins addon.xml file
        addonpath = xbmc.translatePath( os.path.join( "special://skin/", 'addon.xml').encode("utf-8") ).decode("utf-8")
        addon = xmltree.parse( addonpath )
        extensionpoints = addon.findall( "extension" )
        