From The Mana World
#!/usr/bin/python
# Licensed under GNU General Public License

import sys, os, popen2;
import xml.parsers.expat

debug=0


######################################################
##                                                  ##
##  ADD WIKILINKS TO IMAGES OF ITEMS THAT ARE DYED  ##
##  OR DO NOT HAVE THE SAME NAME IN WIKI AND SVN    ##
##                                                  ##
######################################################

imageurls = {
'AlizarinHerb':           "Alizarin-herb.png",

'BlackDye':               "Use-potion-blackdye.png",
'BlackRose':              "Generic-blackrose.png",
'BlackScorpionStinger':   "Generic-blackscorpionstinger.png",
'BlueRose':               "Generic-bluerose.png",

'CactusDrink':            "Use-potion-cactusdrink.png",
'CactusPotion':           "Use-potion-cactuspotion.png",
'Cap':                    "Armor-head-cap.png",
'CaveSnakeEgg':           "Use-food-cavesnakeegg.png",
'CaveSnakeTongue':        "Generic-cavesnaketongue.png",
'CobaltHerb':             "Cobalt-herb.png",
'ConcentrationPotion':    "Use-potion-concentrationpotion.png",
'CottonCloth':            "Generic-fabric.png",
'CottonHeadband':         "Armor-legs-cottonheadband.png",
'CottonShorts':           "Armor-legs-cottonshorts.png",
'CottonSkirt':            "Armor-legs-skirt.png",

'DarkBlueDye':            "Use-potion-darkbluedye.png",
'DarkGreenDye':           "Use-potion-darkgreendye.png",
'DarkRedRose':            "Generic-darkredrose.png",
'DevelopersCap':          "Armor-head-devcap.png",

'GambogeHerb':            "Gamboge-herb.png",
'GMRobe':                 "Armor-chest-gmrobe.png",
'GoldenPlatemail':        "Armor-chest-lightplatemailgold.png",
'GoldenScorpionStinger':  "Generic-goldenscorpionstinger.png",
'GoldenWarlordPlate':     "Armor-chest-warlordplategold.png",
'GrassSnakeEgg':          "Use-food-grasssnakeegg.png",
'GrassSnakeTongue':       "Generic-grasssnaketongue.png",
'GreenDye':               "Use-potion-greendye.png",

'IronPotion':             "Use-potion-ironpotion.png",
'IronPowder':             "Generic-ironpowder.png",
'Iten':                   "Generic-iten.png",

'JeansShorts':            "Armor-legs-jeanshorts.png",

'LargeHealingPotion':     "Use-potion-largehealingpotion.png",
'LightBlueDye':           "Use-potion-lightbluedye.png",
'LightPlatemail':         "Armor-chest-lightplatemail.png",

'MagicPotion':            "Use-potion-magicpotion.png",
'MauveHerb':              "Mauve-herb.png",
'MediumHealingPotion':    "Use-potion-mediumhealingpotion.png",
'MonsterOilPotion':       "Use-potion-monsteroilpotion.png",
'MountainSnakeEgg':       "Use-food-mountainsnakeegg.png",
'MountainSnakeTongue':    "Generic-mountainsnaketongue.png",

'OrangeDye':              "Use-potion-orangedye.png",
'OrangeRose':             "Generic-orangerose.png",
'OrangeTulip':            "Generic-orangetulip.png",

'PileOfAsh':              "Generic-ashpowder.png",
'PinkDye':                "Use-potion-pinkdye.png",
'PinkRose':               "Generic-pinkrose.png",
'PinkTulip':              "Generic-pinktulip.png",
'PurpleDye':              "Use-potion-purpledye.png",
'PurpleTulip':            "Generic-purpletulip.png",

'RedDye':                 "Use-potion-reddye.png",
'RedRose':                "Generic-redrose.png",
'RedScorpionStinger':     "Generic-redscorpionstinger.png",
'RedTulip':               "Generic-redtulip.png",

'ScorpionStinger':        "Generic-scorpionstinger.png",
'SilkRobe':               "Armor-chest-robe.png",
'SmallHealingPotion':     "Use-potion-smallhealingpotion.png",
'SnakeEgg':               "Use-food-snakeegg.png",
'SnakeTongue':            "Generic-snaketongue.png",
'Steak':                  "Use-food-steak.png",
'SulphurPowder':          "Generic-sulphurpowder.png",

'TinyHealingPotion':      "Use-potion-tinyhealingpotion.png",
'TurtleneckSweater':      "Armor-chest-tnecksweater.png",

'VNeckSweater':           "Armor-chest-vnecksweater.png",

'WarlordPlate':           "Armor-chest-warlordplate.png",
'WhiteRose':              "Generic-whiterose.png",
'WhiteShortTankTop':      "Armor-chest-whiteshorttanktop.png",
'WhiteTankTop':           "Armor-chest-whitetanktop.png",
'WhiteTulip':             "Generic-whitetulip.png",

'YellowDye':              "Use-potion-yellowdye.png",
'YellowRose':             "Generic-yellowrose.png",
'YellowTulip':            "Generic-yellowtulip.png"

# Note that the last line above should not be ended by a comma!
}


