'''
obj_bonus.py

A module for allowing objects to provide bonuses to their wearer. Kind of like
how magical effects typically work on muds.
'''
import mud, hooks, storage, auxiliary, mudsys



################################################################################
# auxiliary data
################################################################################
class ObjBonusAuxData:
    def __init__(self, sset = None):
        self.bonus = { }
        if sset != None:
            for one_set in sset.readList("bonus").sets():
                self.bonus[one_set.readString("type")] = one_set.readDouble("amnt")

    def copyTo(self, to):
        to.bonus = { }
        for key, val in self.bonus.iteritems():
            to[key] = val

    def copy(self):
        newdata = ActAuxData()
        self.copyTo(newdata)
        return newdata

    def store(self):
        set     = storage.StorageSet()
        bonuses = storage.StorageList()
        set.storeList("bonus", bonuses)

        for key, val in self.bonus.iteritems():
            oneset = storage.StorageSet()
            oneset.storeString("type", key)
            oneset.storeDouble("amnt", val)
            bonuses.add(oneset)

        return set



################################################################################
# obj bonus methods
################################################################################
def set_obj_bonus(obj, key, val):
    '''sets an object bonus to the object. Key must be a string, and val must
       be a double value.'''
    obj.getAuxiliary("obj_bonus_data").bonus[str(key)] = float(val)

def del_obj_bonus(obj, key):
    '''Deletes a bonus from the object.'''
    if obj.getAuxiliary("obj_bonus_data").bonus.has_key(key):
        obj.getAuxiliary("obj_bonus_data").bonus.pop(key)



################################################################################
# hooks
################################################################################
def obj_bonus_wear_hook(info):
    '''apply our objects bonuses to the wearer'''
    ch, obj = hooks.parse_info(info)
    data    = obj.getAuxiliary("obj_bonus_data")
    for key, val in data.bonus.iteritems():
        ch.add_modifier(key, val)

def obj_bonus_remove_hook(info):
    '''remove our object bonuses from the wearer'''
    ch, obj = hooks.parse_info(info)
    data    = obj.getAuxiliary("obj_bonus_data")
    for key, val in data.bonus.iteritems():
        ch.add_modifier(key, -val)
        
def obj_bonus_to_game_hook(info):
    '''If we have loaded into the game on someone, make sure we apply our
       bonuses.'''
    obj, = hooks.parse_info(info)
    data = obj.getAuxiliary("obj_bonus_data")
    if obj.wearer != None:
        for key, val in data.bonus.iteritems():
            obj.wearer.add_modifier(key, val)

def append_obj_bonus_hook(info):
    obj, ch = hooks.parse_info(info)
    data    = obj.getAuxiliary("obj_bonus_data")
    buf = ", ".join([key+" by "+str(val) for key,val in data.bonus.iteritems()])

    if len(buf) > 0:
        ch.look_buf += " This item affects your " + buf + ". " 



################################################################################
# initialization
################################################################################
auxiliary.install("obj_bonus_data", ObjBonusAuxData, "object")

# set up our hooks
hooks.add("wear",            obj_bonus_wear_hook)
hooks.add("remove",          obj_bonus_remove_hook)
hooks.add("obj_to_game",     obj_bonus_to_game_hook)
hooks.add("append_obj_desc", append_obj_bonus_hook)

# provide some functionality for scripting
mud.set_obj_bonus = set_obj_bonus
mud.del_obj_bonus = del_obj_bonus