# -*- coding: utf-8 -*-
import urllib2
import urllib
import xml.dom.minidom
import os
import sys
import re
import random
import StringIO

from PyQt4 import *
from form import *
from PIL import Image, ImageFilter, ImageQt, ImageFont, ImageDraw

thisFilePath = os.path.dirname(os.path.abspath(sys.argv[0]))
serverString = "http://www.spore.com"
               
class MyForm(QtGui.QMainWindow):
    
    currentopen = ""
    opponentName = ""
    opponentId = ""
    idMap = ""
    nameMap = ""
        
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setWindowIcon(QtGui.QIcon('%s/eye.png' % thisFilePath))
        self.ui.progressBar.reset()
        [self.idMap, self.nameMap] = self.BuildIdNameMaps()
        self.loadOpponents()
                 
    def getAssetList(self):
        self.ui.listWidget_3.clear()
        playername = str(self.ui.lineEdit.text())
        if playername:
            ids = self.GetAssetIdsOfTypeForUser(playername, "CREATURE")
            for sporeId in ids:
                next = QtGui.QListWidgetItem()
                next.setText(sporeId.split(":")[1])
                next.setToolTip (sporeId.split(":")[0])
                self.ui.listWidget_3.addItem(next)
                
            buddylist = self.GetBuddiesForUser(playername)
            if buddylist:
                self.ui.radioButton_2.setEnabled(True)
                self.ui.label_7.setText("Buddies for player: %d" % len(buddylist))
            else:
                self.ui.radioButton_2.setEnabled(False)
                self.ui.label_7.setText("Buddies for player: %d" % 0)
        i=0
        while self.ui.listWidget_3.item(i):
            i=i+1
        if not i:
            self.ui.lineEdit.setText("player not found")
            self.ui.radioButton_2.setEnabled(False)
            self.ui.label_7.setText("Buddies for player: %d" % 0)
            
    def getRandomCreature(self):
        url = "http://www.spore.com/rest/assets/search/RANDOM/0/1/CREATURE"
        myxml = self.GetXMLForREST(url)
        ids = []
        if(myxml):
            ids = self.TryGetNodeValues(myxml, "id")
        return ids
        
    def getRandomPlayersCreature(self):
        playername = str(self.ui.lineEdit_3.text())
        if playername:
            ids = self.GetAssetIdsOfTypeForUser(playername, "CREATURE")
            return random.choice(ids)
        else:
            self.ui.lineEdit_3.setText("from who?")
    
    def GetBuddiesForUser(self, username):
        url = "http://www.spore.com/rest/users/buddies/" + username + "/0/5000"
        myxml = self.GetXMLForREST(url)
        buddyList = []
        if(myxml):
            buddyNodes = self.TryGetNodes(myxml, "name")# you can extend this to get other nodes
            for i in range(0, len(buddyNodes)):
                buddyList.append(buddyNodes[i].firstChild.nodeValue)
            myxml.unlink()
        return buddyList    
        
    def itemclick(self):
        selected = self.ui.listWidget.currentItem()
        info = selected.data(3)
        if not str(info.toString()) == self.currentopen:
            self.updatePic(str(info.toString()))
            
    def UnicodeString(self, inputStr):
        return unicode(inputStr, 'latin-1').encode('utf-8')
        
    def AssetsForUserURL(self, username, start, length):
        return serverString + "/rest/assets/user/" + username + "/" + str(start) + "/" + str(length)
    
    def TryParseXML(self, xmlString):
        try:
            myxml = xml.dom.minidom.parseString(self.UnicodeString(xmlString))
            return myxml
        except:
            print("ERROR parsing XML")
            #raise
            return ""
            
    def TryOpenURL(self, url):
        #print "Getting " + url
        try:
            f = urllib2.urlopen(url)
            return f
        except:
            print("ERROR OPENING: " + url)
            return ""
            
    def TryGetNodes(self, xml, nodename):
        try:
            return xml.getElementsByTagName(nodename)
        except:
            print("ERROR XML Node: " + nodename)
            return ""
            
    def TryGetNodeValues(self, xml, nodename):
        nodes = []
        try:
            elems = xml.getElementsByTagName(nodename)
        except:
            print("ERROR XML NODE: " + nodename)
            return nodes
        
        for i in range(0, len(elems)):
            try:
                nodes.append(elems[i].firstChild.nodeValue)
            except:
                nodes.append("error retrieving")
        return nodes
            
    def GetXMLForREST(self, url):
        f = self.TryOpenURL(url)
        if(f):
            myxml = self.TryParseXML(f.read())
            return myxml
        else:
            return ""
            
    def GetAssetIdsOfTypeForUser(self, username, assettype):
        url = self.AssetsForUserURL(username, 0, 5000)
        myxml = self.GetXMLForREST(url)
        assetIds = []
        if(myxml):
            assetIdList = self.TryGetNodeValues(myxml, "id")
            modelTypeList = self.TryGetNodeValues(myxml, "type")
            nameTypeList = self.TryGetNodeValues(myxml, "name")
            for i in range(0, len(assetIdList)):
                if(modelTypeList[i] == assettype):
                    assetIds.append(assetIdList[i]+":"+nameTypeList[i])
            myxml.unlink()
        return assetIds
                
    def BuildIdNameMaps(self):
        url = "http://www.spore.com/data/blocks/creatureblockmap.xml"
        myxml = self.GetXMLForREST(url)
        idMap = {}
        nameMap = {}
        if(myxml):
            assetIdList = self.TryGetNodeValues(myxml, "id")
            modelTypeList = self.TryGetNodeValues(myxml, "filename")
            nameTypeList = self.TryGetNodeValues(myxml, "name")
            for i in range(0, len(assetIdList)):
                idMap[assetIdList[i]] = modelTypeList[i].lower()
                nameMap[modelTypeList[i]] = nameTypeList[i]
            myxml.unlink()
        return idMap,nameMap
        
    def LargeAssetURL(self, assetId):
        sub1 = assetId[0:3]
        sub2 = assetId[3:6]
        sub3 = assetId[6:9]
        return serverString + "/static/image/" + sub1 + "/" + sub2 + "/" + sub3 + "/" + assetId + "_lrg.png"
        
    def iconFromUrl(self, url):
        #print "getting icon from",url
        f = self.TryOpenURL(url)
        if f:
            output = StringIO.StringIO(f.read())
            pixmap = Image.open(output)
            iconImage = ImageQt.ImageQt(pixmap)
            output.close()
            return iconImage
        else:
            return ""
        
    def setActiveOpponent(self, widget):
        self.opponentName = str(widget.text())
        self.opponentId = str(widget.toolTip())
        if re.match('[a-zA-Z]+', self.opponentName):
            url = self.LargeAssetURL(self.opponentId)
            assetUrl = "http://www.spore.com/rest/asset/%s" % self.opponentId #500256958982 
            myxml = self.GetXMLForREST(assetUrl)
            assetAuthor = self.TryGetNodeValues(myxml, "author")
            if assetAuthor:
                self.ui.groupBox_2.setTitle("%s - created by: %s" % (self.opponentName, str(assetAuthor[0])))
            else:
                self.ui.groupBox_2.setTitle(self.opponentName)
            iconImage = self.iconFromUrl(url)
            pixmap = QtGui.QPixmap.fromImage(iconImage)  
            self.ui.label_3.setPixmap(pixmap)
            self.ui.label_3.setText("")
        else:
            self.ui.groupBox_2.setTitle(self.opponentName)
            self.ui.label_3.setText(QtGui.QApplication.translate("MainWindow",
            "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"+\
            "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"+\
            "p, li { white-space: pre-wrap; }\n"+\
            "</style></head><body style=\" font-family:\'MS Shell Dlg 2\';"+\
            "font-size:8.25pt; font-weight:400; font-style:normal;\">\n"+\
            "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;"+\
            "-qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:8pt;\">A Creature that already</span></p>\n"+\
            "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;"+\
            "-qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:8pt;\">uses these parts will be revealed</span></p>\n"+\
            "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;"+\
            "-qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:8pt;\">when you find or make one</span></p>\n"+\
            "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;"+\
            "-qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:8pt;\">useing the same parts.</span></p></body></html>",
            None, QtGui.QApplication.UnicodeUTF8))
        iconImage = ImageQt.ImageQt(Image.new("RGBA", (40,40), (0,0,0,0)))
        pixmap = QtGui.QPixmap.fromImage(iconImage) 
        self.ui.label_4.setPixmap(pixmap)
        self.ui.listWidget.clear()
        partsDic = self.getPartsForAsset(self.opponentId)
        if partsDic:
            i=0
            self.ui.progressBar.setMaximum(len(partsDic.keys()))
            for sporeId in partsDic.keys():
                i=i+1
                next = QtGui.QListWidgetItem()
                prettyName = "not found"
                count = 0
                if sporeId in self.nameMap.keys():
                    prettyName = self.nameMap[sporeId]
                    if sporeId in partsDic.keys():
                        count = partsDic[sporeId]
                        next.setText("%s (x%d)" % (prettyName, count))
                        url = "http://www.spore.com/data/blocks/thumbs/%s.png" % sporeId
                        icon = self.iconFromUrl(url)
                        pixmap = QtGui.QPixmap.fromImage(icon) 
                        next.setIcon(QtGui.QIcon(pixmap))
                        self.ui.listWidget.setIconSize(QtCore.QSize(50,50))
                        next.setToolTip(sporeId)
                        next.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled ) 
                        next.setCheckState(0) 
                        self.ui.listWidget.addItem(next)
                self.ui.progressBar.setValue(i)
            self.ui.progressBar.reset()
            if self.currentopen:
                self.compareParts(self.currentopen)
        
    def displaySelectedPart(self, widget):
        info = str(widget.toolTip())
        url = "http://www.spore.com/data/blocks/thumbs/%s.png" % info
        iconImage = self.iconFromUrl(url)
        pixmap = QtGui.QPixmap.fromImage(iconImage)  
        self.ui.label_4.setPixmap(pixmap)
        
    def addNewOpponent(self):
        if self.ui.radioButton_3.isChecked():
            ids = self.getRandomCreature()
            if ids:
                next = QtGui.QListWidgetItem()
                next.setText(str(ids[0]))
                next.setToolTip(str(ids[0]))
                self.ui.listWidget_2.addItem(next)    
        if self.ui.radioButton.isChecked():
            assetId = self.getRandomPlayersCreature()
            if assetId:
                [name,var] = assetId.split(":")
                next = QtGui.QListWidgetItem()
                next.setText(str(name))
                next.setToolTip(str(name))
                self.ui.listWidget_2.addItem(next)    
        if self.ui.radioButton_2.isChecked():
            playername = str(self.ui.lineEdit.text())
            if playername:
                buddylist = self.GetBuddiesForUser(playername)
                if buddylist:
                    buddy = random.choice(buddylist)
                    ids = self.GetAssetIdsOfTypeForUser(buddy, "CREATURE")
                    randId = random.choice(ids)
                    if str(randId) != None:
                        [name,var] = randId.split(":")
                        next = QtGui.QListWidgetItem()
                        next.setText(name)
                        next.setToolTip(name)
                        self.ui.listWidget_2.addItem(next)    
                else:
                    print "no buddies found for %s" % playername
            else:
                print "no player sepecified, who's buddies do you want?"
        self.saveOpponents()
    
    def saveOpponents(self):  
        outputFile = thisFilePath+"/data"
        data = []
        i=0
        while self.ui.listWidget_2.item(i):
            obj = self.ui.listWidget_2.item(i)
            name = str(obj.text())
            var = str(obj.toolTip())
            if not var in data:
                data.append(name+":"+var)
            i=i+1
                
        out_file = open(outputFile,"w")
        out_file.write("\n".join(data))
        out_file.close()
        
    def loadOpponents(self):
        outputFile = thisFilePath+"/data"
        if os.path.isfile(outputFile):
            data = []
            file = open(outputFile, 'r')
            info = file.readlines()
            file.close()
            for line in info:
                if line.strip() != "\n":
                    [name,var] = line.strip().split(":") 
                    next = QtGui.QListWidgetItem()
                    next.setText(name)
                    next.setToolTip(var)
                    self.ui.listWidget_2.addItem(next)        
    
    def loadPlayerAsset(self, widget):
        selected = self.ui.listWidget_3.currentItem()
        info = str(selected.toolTip())
        if not info == self.currentopen:
            self.currentopen = info
            url = self.LargeAssetURL(info)
            iconImage = self.iconFromUrl(url)
            pixmap = QtGui.QPixmap.fromImage(iconImage)  
            self.ui.label.setPixmap(pixmap)
            if self.compareParts(info):
                if self.opponentName:
                    opponent = str(self.opponentId)
                    assetUrl = "http://www.spore.com/rest/asset/%s" % opponent #500256958982
                    myxml = self.GetXMLForREST(assetUrl)
                    assetName = self.TryGetNodeValues(myxml, "name")
                    if assetName:
                        self.opponentName = str(assetName[0])
                        if not re.match('[a-zA-Z]+', opponent):
                            self.swapIdWithName(opponent, self.opponentName)
                    assetAuthor = self.TryGetNodeValues(myxml, "author")
                    if assetAuthor:
                        self.ui.groupBox_2.setTitle("%s - created by: %s" % (self.opponentName, str(assetAuthor[0])))
                    else:
                        self.ui.groupBox_2.setTitle(self.opponentName)
                    url = self.LargeAssetURL(opponent)
                    iconImage = self.iconFromUrl(url)
                    pixmap = QtGui.QPixmap.fromImage(iconImage)  
                    self.ui.label_3.setPixmap(pixmap)
                    self.ui.label_3.setText("")
                    self.saveOpponents()
                
    def swapIdWithName(self, assetId, assetName):
        saveThese = []
        i=0
        while self.ui.listWidget_2.item(i):
            obj = self.ui.listWidget_2.item(i)
            if not str(obj.text()) in [str(assetId),str(assetName)]:
                saveThese.append(str(obj.text())+":"+str(obj.toolTip()))
            i=i+1
        saveThese.append(assetName+":"+str(assetId))
        self.opponentName = str(assetName)
        self.opponentId = str(assetId)
        self.ui.listWidget_2.clear()
        for s in saveThese:
            [name,var] = s.strip().split(":") 
            next = QtGui.QListWidgetItem()
            next.setText(name)
            next.setToolTip(var)
            self.ui.listWidget_2.addItem(next)    
    
    def removeOpponent(self):
        selected = self.ui.listWidget_2.currentItem()
        killit = str(selected.text())
        saveThese = []
        i=0
        while self.ui.listWidget_2.item(i):
            obj = self.ui.listWidget_2.item(i)
            if not str(obj.text()) == killit:
                saveThese.append(str(obj.text())+":"+str(obj.toolTip()))
            i=i+1
        self.ui.listWidget_2.clear()
        for s in saveThese:
            [name,var] = s.strip().split(":") 
            next = QtGui.QListWidgetItem()
            next.setText(name)
            next.setToolTip(var)
            self.ui.listWidget_2.addItem(next)    
        self.opponentName = ""
        self.opponentId = ""
        self.saveOpponents()
            
    def getPartsForAsset(self, assetId):
        parts= []
        partsDic = {}
        skipme= []
        stringId = str(assetId)
        assetURL = "%s/static/model/%s/%s/%s/%s.xml" % (serverString,stringId[:3],stringId[3:6],stringId[6:9],stringId)
        assetxml = self.GetXMLForREST(assetURL)
        #find all blockid nodes and get the part after the ", "
        if assetxml:
            elems = assetxml.getElementsByTagName('blockid')
            self.ui.progressBar.setMaximum(len(elems))
            for i in range(0, len(elems)):
                node = elems[i].firstChild.nodeValue.split(", ")[-1]
                if not node in skipme:
                    if node in self.idMap.keys():
                        fileName = self.idMap[node]
                        if not fileName in parts:
                            parts.append(fileName)
                            partsDic[fileName] = 1
                        else:
                            partsDic[fileName] = partsDic[fileName] + 1
                    else:
                        skipme.append(node)
                self.ui.progressBar.setValue(i)
            self.ui.progressBar.reset()
            return partsDic
        
    def compareParts(self, assetId):
        partsDic = self.getPartsForAsset(assetId)
        i=0
        while self.ui.listWidget.item(i):
            obj = self.ui.listWidget.item(i)
            tt = str(obj.toolTip())
            txt = str(obj.text())
            if tt in partsDic.keys():
                if int(txt.split("(x")[1].split(")")[0]) <= int(partsDic[tt]):
                    obj.setCheckState(1) 
            else:
                obj.setCheckState(0) 
            i=i+1
        i=0
        win = True
        while self.ui.listWidget.item(i):
            obj = self.ui.listWidget.item(i)
            if not obj.checkState():
                win = False
            i=i+1
        if i == 0:
            return False
        return win
        
def launchApp():
    app = QtGui.QApplication(sys.argv)
    app.setStyle("plastique")
    myapp = MyForm()
    myapp.show()
    sys.exit(app.exec_())
    
if __name__ == "__main__":
    launchApp()