##############################
##                          ##
##  OTHER ITEM INFORMATION  ##
##                          ##
##############################

# Availability
B =   1  # (0) Buyable:      can be bought from shops
Q =   2  # (1) Quest reward: available from quests
C =   4  # (2) Common drop:  commonly dropped by monsters (> 1% chance)
R =   8  # (3) Rare drop:    rarely dropped by monsters (<= 1% chance)
O =  16  # (4) Old:          was previously available in the game
U =  32  # (5) Unreleased:   unreleased or otherwise unobtainable
G =  64  # (6) GM only:      only for game masters
D = 128  # (7) Dev only:     only for developers
S = 256  # (8) Special:      special purpose (e.g. Wedding Ring)

# Other
Y = 512  # (9) Dyeable:      can be dyed

extrainfo = {
'AlizarinHerb':          C,
'AntlerHat':             O,
'Apple':                 B + C,
'Arrow':                 B + C,
'Axe':                   U,
'AxeHat':                O,

'Bandana':               O,
'Bardiche':              U,
'Beer':                  B,
'Beheader':              U,
'BlackCowboyHat':        Q,
'BlackDye':              Q,
'BlackRose':             B,
'BlackScorpionStinger':  C,
'BlacksmithsAxe':        U,
'BlueEasterEgg':         O,
'BluePresentBox':        Q + C,
'BlueRose':              B,
'BoneDarts':             U,
'BoneKnife':             Q,
'Boots':                 B + C,
'BottleOfSand':          U,
'BottleOfWater':         C,
'Bow':                   B + Q,
'BugLeg':                Q + C,
'BunnyEars':             O,

'CactusDrink':           B + C,
'CactusPotion':          B + Q + C,
'Cake':                  B + Q + C,
'Candy':                 Q + C,
'CandyCane':             Q + C,
'Cap':                   U,
'CasinoCoins':           B + Q + C,
'CatEars':               U,
'CaveSnakeEgg':          C,
'CaveSnakeLamp':         C,
'CaveSnakeTongue':       C,
'ChainmailShirt':        B,
'CherryCake':            B + Q + C,
'ChickenLeg':            B,
'ChocolateBar':          Q + C,
'ChristmasElfHat':       O,
'ChristmasTreeHat':      O,
'Circlet':               O,
'CobaltHerb':            C,
'CoinBag':               C,
'ConcentrationPotion':   B + Q + R,
'CottonCloth':           C,
'CottonHeadband':        U,
'CottonShirt':           B + Q,
'CottonShorts':          B + Q,
'CottonSkirt':           B,
'CrescentRod':           U,
'Crown':                 U,
'CrusadeHelmet':         Q,

'Dagger':                B + C,
'DarkBlueDye':           Q,
'DarkCrystal':           O,
'DarkGreenDye':          Q,
'DarkRedRose':           B,
'DecorCandy':            Q + C,
'DemonMask':             U,
'DesertBow':             U,
'DesertHat':             U,
'DesertShirt':           B,
'DevelopersCap':         D,

'EasterEgg':             Q,
'EmptyBottle':           C,
'Eyepatch':              O,

'FaceMask':              O,
'Falcion':               U,
'FancyHat':              B + C,
'ForestBow':             B + Q,
'FunkyHat':              O,
'FurBoots':              Q,

'GambogeHerb':           C,
'GingerBreadMan':        Q + C,
'GMsCap':                G,
'GMRobe':                G,
'Goggles':               O,
'GoldenPlatemail':       U,
'GoldenScorpionStinger': Q,
'GoldenWarlordPlate':    U,
'GraduationCap':         Q,
'GrassSnakeEgg':         C,
'GrassSnakeTongue':      C,
'GreenDye':              Q,
'GreenEasterEgg':        O,
'GreenPresentBox':       C,

'Halberd':               U,
'HardSpike':             C,
'HeartNecklace':         U,
'HighPriestCrown':       U,
'Hint1':                 O,
'Hint2':                 O,
'Hint3':                 O,
'Hint4':                 O,
'Hint5':                 O,
'Hint6':                 O,
'Hint7':                 O,
'Hint8':                 O,
'Hint9':                 O,
'Hint10':                O,

'InfantryHelmet':        R,
'IronArrow':             B,
'IronOre':               C,
'IronPotion':            B + Q + C,
'IronPowder':            U,
'Iten':                  U,

'Jackal':                U,
'JeansChaps':            Q,
'JeansShorts':           R,

'Knife':                 B + C,
'KnightsHelmet':         Q,

'LargeHealingPotion':    Q,
'LeatherGloves':         R,
'LeatherGoggles':        O,
'LeatherPatch':          Q,
'LeatherShield':         B,
'LeatherShirt':          B + C,
'LightBlueDye':          Q,
'LightPlatemail':        B,

'MaggotSlime':           Q + C,
'MauveHerb':             C,
'MediumHealingPotion':   Q,
'Milk':                  B + C,
'MinerGloves':           B + C,
'MinersHat':             B + C,
'MonsterOilPotion':      Q,
'MonsterSkullHelmet':    U,
'MoubooHead':            U,
'MountainSnakeEgg':      C,
'MountainSnakeTongue':   C,
'MushHat':               O,

'NohMask':               Q,

'Orange':                B + C,
'OrangeCupcake':         B + C,
'OrangeDye':             Q,
'OrangeRose':            B,
'OrangeTulip':           B,

'Pearl':                 R,
'Petal':                 C,
'PileOfAsh':             C,
'PinkAntenna':           C,
'PinkDye':               Q,
'PinkEasterEgg':         O,
'PinkRose':              B,
'PinkTulip':             B,
'PirateHat':             O,
'PumpkinHelmet':         O,
'PurpleDye':             Q,
'PurplePresentBox':      Q + C,
'PurpleTulip':           B,

'RangerHat':             O,
'RawLog':                C,
'RedChristmasStocking':  O,
'RedDye':                Q,
'RedEasterEgg':          O,
'RedRose':               B,
'RedScorpionStinger':    Q + C,
'RedTulip':              B,
'RoastedMaggot':         B + C,
'RockKnife':             U,

'Sabre':                 U,
'SandCutter':            U,
'SantaBeardHat':         O,
'SantaCookie':           O,
'SantaHat':              Q,
'ScarabArmlet':          O,
'Scimitar':              U,
'Scorpion':              U,
'ScorpionStinger':       Q + C,
'Scythe':                Q,
'SerfHat':               B,
'Setzer':                Q,
'SharpKnife':            B + C,
'ShortBow':              B,
'ShortSword':            Q,
'ShroomHat':             O,
'SilkCocoon':            C,
'SilkHeadband':          B,
'SilkRobe':              Q,
'SmallHealingPotion':    Q,
'SmallMushroom':         C,
'SnakeSkin':             C,
'SnakeEgg':              C,
'SnakeTongue':           C,
'StaffOfFire':           U,
'StaffOfIce':            U,
'StaffOfLife':           U,
'StandardHeadband':      B,
'Steak':                 B,
'SteelShield':           Q,
'SulphurPowder':         U,

'TealEasterEgg':         O,
'TinyHealingPotion':     Q,
'TopHat':                O,
'ToySabre':              O,
'TreasureKey':           C,
'TurtleneckSweater':     O,

'VNeckSweater':          O,

'WarlordHelmet':         Q,
'WarlordPlate':          B,
'WeddingRing':           S,
'WhiteCowboyHat':        Q,
'WhiteFur':              C,
'WhiteRose':             B,
'WhiteShortTankTop':     Q,
'WhiteTankTop':          Q,
'WhiteTulip':            B,
'WinterGloves':          Q,
'WoodenShield':          Q,

'XmasCake':              Q + C,
'XmasCandyCane':         Q + C,

'YellowDye':             Q,
'YellowEasterEgg':       O,
'YellowRose':            B,
'YellowTulip':           B

# Note that the last line above should not be ended by a comma!
}


