#!/usr/bin/python

# attrmap.py
#       --copyright--                   Copyright 2007 (C) Tranzoa, Co. All rights reserved.    Warranty: You're free and on your own here. This code is not necessarily up-to-date or of public quality.
#       --url--                         http://www.tranzoa.net/tzpython/
#       --email--                       pycode is the name to send to. tranzoa.com is the place to send to.
#       --bodstamps--
#       July 20, 2003           bar
#       August 5, 2003          bar     allow no class to be given to convert_map_to_attributes
#       November 18, 2007       bar     turn on doxygen
#       November 27, 2007       bar     insert boilerplate copyright
#       May 17, 2008            bar     email adr
#       May 27, 2012            bar     doxygen namespace
#       --eodstamps--
##      \file
#       \namespace              tzpython.attrmap
#
#
#       Convert objects between attribute and map formats.
#
#       E.g. If an object looks like this:
#
#           o.x = 1
#           o.y = 2
#
#         then, converted, it looks like this:
#
#           o['x'] = 1
#           o['y'] = 2
#
#
#         and vice versa.
#
#
#       We take arrays of these things, too.
#
#
#

from    types                   import  ListType, TupleType, DictionaryType


__ALL__ = [
            'convert_attributes_to_map',
            'convert_map_to_attributes',
          ]



def convert_attributes_to_map(me) :
    """
        Convert an object that has information stored in attributes in to a map/dictionary with the attribute names are the keys.
    """
    if  isinstance(me, DictionaryType)    :   return(me)

    you = {}
    if  isinstance(me, ListType) or isinstance(me, TupleType) :
        you = []
        for i in me :
            you.append(convert_attributes_to_map(i))            # yes, the caller could screw up if the entries in the array are not simple objects or are already maps, etc.
        pass
    else :
        for a in dir(me) :
            if  a[0:2] != '__' :
                you[a] = getattr(me, a)
            pass
        pass

    return(you)


def convert_map_to_attributes(me, cls = None) :
    """
        Convert a map/dictionary object to an object with attributes containing values.
    """

    class   a_thang :
        pass


    if  cls == None :
        cls = a_thang


    you = None

    if  isinstance(me, ListType) or isinstance(me, TupleType) :
        you = []
        for i in me :
            you.append(convert_map_to_attributes(i, cls))       # yes, the caller could screw up if the entries in the array are not maps
        pass
    else :
        if  not isinstance(me, DictionaryType)    :   return(me)

        you = cls()

        for a in me.keys() :                                    # yes the caller could screw up if the map has a key starting with double underscores
            setattr(you, a, me[a])
            pass
        pass

    return(you)


#
#
#       Test
#
#
if __name__ == '__main__' :
    class   a_thang :
        def __init__(me) :
            me.something = 'else'

        pass

    ma = [ { 'now':'is', '_the':'time' }, {'for':'all'} ]
    aa = convert_map_to_attributes(ma, a_thang)

    for t in aa :
        for a in dir(t) :
            if  a[0:2] != '__' :
                print a, getattr(t, a)
            pass
        pass

    am = convert_attributes_to_map(aa)

    print am

    aa = convert_map_to_attributes(aa)
    am = convert_attributes_to_map(aa)

    print am

    pass


#
#
#
# eof
