# Time-stamp: <2002-03-20 19:12:18 crabbkw>
# Code and design by Casey Crabb (crabbkw@rose-hulman.edu)
# This code is licensed under the BSD license.
# See the LICENSE file for details
#
# Copyright Casey Crabb (crabbkw@rose-hulman.edu) July 2001
#


# from __future__ import nested_scopes
try:
    from xml.parsers import expat
except:
    from xml.parsers import pyexpat
    expat = pyexpat
import os
import string
import pprint

pp = pprint.PrettyPrinter(indent=4)

class ProfileTag:
    def __init__(self):
        self.name = None
        self.server = None
        self.port = None
        self.user = None
        self.logdir = None
        self.password = None
        self.resource = None
        self.commands = None
        self.aliases = None
        self.audiocmd = None
        self.audioargs = None
        self.priority = 0
        self.autoStatusList = []
        self.encoding = "iso-8859-1"

        #
        # list is: "default (true/false)",
        #  "prettyname (must be the same as key excepting case",
        #  "help text"
        #
        self.switches = {
            "debug" : ["false", "debug", "show debug messages?"],
            "statusshow" : ["true", "statusShow", "show presence updates?" ],
            "ssl" : ["false", "ssl",
                "encrypt communications over an SSL layer?" ],
            "colors" : ["true", "Colors",
                "use colors when displaying?" ],
            "ringbell" : [ "true", "ringBell",
                "ring the bell on message arrival?" ],
            "nickprompt" : [ "false", "nickPrompt",
                "Use the nick you're writing to as the prompt?" ],
            "allowinterrupt" : [ "false", "allowInterrupt",
                "Allow new incoming messages to interrupt your composing a message?" ],
            "autostatus" : [ "false", "autoStatus", "use autostatus rules?" ],
            "statusnag" : [ "false", "statusNag", "warn if status is not online while sending messages?" ],
            "confsuppress" : [ "false", "confSuppress", "Suppress the 'from line' on conference messages?" ],
            "igndupstatus" : [ "true", "ignDupStatus", "Ignore duplicate status messages?" ]
        }

    def __repr__(self):
        return pp.pformat(self.__dict__)

class DummyTag:
    def __init__(self):
        self.text = ""

class DummyAliasTag:
    def __init__(self, name):
        self.name = name
        self.text = ""