##################
##              ##
##  INTRO TEXT  ##
##              ##
##################

def printwarningcomments():


def printintrotext():



#####################
##                 ##
##  TABLE HEADERS  ##
##                 ##
#####################

health_titles = ["Image",
                 "Name",
                 "ID",
                 "HP",
                 "SP",
                 "Price<br />BUY/sell",
                 "Weight",
                 "Description",
                 "Other"]
status_titles = ["Image",
                 "Name",
                 "ID",
                 "Spell name",
                 "Parameter 1",
                 "Parameter 2",
                 "Price<br />BUY/sell",
                 "Weight",
                 "Description",
                 "Other"]
weapon_titles = ["Image",
                 "Name",
                 "ID",
                 "Damage<br />(range)",
                 "Price<br />BUY/sell",
                 "Weight",
                 "Description",
                 "Other"]
armor_titles =  ["Image",
                 "Name",
                 "ID",
                 "Defense", 
                 "Price<br />BUY/sell",
                 "Weight",
                 "Description",
                 "Other"]
other_titles =  ["Image",
                 "Name",
                 "ID",
                 "Price<br />BUY/sell",
                 "Weight",
                 "Description",
                 "Other"]


class whatever: pass

log = []



# parseitems(file)
## Returns list with items from eathena item_db file.

