################XBMCScripts Installer v1.0################
#Last updated: August 8th 2005                           #
##########################################################                                                        
#Credits:
#Main script and graphics: EnderW (enderw@xbmscripts.com)
#Modules:
#   CachedHTTP: Aslak Grinsted / Phunck (ag@phunck.com)
#
#
#Visit http://www.xbmcscripts.com for help and updates on
#this script.
##########################################################

import os, xbmc, xbmcgui, sys, time
try:
   del sys.modules['xbmcscripts_core']
except:
   pass
sys.path.append(sys.path[0] + '\\lib')
import xbmcscripts_core as core
import cachedhttp
import threading

core.DEBUGMODE = 1
core.settings.showfolder = 1


#Assigning local names to core objects

msg = core.msg
error = core.error

#Functions
printDebug = core.printDebug #Prints debug data


XML = core.ParseXML()
ScriptPath = sys.path[0]+'\\'

printDebug(msg, 'Local script path: ' + str(ScriptPath))

def convert_date(datetuple):
    writetime = time.strftime('%m/%d', datetuple)
    return writetime

class GUI(xbmcgui.Window):
    def __init__(self):
        self.setCoordinateResolution(6)
        self.w = 720
        self.h = 576
        self.midx = self.w / 2
        self.midy = self.h / 2
        #self.locallist = XML.parselocal()
        self.init_installer()
        
    def init_installer(self):
        button_normal = ScriptPath + 'gfx\\button_nor.png'
        button_hl = ScriptPath + 'gfx\\button_hl.png'
        self.statrun = 0
        self.sitedata = XML.parsesite(self.callback)
        self.catactive = 0
        self.animrunning = 0
        self.closing = 0
        
        self.categories = [ ('Communication' , 21) , ('Other' , 28) , ('Media: Other' , 18) , ('Media: Streaming' , 14) ,
        ('News' , 22) , ('TV-Guides' , 15)]
        
        self.make_categories()
        
            
        self.gfxbg = xbmcgui.ControlImage(0, 0, 720, 576, ScriptPath + "gfx\\bg.png")
        self.addControl(self.gfxbg)
        self.gfxtop = xbmcgui.ControlImage(0, 0, 720, 89, ScriptPath + "gfx\\top.png")
        self.addControl(self.gfxtop)
        self.gfxbottom = xbmcgui.ControlImage(0, self.h - 86, 720, 86, ScriptPath + "gfx\\bottom.png")
        self.addControl(self.gfxbottom)
        self.gfxbarbg= xbmcgui.ControlImage(int((self.w - 652)/2), int(self.h - 86 / 2 - 19 / 2), 652, 19, ScriptPath + "gfx\\bar_grey.png")
        self.addControl(self.gfxbarbg)
        self.gfxbar= xbmcgui.ControlImage(int((self.w - 652)/2), int(self.h - 86 / 2 - 19 / 2), 652, 19, ScriptPath + "gfx\\bar_green.png")
        self.addControl(self.gfxbar)
        self.xbutton = xbmcgui.ControlImage(53, 350, 21, 21, ScriptPath + "gfx\\xbutton.png")
        self.addControl(self.xbutton)
        self.xtext = xbmcgui.ControlLabel(77, 353, 300, 50, 'Change focus', 'font10')
        self.addControl(self.xtext)
        self.cat1 = xbmcgui.ControlButton(50, 120, 191, 30, 'Latest additions', button_hl, button_normal, 30, 2 , 0 , 'font14')
        self.addControl(self.cat1)        
        self.cat2 = xbmcgui.ControlButton(50, 150, 191, 30, 'Communication', button_hl, button_normal, 30, 2 , 0 , 'font14')
        self.addControl(self.cat2)
        self.cat3 = xbmcgui.ControlButton(50, 180, 191, 30, 'Other', button_hl, button_normal, 30, 2 , 0 , 'font14')
        self.addControl(self.cat3)
        self.cat4 = xbmcgui.ControlButton(50, 210, 191, 30, 'Media: Other', button_hl, button_normal, 30, 2 , 0 , 'font14')
        self.addControl(self.cat4)        
        self.cat5 = xbmcgui.ControlButton(50, 240, 191, 30, 'Media: Streaming', button_hl, button_normal, 30, 2 , 0 , 'font14')
        self.addControl(self.cat5)
        self.cat6 = xbmcgui.ControlButton(50, 270, 191, 30, 'News', button_hl, button_normal, 30, 2 , 0 , 'font14')
        self.addControl(self.cat6)
        self.cat7 = xbmcgui.ControlButton(50, 300, 191, 30, 'TV-Guides', button_hl, button_normal, 30, 2 , 0 , 'font14')
        self.addControl(self.cat7)
        
        
        
        self.statusbar= xbmcgui.ControlImage(-263, 440, 263, 45, ScriptPath + "gfx\\statusbar.png")
        self.addControl(self.statusbar)
        self.statustext= xbmcgui.ControlLabel(50, 450, 263, 45, "", "font14")
        self.addControl(self.statustext)
        
        
        self.list = xbmcgui.ControlList(270,90,380,230)
        self.title = xbmcgui.ControlLabel(180, 150, 350, 50, "" , "font14") 
        self.descbox = xbmcgui.ControlTextBox(280, 325, 370, 175, "font14") 
        self.addControl(self.title)
        self.addControl(self.list)
        self.addControl(self.descbox)
        self.setFocus(self.cat1)
        
        
        #Movement
        self.cat1.controlRight(self.list)
        self.cat1.controlUp(self.cat7)
        self.cat1.controlDown(self.cat2)
        
        self.cat2.controlRight(self.list)
        self.cat2.controlUp(self.cat1)
        self.cat2.controlDown(self.cat3)
        
        self.cat3.controlRight(self.list)
        self.cat3.controlUp(self.cat2)
        self.cat3.controlDown(self.cat4)
        
        self.cat4.controlRight(self.list)
        self.cat4.controlUp(self.cat3)
        self.cat4.controlDown(self.cat5)
        
        self.cat5.controlRight(self.list)
        self.cat5.controlUp(self.cat4)
        self.cat5.controlDown(self.cat6)
        
        self.cat6.controlRight(self.list)
        self.cat6.controlUp(self.cat5)
        self.cat6.controlDown(self.cat7)
        
        
        self.cat7.controlRight(self.list)
        self.cat7.controlUp(self.cat6)
        self.cat7.controlDown(self.cat1)
        
        
        self.list.controlLeft(self.cat1)
        self.showcat(0)
        
    def showcat(self, category):
        self.list.reset()
            
            
        self.catactive = int(category)
        for item in self.catdata[int(category)]:
            listitem = xbmcgui.ListItem()
            listitem.setLabel(str(item['name']))
            listitem.setLabel2(str(convert_date(item['date'])))
            self.list.addItem(listitem)
    
    def make_categories(self):
        self.catdata = []
        datelist = []
        for x in self.sitedata:
            datelist.append((x['date'], x))
        #Sort the script list by newest first:
        datelist.sort(lambda x, y: cmp(y, x))
        latest = []
        #Add only the ten newest:
        for date, item in datelist[:10]:
            latest.append(item)
        self.catdata.append(latest)
        #self.catdata now contain the "Latest additions" category. Now we add the rest of the categories:
        for x in self.categories:
            self.tempcat = []
            #Running through all scripts in self.sitedata seeing if the category we ask for, x[1], matches the dictionary key (an integer):
            for item in self.sitedata:
                if int(item['category']) == x[1]:
                    self.tempcat.append(item)
            self.catdata.append(self.tempcat)
        
            
    #callback handles the percentage got from CachedHTTP in xbmcscripts_core and whether it's downloading or done downloading.
    #It is called from CachedHTTP everytime data is received.
    def callback(self, state, pct):
        if state == 'dl':
            self.statustext.setLabel("Downloading: " + str(pct) + '%')
            self.gfxbar.setPosition( int(((self.w - 652) / 2) - 652 + ((652 / 100) * pct)), int(self.h - 86 / 2 - 19 / 2))
        elif state == 'done':
            self.statustext.setLabel('Installing...')
            
    #Checks whether an animation is already running, if not, then run it:
    def movestatus(self, direction):
        if self.statrun == 0:
            self.statrun = 1
            self.statusmove = StatusMove(self, direction)
            self.statusmove.start()
            
    #Statusbar animation positions:
    def statusin(self, num):
        x = -245 + int(((263 / 19) * num))
        self.statusbar.setPosition(x, 440)
        self.statustext.setPosition(x + 50, 450)
        
    def statusout(self, num):
        x = 0 - int(((263 / 19) * num))
        self.statusbar.setPosition(x, 440)
        
        self.statustext.setPosition(x + 50, 450)  
    
    #This one shouldn't require any information :)
    def onAction(self, action):
        if action == 10:
            if self.animrunning == 1:
                pass
            else:
                self.closing = 1
                self.close()
        elif action == 3 or action == 4 or action == 111 or action == 112:
            if self.getFocus() == self.list:
                time.sleep(0.01)
                self.descbox.setText(self.catdata[self.catactive][self.list.getSelectedPosition()]['description'])
        if action == 18:
            if self.getFocus() == self.descbox:
                self.setFocus(self.list)
            else:
                self.setFocus(self.descbox)
                
    def onControl(self, control):
        if control == self.list:
            id = self.catdata[self.catactive][self.list.getSelectedPosition()]['id']
            
            self.statustext.setLabel("Contacting site...")
            self.movestatus('in')
            try: self.removeControl(self.gfxbar)
            except: pass
            try:
                #Position the progress bar out of sight:
                self.gfxbar= xbmcgui.ControlImage(-652, int(self.h - 86 / 2 - 19 / 2), 652, 19, ScriptPath + "gfx\\bar_orange.png")
                self.addControl(self.gfxbar)
            except:
                pass
            if core.install('http://www.xbmcscripts.com/modules/mod_docman/includes_frontend/index.php?option=com_docman&task=doc_download&gid=' + id, self.callback, self.sitedata[self.list.getSelectedPosition()]) == True:
                self.statustext.setLabel("Installation complete!")
            #If installation fails, false is returned:
            else:
                self.statustext.setLabel("Couldn't install script")
            try: self.removeControl(self.gfxbar)
            except: pass
            #Last we display green bar at idle position:
            try:
                self.gfxbar= xbmcgui.ControlImage(int((self.w - 652)/2), int(self.h - 86 / 2 - 19 / 2), 652, 19, ScriptPath + "gfx\\bar_green.png")
                self.addControl(self.gfxbar)
            except:
                pass
            
            self.movestatus('out')
        elif control == self.cat1:
            self.showcat(0)
        elif control == self.cat2:
            self.showcat(1)
        elif control == self.cat3:
            self.showcat(2)
        elif control == self.cat4:
            self.showcat(3)
        elif control == self.cat5:
            self.showcat(4)
        elif control == self.cat6:
            self.showcat(5)
        elif control == self.cat7:
            self.showcat(6)





        

class StatusMove(threading.Thread):
    def __init__(self, instance, direction):
        threading.Thread.__init__(self)
        self.gui = instance
        self.direction = direction

    def run(self):
        if self.gui.closing != 1:
            self.gui.animrunning = 1
            if self.direction == 'out':
                time.sleep(4)
            for x in range(20):
                if self.direction == 'in':
                    self.gui.statusin(x)
                if self.direction == 'out':
                    self.gui.statusout(x)
                time.sleep(0.01)
            self.gui.statrun = 0
            self.gui.animrunning = 0

gui = GUI()
gui.doModal()
del gui