class DefaultCommands:
    def __init__(self):
        self.commandsdict = { "msg" : "/msg",
                              "e" : "e",
                              "w" : "w",
                              "info" : "/info",
                              "add" : "/add",
                              "remove" : "/remove",
                              "chat" : "/chat",
                              "away" : "/away",
                              "xa" : "/xa",
                              "dnd" : "/dnd",
                              "quit" : "/quit",
                              "reply" : "//",
                              "respond" : "/r",
                              "set" : "/set",
                              "auth" : "/auth",
                              "bang" : "!",
                              "rename" : "/rename",
                              "delete" : "/delete",
                              "idle" : "/idle",
                              "interactivereg" : "/interactivereg",
                              "listprofiles" : "/listprofiles",
                              "switchprofile" : "/switchprofile",
                              "help" : "/help",
                              "online" : "/online",
                              "show" : "/show",
                              "addgroup" : "/addgroup",
                              "delgroup" : "/delgroup",
                              "setgroup" : "/setgroup",
                              "membership" : "/membership",
                              "sendfile" : "/sendfile",
                              "agents" : "/agents",
                              "agenthelp" : "/agenthelp",
                              "agentreg" : "/reg",
                              "getfile"  : "/getfile",
                              "alias"    : "/alias",
                              "saveprefs" : "/saveprefs",
                              "unalias" : "/unalias",
                              "msgr" : "/msgr",
                              "last" : "/last",
                              "logs" : "/logs",
                              "submitvcard" : "/submitvcard",
                              "admin" : "/admin",
                              "adminwho" : "/adminwho",
                              "setpriority" : "/setpriority",
                              "joinconf" : "/joinconf",
                              "leaveconf" : "/leaveconf",
                              "confusers" : "/confusers"
                              }

        self.helpcommands = { "msg" : "Send a message to a user",
                              "e" : "Show users that are currently online",
                              "w" : "Show the status of all users on your Roster",
                              "info" : "Get information on a user",
                              "add" : "Add a user to your roster",
                              "remove" : "Unsubscribe from a user's presence",
                              "chat" : "Set your status to chat",
                              "away" : "Set your status to away",
                              "xa" : "Set your status to eXtended Away",
                              "dnd" : "Set your status to DND",
                              "quit" : "Quit IMCom",
                              "reply" : "Message the last user you messaged.",
                              "respond" : "Message the last user who messaged you",
                              "set" : "Set boolean variables",
                              "auth" : "Authorize a user to add you to their roster",
                              "bang" : "execute a shell command",
                              "rename" : "rename a user on your roster",
                              "delete" : "DANGER, deletes a user from your roster",
                              "listprofiles" : "List all the profile in your config",
                              "switchprofile" : "Switch to another profile from your config",
                              "help" : "Get help",
                              "online" : "set status to online",
                              "show" : "Show members of a particular group",
                              "addgroup" : "Add a user to a group",
                              "delgroup" : "Remove a group from a user",
                              "setgroup" : "Set the user's only group",
                              "membership" : "Show the groups that a user is in",
                              "sendfile" : "Send a file to a user",
                              "agents" : "List the agents or transports that the jabber server recognizes",
                              "agenthelp" : "Gets information on how to register with the transport. \nRequired to begin registration process",
                              "agentreg" : "Register with a transport.",
                              "getfile" : "Accept a file transfer offer",
                              "alias" : "Create a textual-substitution alias",
                              "saveprefs" : "Save your preferences (colors, commands aliases)",
                              "unalias" : "Remove an existing alias",
                              "msgr" : "Send a multiline message to a user with a resource",
                              "last" : "Show the history of exchanges with a nick",
                              "logs" : "View or search the logfiles",
                              "submitvcard" : "Submit your vCard information to the server",
                              "admin" : "Sends a message to all users online, or sets a MOTD (Admin users only)",
                              "adminwho" : "Shows a list of users on your server currently (Admin users only)",
                              "setpriority" : "Set the priority of this connection. (used when logged onto the same account from more than one resource.",
                              "joinconf" : "Join a group-chat or conference",
                              "leaveconf" : "Leave a group-chat or conference",
                              "confusers" : "Shows the users in a conference"
                              }

class Commands:
    def __init__(self):
        self.commandsdict = {}
class Colors:
    def __init__(self):
        darkgray = chr(27)+"[1;30m"
        brightred = chr(27)+"[1;31m"
        brightgreen = chr(27)+"[1;32m"
        yellow = chr(27)+"[1;33m"
        brightblue = chr(27)+"[1;34m"
        purple = chr(27)+"[1;35m"
        brightcyan = chr(27)+"[1;36m"
        white = chr(27)+"[1;37m"
        black = chr(27)+"[0;30m"
        red = chr(27)+"[0;31m"
        green = chr(27)+"[0;32m"
        brown = chr(27)+"[0;33m"
        blue = chr(27)+"[0;34m"
        magenta = chr(27)+"[0;35m"
        cyan = chr(27)+"[0;36m"
        lightgray = chr(27)+"[0;37m"
        self.cdict = { "darkgray":darkgray, "brightred":brightred,
                       "brightgreen":brightgreen, "yellow":yellow,
                       "brightblue":brightblue, "purple":purple,
                       "brightcyan":brightcyan, "white":white,
                       "black":black, "red":red, "green":green,
                       "brown":brown, "blue":blue, "magenta":magenta,
                       "cyan":cyan, "lightgray":lightgray }
        self.colorsdict = {}
        self.sessioncolors = {}

    #def __repr__(self):
    #    s1 = pp.pformat(self.colorsdict)
    #    s2 = pp.pformat(self.sessioncolors)
    #    return "'colorsdict': " + s1 + "\n" + "'sessioncolors': " + s2