def saveint(string, altval = 0):
    a = 0
    try:
        a = int(string)
    except:
        a = altval
    return a


        
def parsescript(s):
    # Assumes that there's only one call of each method, otherwise it would need to know
    # how to combine those function calls. In practice, the latter call would prevail.
    script = {}
    scriptentry = ""
    parentry = ""
    mode = 0
    for a in s:
        if mode == 0: # looking for method
            if a.isalpha(): 
                mode = 1
                scriptentry += a
            elif a == '}': mode = 9
        elif mode == 1: # reading method name
            if a in " ;}":
                if a == " ": mode = 2
                elif a == ";": mode = 1
                elif a == "}": mode = 9
                parentry = ""
                script[scriptentry] = []
            else: scriptentry += a
        elif mode == 2: #looking for param
            if a == " ": pass
            elif a == ";": 
                mode = 0
                scriptentry = ""
            else:
                mode = 3
                parentry = a
        elif mode == 3: #reading param
            if a == " " or a == "," or a == ";":
                script[scriptentry].append(parentry)
                parentry = ""
                if a == ';': 
                    mode = 0
                    scriptentry = ""
                else: mode = 2
            else: 
                parentry += a
        elif mode == 9: #finished
            pass

    # Convert all possible parameters to integers
    for x in script.values():
        for j in range(len(x)):
            try:
                x[j] = int(x[j])
            except:
                #print x[j]
                pass
    return script

    

def parseitems(file):
    objects = []
    for line in file:
        s = line[:line.find('//')].strip().replace('\t','')
        if s:
            #Replace commas inbetween {} with |, so we can use split
            mode = 0
            sout = ""
            for a in s:
                if mode == 0: #Out of {}
                    if a == '{': mode = 1
                    sout += a
                elif mode == 1: #Inside {}
                    if a == ',': sout += '|'
                    else:
                        sout += a
                        if a == '}': mode = 0

            values_norm = 20
            values = sout.split(',')
            if line[0] == '#':
                if debug:
                    log.append("FOUND COMMENT LINE: %s" % str(values))
                continue
            if len(values) != values_norm:
                log.append("item_db: Warning, item-line with ID %s has %d values instead of %d" % (values[0], len(values), values_norm))
                if debug:
                    log.append("  line was %s" % str(values))
                while len(values) < values_norm:
                    values.append('')
                while len(values) > values_norm:
                    values.pop()

            o = whatever()
            o.id          = int(values[0])
            o.label       = values[1]
            o.name        = values[2]
            o.type        = saveint(values[3])
            o.price       = saveint(values[4])
            o.sell        = saveint(values[5])
            o.weight      = saveint(values[6])
            o.attack      = saveint(values[7])
            o.defense     = saveint(values[8])
            o.range       = saveint(values[9])
            o.magicbonus  = saveint(values[10])
            o.slot        = saveint(values[11],-1)
            o.job         = saveint(values[12],-1)
            o.gender      = saveint(values[13],-1)
            o.loc         = saveint(values[14])
            o.wlv         = saveint(values[15])
            o.elv         = saveint(values[16])
            o.view        = saveint(values[17],-1)
            o.usescript   = parsescript(values[18].replace('|',','))
            o.equipscript = parsescript(values[19].replace('|',','))

            objects.append(o)

    return objects



# parsexmlitems(file)
## Creates a dictionary containing the values of a client items.xml
## Yeah, there are XML parsers in the standard python libraries, but they're too object
## oriented and thus don't fit the style of this program.

def parsexmlitems(file):
    items = {}
    pre = "<item "
    term = ">"
    attrs = ["id", "image", "name", "description", "type", "weight"]
    intattrs = ["id", "weight"]
    s = file.read()
    index = 0
    debug = 0
    while pre in s[index:]:
        index += s[index:].find(pre) + len(pre)
        curitem = {}
        termstart = index + s[index:].find(term) + len(term)

        for attr in attrs:
            found = s[index:].find(attr+'="')
            if found >= 0:
                start = index + found + len(attr+'="')
                end = start + s[start:].find('"')
            else:
                start = termstart

            if start < termstart:
                curitem[attr] = s[start:end]

        for a in intattrs:
            try:
                if a in curitem: curitem[a] = int(curitem[a])
            except:
                log.append("Item-ID %s: Cannot convert integer attribute %s to an integer. Value: '%s'" % (curitem["id"], a, curitem[a]))

        # For now, IDs below 500 are no real items and IDs 2xxx are dyed variants
        if 499 < curitem.get('id') < 2000:
            items[curitem.get('id')] = curitem

    return items

        

# addclientinformation(items, citems)
## Extends the item data with the data collected from the client items.xml. Adding imageurls,
## client name, description and effect

def addclientinformation(items, citems):
    global imageurls
    for i in items:
        if i.id in citems:
            if i.label in imageurls:
                url = imageurls[i.label]
            else:
                i.imagename=citems[i.id]["image"]
                url=i.imagename[0].upper() + i.imagename[1:]
            i.imgurl = "[[Image:"+ url + "]]"
            i.description = citems[i.id]["description"]
            i.clientname = citems[i.id]["name"]
        else:
            i.imgurl = ''
            i.description = ''
            i.clientname = ''