class DefaultColors:
    def __init__(self):
        darkgray = chr(27)+"[1;30m"
        brightred = chr(27)+"[1;31m"
        brightgreen = chr(27)+"[1;32m"
        yellow = chr(27)+"[1;33m"
        brightblue = chr(27)+"[1;34m"
        purple = chr(27)+"[1;35m"
        brightcyan = chr(27)+"[1;36m"
        white = chr(27)+"[1;37m"
        black = chr(27)+"[0;30m"
        red = chr(27)+"[0;31m"
        green = chr(27)+"[0;32m"
        brown = chr(27)+"[0;33m"
        blue = chr(27)+"[0;34m"
        magenta = chr(27)+"[0;35m"
        cyan = chr(27)+"[0;36m"
        lightgray = chr(27)+"[0;37m"
        self.cdict = { "darkgray":darkgray, "brightred":brightred,
                       "brightgreen":brightgreen, "yellow":yellow,
                       "brightblue":brightblue, "purple":purple,
                       "brightcyan":brightcyan, "white":white,
                       "black":black, "red":red, "green":green,
                       "brown":brown, "blue":blue, "magenta":magenta,
                       "cyan":cyan, "lightgray":lightgray }

        self.colorsdict = { "user"        : brightgreen,
                            "status"      : yellow,
                            "error"       : brightred,
                            "messagebody" : yellow,
                            "time"        : brightcyan,
                            "desc"        : purple,
                            "sep"         : brightblue,
                            "default"     : white,
                            "key"         : brightblue }