# gettypedir (items)
## Returns sorted lists of items by itemtype
def gettypedir(items):
    items.sort(key=lambda x: x.price+x.sell)

    typedir = whatever()
    typedir.legarmor = []
    typedir.onehandedweapons = []
    typedir.handarmor = []
    typedir.shields = []
    typedir.twohandedweapons = []
    typedir.footarmor = []
    typedir.rings = []
    typedir.headarmor = []
    typedir.chestarmor = []
    typedir.ammo = []
    typedir.healthy = []
    typedir.status = []
    typedir.inspiring = []
    typedir.other = []

    for item in items:
        if item.imgurl.strip() or item.clientname.strip():
            # -1- Check the equipable items
            if item.loc == 1: typedir.legarmor.append(item)
            elif item.loc == 2: typedir.onehandedweapons.append(item)
            elif item.loc == 4: typedir.handarmor.append(item)
            elif item.loc == 32: typedir.shields.append(item)
            elif item.loc == 34: typedir.twohandedweapons.append(item)
            elif item.loc == 64: typedir.footarmor.append(item)
            elif item.loc == 128: typedir.rings.append(item)
            elif item.loc == 256: typedir.headarmor.append(item)
            elif item.loc == 512: typedir.chestarmor.append(item)
            elif item.loc == 32768: typedir.ammo.append(item)
            elif item.loc < 0:
                log.append("Warning: Script needs to be updated with new armor type for item %d." % item.id)

            # -2- Check other items
            elif "itemheal" in item.usescript: 
                if item.usescript["itemheal"][0] >= item.usescript["itemheal"][1]: 
                    typedir.healthy.append(item)
                if item.usescript["itemheal"][1] >= item.usescript["itemheal"][0]: 
                    typedir.inspiring.append(item)
            #elif "sc_start" in item.usescript: typedir.status.append(item)
            else: typedir.other.append(item)

    typedir.onehandedweapons.sort(key=lambda x: x.attack)
    typedir.twohandedweapons.sort(key=lambda x: x.attack)
    typedir.ammo.sort(key=lambda x: x.attack)

    typedir.legarmor.sort(key=lambda x: x.defense)
    typedir.handarmor.sort(key=lambda x: x.defense)
    typedir.shields.sort(key=lambda x: x.defense)
    typedir.footarmor.sort(key=lambda x: x.defense)
    typedir.rings.sort(key=lambda x: x.defense)
    typedir.headarmor.sort(key=lambda x: x.defense)
    typedir.chestarmor.sort(key=lambda x: x.defense)

    typedir.healthy.sort(key=lambda x: int(x.usescript["itemheal"][0])+int(x.usescript["itemheal"][1]))
    typedir.inspiring.sort(key=lambda x: int(x.usescript["itemheal"][1]))
    typedir.status.sort(key=lambda x: x.price+x.sell)
    typedir.other.sort(key=lambda x: x.id)

    return typedir
    

            
# printlog()
## Prints the global variable log to stdout
def printlog():
    global log
    if len(log) > 0:
        sys.stdout.write('\n---------------------------------------\n')
    for line in log:
        sys.stdout.write(line+'\n')



##############################
##                          ##
##  CREATE THE WIKI TABLES  ##
##                          ##
##############################

def getmoneystring(buy, sell):
    return '| align="right" | %d GP<br>%d gp\n' % (buy,sell)

def getidstring(id):
    return '| style="text-align:center;" | [%d]\n' % id

def getextrainfostring(i):
    global extrainfo
    returnstring = ''
    if i.label in extrainfo:
        # Availability/rarity
        if extrainfo[i.label] >> 0 & 1 == 1: returnstring += '<br />Buyable'
        if extrainfo[i.label] >> 1 & 1 == 1: returnstring += '<br />Quest reward'
        if extrainfo[i.label] >> 2 & 1 == 1: returnstring += '<br />Common drop'
        if extrainfo[i.label] >> 3 & 1 == 1: returnstring += '<br />Rare drop'
        if extrainfo[i.label] >> 4 & 1 == 1: returnstring += '<br />Previously available'
        if extrainfo[i.label] >> 5 & 1 == 1: returnstring += '<br />Unobtainable'
        if extrainfo[i.label] >> 6 & 1 == 1: returnstring += '<br />GM only'
        if extrainfo[i.label] >> 7 & 1 == 1: returnstring += '<br />Dev only'
        if extrainfo[i.label] >> 8 & 1 == 1: returnstring += '<br />Special'

        # Other
        if extrainfo[i.label] >> 9 & 1 == 1: returnstring += '<br />Dyeable\n'

    # Spell
    if "sc_start" in i.usescript:
        returnstring += '<br />Spell: %s (%d, %d)' % (i.usescript["sc_start"][0],
                                                      i.usescript["sc_start"][1],
                                                      i.usescript["sc_start"][2])

    # Bonus
    if "bonus" in i.equipscript:
        returnstring += '<br />Bonus: %s %d' % (i.equipscript["bonus"][0],
                                                i.equipscript["bonus"][1])

    # Do not return the first instance of the <br /> tag
    return returnstring[6:] + '\n'

def tablestart(title, text):
    sys.stdout.write('== %s ==\n' % title)
    sys.stdout.write('%s\n' % text)
    sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%"\n')

def tableend():
    sys.stdout.write('|}\n\n')

    
def printhealitems(items, title):
    tablestart(title, 'Sorted by combined HP and SP effect.')
    for title in health_titles:
        sys.stdout.write('! style="background:#efdead;" | %s\n' % title)
        
    for i in items:
        sys.stdout.write('|-\n')
        sys.stdout.write('| style="text-align:center;" | %s\n' % i.imgurl)
        sys.stdout.write('| %s\n' % i.clientname)
        sys.stdout.write( getidstring(i.id) )
        sys.stdout.write('| style="text-align:center;" | %d\n' % i.usescript["itemheal"][0])
        sys.stdout.write('| style="text-align:center;" | %d\n' % i.usescript["itemheal"][1])
        sys.stdout.write( getmoneystring(i.price,i.sell) )
        sys.stdout.write('| style="text-align:center;" | %d\n' % i.weight)
        sys.stdout.write('| %s\n' % i.description)
        sys.stdout.write('| ' + getextrainfostring(i))
    tableend()

            
def printstatusitems(items, title):
    tablestart(title, 'Sorted by price.')
    for title in status_titles:
        sys.stdout.write('! style="background:#efdead;" | %s\n' % title)
        
    for i in items:
        sys.stdout.write('|-\n')
        sys.stdout.write('| style="text-align:center;" | %s\n' % i.imgurl)
        sys.stdout.write('| %s\n' % i.clientname)
        sys.stdout.write( getidstring(i.id) )
        sys.stdout.write('| style="text-align:center;" | %s\n' % i.usescript["sc_start"][0])
        sys.stdout.write('| style="text-align:center;" | %s\n' % i.usescript["sc_start"][1])
        sys.stdout.write('| style="text-align:center;" | %s\n' % i.usescript["sc_start"][2])
        sys.stdout.write( getmoneystring(i.price,i.sell) )
        sys.stdout.write('| style="text-align:center;" | %d\n' % i.weight)
        sys.stdout.write('| %s\n' % i.description)
        sys.stdout.write('| ' + getextrainfostring(i))
    tableend()
            

def printweaponitems(items, title):
    tablestart(title, 'Sorted by attack.')
    for title in weapon_titles:
        sys.stdout.write('! style="background:#efdead;" | %s\n' % title)

    for i in items:
        sys.stdout.write('|-\n')
        sys.stdout.write('| style="text-align:center;" | %s\n' % i.imgurl)
        sys.stdout.write('| %s\n' % i.clientname)
        sys.stdout.write( getidstring(i.id) )
        sys.stdout.write('| style="text-align:center;" | %d (%d)\n' % (i.attack,i.range))
        sys.stdout.write( getmoneystring(i.price,i.sell) )
        sys.stdout.write('| style="text-align:center;" | %d\n' % i.weight)
        sys.stdout.write('| %s\n' % i.description)
        sys.stdout.write('| ' + getextrainfostring(i))
    tableend()
    