class Preferences:
    def __init__(self):
        self.profiles = {}
        self.elementStack = []
        self.parser = expat.ParserCreate()
        self.parser.StartElementHandler = self.startElement
        self.parser.EndElementHandler = self.endElement
        self.parser.CharacterDataHandler = self.characters
        self.default = None
        self.debug = 0
        self.defaultcommands = DefaultCommands()
        self.defaultcolors = DefaultColors()
        self.currentGoal = 0
        self.oldGoal = 0
        self.GETCOMMANDS = 1
        self.GETCOLORS = 2
        self.GETPROFILECOMMANDS = 3
        self.GETPROFILE = 4
        self.GETPROFILECOLORS = 5
        self.GETALIASES = 6
        self.GETAUTOSTATUS = 7
        self.lastAutoStatus = None
        try:
            f = open(os.environ['HOME']+"/.imcom/imcomrc","r")
            self.parser.ParseFile(f)
            self.fixColors()
        except IOError:
            print
            print "Profile ~/.imcom/imcomrc doesn't exist, should create one"
            print
            print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
            print "If you were previously using IMCom and just upgraded\n"\
                  "move ~/.imcomrc to ~/.imcom/imcomrc and start IMCom again"
            print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
            print
            print

    def getCommand(self,profile,command):
        if(profile.commands.commandsdict.has_key(command)):
            return profile.commands.commandsdict[command]
        elif(self.defaultcommands.commandsdict.has_key(command)):
            return self.defaultcommands.commandsdict[command]
        return None

    def getDefaultProfile(self):
        if(self.default != None):
            return self.profiles[self.default]
        else:
            return None

    def getProfile(self, string):
        try:
            return self.profiles[string]
        except:
            return None

    def addProfile(self, profilename, server, port, user, password, resource):
        p = ProfileTag()
        p.name = profilename
        p.server = server
        p.port = port
        p.user = user
        p.password = password
        p.resource = resource
        p.priority = 0
        p.logdir = os.environ['HOME']+"/.imcom/"+p.name
        # add line here to put in boolean switches?  --don't think we need it(casey)
        self.profiles[profilename] = p

    def createInitialProfile(self, name, host, port, user,
                             password, resource, encoding):
        towrite = "<imcom default='"+name+"'>\n"\
                  "    <profile name='"+name+"' "
        p = ProfileTag()
        for x in p.switches.keys():
            towrite += x + "='" + fix( p.switches[x][0] ) + "' "

        towrite += ">\n"
        towrite = towrite + \
                  "        <server>"+host+"</server>\n"\
                  "        <port>"+port+"</port>\n"\
                  "        <user>"+user+"</user>\n"\
                  "        <password>"+password+"</password>\n"\
                  "        <resource>"+resource+"</resource>\n"\
                  "        <priority>0</priority>\n"\
                  "        <encoding>"+encoding+"</encoding>\n"\
                  "        <autostatus>\n"\
                  "            <status current='online' auto='all' idle='10' new='away'>Auto-away after 10 minutes</status>\n"\
                  "            <status current='away' auto='auto' idle='20' new='xa'>Auto-away after 20 minutes</status>\n"\
                  "            <status current='away,xa' auto='auto' idle='0' new='online'></status>"\
                  "        </autostatus>\n"\
                  "    </profile>\n"\
                  "</imcom>"

        try:
            os.mkdir(os.environ['HOME']+"/.imcom")
        except:
            pass

        f = open(os.environ['HOME']+"/.imcom/imcomrc","w")
        f.write(towrite)
        f.flush()
        f.close()

        f = open(os.environ['HOME']+"/.imcom/imcomrc","r")
        self.profiles = {}
        self.elementStack = []
        self.default = None
        self.parser.ParseFile(f)


    def startElement(self, name, attrs):
        if(self.debug):
            print "Start tag < " + name + " >"
        if(string.lower(name) == "imcom"):
            self.default = attrs["default"]
            return
        if(string.lower(name) == "profile"):
            profile = ProfileTag()

            for x in profile.switches.keys():
                if self.getAttr( attrs, x ) != None:
                    profile.switches[x][0] = self.getAttr( attrs, x )

            profile.name = self.getAttr(attrs,"name")
            profile.logdir = os.environ['HOME']+"/.imcom/"+profile.name

            profile.commands = Commands()
            profile.commands.commandsdict = self.defaultcommands.commandsdict
            profile.colors = Colors()
            profile.aliases = {}
            self.oldGoal = 0
            self.currentGoal = self.GETPROFILE
            self.elementStack.append(profile)
            return

        sl = string.lower(name)
        if(self.currentGoal == self.GETPROFILE and (
            sl == "server" or sl == "port" or sl == "user" or
            sl == "password" or sl == "resource" or
            sl == "audiocmd" or sl == "audioargs" or
            sl == "priority" or sl == "encoding")):
            dt = DummyTag()
            self.elementStack.append(dt)

        if( (self.currentGoal == self.GETAUTOSTATUS) and
            sl == "status"):
            #
            # the dummy tag is where self.characters() will
            # put the text from this element
            #
            dt = DummyTag()
            self.elementStack.append(dt)
            self.autoStatusEntry( attrs )

        if(self.currentGoal == self.GETPROFILE and sl == "command"):
            self.oldGoal = self.GETPROFILE
            self.currentGoal = self.GETPROFILECOMMANDS

        if(self.currentGoal == self.GETPROFILE and sl == "autostatus"):
            self.oldGoal = self.GETPROFILE
            self.currentGoal = self.GETAUTOSTATUS
            return

        if(self.currentGoal == self.GETPROFILE and sl == "color"):
            self.oldGoal = self.currentGoal
            self.currentGoal = self.GETPROFILECOLORS

        if(self.currentGoal == self.GETPROFILE and sl == "aliases"):
            self.oldGoal = self.currentGoal
            self.currentGoal = self.GETALIASES
            return

        if(self.currentGoal == 0 and sl == "command"):
            self.oldGoal = 0
            self.currentGoal = self.GETCOMMANDS
            return

        if(self.currentGoal == 0 and sl == "color"):
            self.oldGoal = 0
            self.currentGoal = self.GETCOLORS
            return

        if((self.currentGoal == self.GETPROFILECOMMANDS or
            self.currentGoal == self.GETCOMMANDS) and
           self.defaultcommands.commandsdict.has_key(sl)):
            dt = DummyTag()
            self.elementStack.append(dt)

        if(self.currentGoal == self.GETALIASES and sl =="alias"):
            name = self.getAttr(attrs,"name")
            dt = DummyAliasTag(name)
            self.elementStack.append(dt)
            return

        if((self.currentGoal == self.GETCOLORS or
            self.currentGoal == self.GETPROFILECOLORS) and (
            sl == "user" or sl == "status" or sl == "error" or
            sl == "messagebody" or sl == "time" or sl == "desc" or
            sl == "sep" or sl == "default" or sl == "key")):
            dt = DummyTag()
            self.elementStack.append(dt)


    def endElement(self, name):
        if(self.debug):
            print "End tag < " + name + " >"
        sl = string.lower(name)
        if(self.currentGoal == self.GETPROFILE):
            if(sl == "server"):
                dt = self.elementStack.pop()
                p  = self.elementStack.pop()
                try:
                    p.server = dt.text
                except:
                    pass
                self.elementStack.append(p)
                return
            if(sl == "port"):
                dt = self.elementStack.pop()
                p  = self.elementStack.pop()
                try:
                    p.port = int(dt.text)
                except:
                    pass
                self.elementStack.append(p)
                return
            if(sl == "user"):
                dt = self.elementStack.pop()
                p  = self.elementStack.pop()
                try:
                    p.user = dt.text
                except:
                    pass
                self.elementStack.append(p)
                return
            if(sl == "password"):
                dt = self.elementStack.pop()
                p  = self.elementStack.pop()
                try:
                    p.password = dt.text
                except:
                    pass
                self.elementStack.append(p)
                return
            if(sl == "resource"):
                dt = self.elementStack.pop()
                p  = self.elementStack.pop()
                try:
                    p.resource = dt.text
                except:
                    pass
                self.elementStack.append(p)
                return
            if(sl == "encoding"):
                dt = self.elementStack.pop()
                p  = self.elementStack.pop()
                try:
                    p.encoding = dt.text
                except:
                    pass
                self.elementStack.append(p)
                return
            if(sl == "audiocmd"):
                dt = self.elementStack.pop()
                p  = self.elementStack.pop()
                try:
                    p.audiocmd = dt.text
                except:
                    pass
                self.elementStack.append(p)
                return
            if(sl == "audioargs"):
                dt = self.elementStack.pop()
                p  = self.elementStack.pop()
                try:
                    p.audioargs = dt.text
                except:
                    pass
                self.elementStack.append(p)
                return
            if(sl == "priority"):
                dt = self.elementStack.pop()
                p  = self.elementStack.pop()
                try:
                    p.priority = int(dt.text)
                except:
                    pass
                self.elementStack.append(p)
                return
        if(sl == "profile"):
            p  = self.elementStack.pop()
            self.profiles[p.name] = p
            self.currentGoal = 0
            return

        if(sl == "command"):
            self.currentGoal = self.oldGoal
            return

        if(sl == "color"):
            self.currentGoal = self.oldGoal
            return

        if(sl == "aliases"):
            self.currentGoal = self.oldGoal
            return

        if(sl == "autostatus"):
            self.currentGoal = self.oldGoal
            return

        if((self.currentGoal == self.GETPROFILECOMMANDS or
            self.currentGoal == self.GETCOMMANDS) and
           self.defaultcommands.commandsdict.has_key(sl)):
            if(self.currentGoal == self.GETCOMMANDS):
                c = self.elementStack.pop()
                temp = self.getText(c)
                if(temp):
                    self.defaultcommands.commandsdict[sl] = temp
                return
            else:
                c = self.elementStack.pop()
                p = self.elementStack.pop()
                temp = self.getText(c)
                if(temp):
                    p.commands.commandsdict[sl] = temp
                self.elementStack.append(p)
                return

        if(self.currentGoal == self.GETAUTOSTATUS and sl == "status"):
            self.lastAutoStatus = self.lastAutoStatus[0:6] + \
                (self.elementStack.pop().text,) + self.lastAutoStatus[7:]
            p = self.elementStack.pop();
            p.autoStatusList.append( self.lastAutoStatus )
            self.elementStack.append(p)
            return

        if((self.currentGoal == self.GETALIASES) and
           sl == "alias"):
            dt = self.elementStack.pop()
            p = self.elementStack.pop()
            p.aliases[dt.name] = dt.text
            self.elementStack.append(p)
            return

        if(self.currentGoal == self.GETCOLORS or
           self.currentGoal == self.GETPROFILECOLORS):
            if(sl == "user" or sl == "status" or sl == "error" or
               sl == "messagebody" or sl == "time" or sl == "desc" or
               sl == "sep" or sl == "default" or sl == "key"):
                if(self.currentGoal == self.GETCOLORS):
                    c = self.elementStack.pop()
                    temp = self.getText(c)
                    if(temp and self.defaultcolors.cdict.has_key(temp)):
                        self.defaultcolors.colorsdict[sl] = self.defaultcolors.cdict[temp]
                    return
                else:
                    c = self.elementStack.pop()
                    p = self.elementStack.pop()
                    temp = self.getText(c)
                    if(temp and p.colors.cdict.has_key(temp)):
                        p.colors.colorsdict[sl] = p.colors.cdict[temp]
                    self.elementStack.append(p)

    def getText(self, p):
        try:
            return string.strip(string.lower(p.text))
        except:
            return None

    def characters(self, content):
        # content is a string of the cdata
        if(len(string.strip(content)) > 0):
            if(self.debug):
                print "Content < " + content + " > "
            element = self.elementStack.pop()
            try:
                blah = element.text
                if(blah == None):
                    element.text = content
                    self.elementStack.append(element)
                    return
            except:
                element.text = content
                self.elementStack.append(element)
                return

            element.text = element.text + content
            self.elementStack.append(element)

    def getAttr(self, attrs, name):
        try:
            return attrs[name]
        except:
            return None

    def writePreferences(self):
        towrite = "<imcom default='"+fix(self.default)+"'>\n"
        towrite = towrite + "  <color>\n"
        keys = self.defaultcolors.colorsdict.keys()
        for item in keys:
            towrite = towrite + "    <"+fix(item)+">"+\
                      fix(getHashKeyFromValue(self.defaultcolors.cdict,
                                              self.defaultcolors.colorsdict[item])) + \
                      "</"+fix(item)+">\n"
        towrite = towrite + "  </color>\n  <command>\n"
        keys = self.defaultcommands.commandsdict.keys()
        for item in keys:
            towrite = towrite + "    <"+fix(item)+">"+\
                      fix(self.defaultcommands.commandsdict[item]) + \
                      "</"+fix(item)+">\n"
        towrite = towrite + "  </command>\n"
        keys = self.profiles.keys()
        for item in keys:
            towrite = towrite + writeProfile(self.profiles[item])
        towrite = towrite + "</imcom>"
        try:
            os.mkdir(os.environ['HOME']+"/.imcom")
        except:
            pass
        f = open(os.environ['HOME']+"/.imcom/imcomrc","w")
        f.write(towrite)
        f.flush()
        f.close()
        return towrite

    def autoStatusEntry(self, attrs):
        self.lastAutoStatus = (
            [-1,-1], [-1,-1], ['all'], 'all', 0, 'inactive', '' )
        for x in attrs.keys():
            y = string.lower( x )
            if( y == "time" ):
                z = attrs[x]
                times = string.split( z, "-" )
                if( len( times ) != 2 ):
                    next
                self.lastAutoStatus[0][0], self.lastAutoStatus[0][1] = \
                    string.split( times[0], ":" )
                self.lastAutoStatus[1][0], self.lastAutoStatus[1][1] = \
                    string.split( times[1], ":" )

            if( y == "current" ):
                z = attrs[x]
                if( self.lastAutoStatus[2].count('all') ):
                    self.lastAutoStatus[2].remove('all')
                for x in string.split( z, "," ):
                    self.lastAutoStatus[2].append( x )

            if( y == "auto" ):
                self.lastAutoStatus = self.lastAutoStatus[0:3] + \
                    (attrs[x],) + self.lastAutoStatus[4:]

            if( y == "new" ):
                self.lastAutoStatus = self.lastAutoStatus[0:5] + \
                    (attrs[x],) + self.lastAutoStatus[6:]

            if( y == "idle" ):
                self.lastAutoStatus = self.lastAutoStatus[0:4] + \
                    (int(attrs[x]),) + self.lastAutoStatus[5:]

    def fixColors( self ):
        for p in self.profiles.values():
            for color in self.defaultcolors.colorsdict.keys():
                if ( not p.colors.colorsdict.has_key( color ) ):
                    p.colors.sessioncolors[color] = \
                        self.defaultcolors.colorsdict[color]
                else:
                    p.colors.sessioncolors[color] = \
                        p.colors.colorsdict[color]