def printarmoritems(items, title):
    tablestart(title, 'Sorted by defence.')
    for title in armor_titles:
        sys.stdout.write('! style="background:#efdead;" | %s\n' % title)

    for i in items:
        sys.stdout.write('|-\n')
        sys.stdout.write('| style="text-align:center;" | %s\n' % i.imgurl)
        sys.stdout.write('| %s\n' % i.clientname)
        sys.stdout.write( getidstring(i.id) )
        sys.stdout.write('| style="text-align:center;" | %d%%\n' % i.defense)
        sys.stdout.write( getmoneystring(i.price,i.sell) )
        sys.stdout.write('| style="text-align:center;" | %d\n' % i.weight)
        sys.stdout.write('| %s\n' % i.description)
        sys.stdout.write('| ' + getextrainfostring(i))
    tableend()


def printotheritems(items, title):
    tablestart(title, 'Sorted by ID.')
    for title in other_titles:
        sys.stdout.write('! style="background:#efdead;" | %s\n' % title)

    for i in items:
        sys.stdout.write('|-\n')
        sys.stdout.write('| style="text-align:center;" | %s\n' % i.imgurl)
        sys.stdout.write('| %s\n' % i.clientname)
        sys.stdout.write( getidstring(i.id) )
        sys.stdout.write( getmoneystring(i.price,i.sell) )
        sys.stdout.write('| style="text-align:center;" | %d\n' % i.weight)
        sys.stdout.write('| %s\n' % i.description)
        sys.stdout.write('| ' + getextrainfostring(i))
    tableend()

    

############
##        ##
##  MAIN  ##
##        ##
############

try:
    if len(sys.argv) == 1:
        item_db = "item_db.txt"
        item_xml = "items.xml"
    elif len(sys.argv) == 3:
        item_db = sys.argv[1]
        item_xml = sys.argv[2]
    else: 
        item_db = ''
        item_xml = ''
        sys.stdout.write("Wrong number of arguments\n")

    if item_db and not os.path.isfile(item_db):
        sys.stdout.write("File does not exist: %s\n" % item_db)
        item_db = ''
    if item_xml and not os.path.isfile(item_xml):
        sys.stdout.write("File does not exist: %s\n" % item_xml)
        item_db = ''
    
    if not (item_db and item_xml):
        sys.stdout.write("\nUSAGE:\n")
        sys.stdout.write("dbtowiki without any arguments will use item_db.txt and items.xml in the current directory.\n")
        sys.stdout.write("to specify custom files, call: dbtowiki <item_db> <item_xml>\n")
        exit(-1);
    else:
        if debug:
            log.append("Item-list [item_db] = %s" % item_db)
            log.append("Item-list [item_xml] = %s" % item_xml)
        f = open(item_db)
        items = parseitems(f);
        f = open(item_xml)
        citems = parsexmlitems(f);

        addclientinformation(items, citems)

        printwarningcomments()
        printintrotext()

        typedir = gettypedir(items)
        if len(typedir.healthy) > 0: printhealitems(typedir.healthy, "Health items")
        if len(typedir.status) > 0: printstatusitems(typedir.status, "Status items")
        if len(typedir.inspiring) > 0: printhealitems(typedir.inspiring, "Mana items")
        if len(typedir.other) > 0: printotheritems(typedir.other, "Other items")

        if len(typedir.onehandedweapons) > 0: printweaponitems(typedir.onehandedweapons, "One-handed weapons")
        if len(typedir.twohandedweapons) > 0: printweaponitems(typedir.twohandedweapons, "Two-handed weapons")
        if len(typedir.ammo) > 0: printweaponitems(typedir.ammo, "Ammo")

        if len(typedir.headarmor) > 0: printarmoritems(typedir.headarmor, "Head armor")
        if len(typedir.legarmor) > 0: printarmoritems(typedir.legarmor, "Leg armor")
        if len(typedir.chestarmor) > 0: printarmoritems(typedir.chestarmor, "Chest armor")
        if len(typedir.footarmor) > 0: printarmoritems(typedir.footarmor, "Foot armor")
        if len(typedir.handarmor) > 0: printarmoritems(typedir.handarmor, "Gloves")
        if len(typedir.shields) > 0: printarmoritems(typedir.shields, "Shields")
        if len(typedir.rings) > 0: printarmoritems(typedir.rings, "Rings")

finally:
    printlog()