def getHashKeyFromValue(hash, value):
    keys = hash.keys()
    for item in keys:
        if hash[item] == value:
            return item
    return None

def writeProfile(p):
    towrite = "  <profile "
    for x in p.switches.keys():
        towrite += x + "='" + fix( p.switches[x][0] ) + "' "
    towrite += "name='" + fix( p.name ) + "' "
    towrite += ">\n" + \
              "    <server>" + fix(p.server) + "</server>\n" +\
              "    <port>" + fix(str(p.port)) + "</port>\n" +\
              "    <user>" + fix(p.user) + "</user>\n" +\
              "    <password>" + fix(p.password) + "</password>\n" +\
              "    <resource>" + fix(p.resource) + "</resource>\n" +\
              "    <priority>" + fix(str(p.priority)) + "</priority>\n" +\
              "    <encoding>" + fix(p.encoding) + "</encoding>\n"
    if(p.audiocmd):
        towrite = towrite + "    <audiocmd>" + fix(p.audiocmd) + "</audiocmd>\n"
    if(p.audioargs):
        towrite = towrite + "    <audioargs>" + fix(p.audioargs) + "</audioargs>\n"
    if(p.colors):
        towrite = towrite + "    <color>\n"
        for item in p.colors.colorsdict.keys():
            towrite = towrite + "      <"+fix(item)+">"+\
                      fix(getHashKeyFromValue(p.colors.cdict,
                                              p.colors.colorsdict[item])) + \
                                              "</"+fix(item)+">\n"
        towrite = towrite + "    </color>\n"
    if(p.commands):
        towrite = towrite + "    <command>\n"
        for item in p.commands.commandsdict.keys():
            towrite = towrite + "      <"+fix(item)+">"+\
                      fix(p.commands.commandsdict[item]) + "</"+fix(item)+">\n"
        towrite = towrite + "    </command>\n"
    if(p.aliases):
        towrite = towrite + "    <aliases>\n"
        for item in p.aliases.keys():
            towrite = towrite + "      <alias name='"+fix(item)+"'>"+\
                      fix(p.aliases[item]) + "</alias>\n"
        towrite = towrite + "    </aliases>\n"
    if(p.autoStatusList):
        towrite = towrite + "    <autostatus>\n"
        for item in p.autoStatusList:
            towrite = towrite + "      <status "
            if( item[0][0] != -1 ):
                towrite += "time='" + item[0][0] + ":" + item[0][1] + \
                    "-" + item[1][0] + ":" + item[1][1] + "' "
            if( ( len(item[2]) != 0 ) and ( item[2][0] != 'all' ) ):
                towrite += "current='"
                for x in item[2]:
                    towrite += x + ","
                towrite = towrite[:-1]
                towrite += "' "
            towrite += "auto='" + item[3] + "' "
            towrite += "idle='" + str(item[4]) + "' "
            towrite += "new='" + item[5] + "' "
            towrite += ">" + fix(item[6]) + "</status>\n"
        towrite = towrite + "    </autostatus>\n"
    towrite = towrite + "  </profile>\n"
    return towrite

def fix(str):
    str = string.replace( str, "&", "&amp;" );
    str = string.replace( str, '"', "&quot;");
    str = string.replace( str, "'", "&apos;");
    str = string.replace( str, "<", "&lt;");
    str = string.replace( str, ">", "&gt;");
    return str;

if(__name__ == "__main__"):
    p = Preferences()
    p.debug = 0
    #print p.profiles
    #print p.default
    d = p.profiles[p.default]
    print p.writePreferences()

    #print("Host is <"+d.server+">\n"+
    #      "Port is <%d>\n"%d.port+
    #      "User is <"+d.user+">\n"+
    #      "Pass is <"+d.password+">")

