import struct

try:
   from collections import OrderedDict
except:
   from ordereddict import OrderedDict

odict=OrderedDict

def sizeof(st):
   return struct.calcsize("<"+"".join(st.values()))

#def getStruct(st, raw):
#   r=struct.unpack("<"+"".join(st.values()))
#   return odict(zip(st.keys(), r))

def getStruct(st, raw, mod):
   r=struct.unpack("<"+"".join(st.values()), raw)
   d1=odict(zip(odict(st.keys()).keys(), r))
   for k in st.keys():
      if k[1] == 'zerotstr':
         d1[k[0]] = ztstr(d1[k[0]])
      elif k[1].startswith('bitarray:'):
         ba=bitarray(endian='little')
         ba.fromstring(d1[k[0]])
         try:
            myl=dir(mod)[k[1].split(':')[1]]
         except:
            myl=['b'+str(x) for x in xrange(0, ba.length() )]
         myl.reverse() # Little endianess!
         myod=odict(zip(myl, ba))
         items=myod.items()
         items.reverse()
         d1[k[0]] = items

      elif k[1].startswith('struct:'):
         try:
            d1[k[0]] = getStruct(dir(mod)[k[1].split(':')[1]], d1[k[0]])
         except:
            pass

   return d1


#def setStruct(st, values):
#   return struct.pack("<"+"".join(st.values()), *values)

def setStruct(st, values, mod):
   for k in st.keys():
      if k[1] == 'zerotstr':
         values[k[0]]=values[k[0]].ljust(int(st[k][:-1]), '\x00')
      elif k[1].startswith('bitarray:'):
         myl=values[k[0]].values()
         myl.reverse()
         values[k[0]]=bitarray(myl, endian='little').tostring()
      elif k[1].startswith('struct:'):
         values[k[0]] = setStruct(dir(mod)[k[1].split(':')[1]], values[k[0]])

   return struct.pack("<"+"".join(st.values()), *values.values())


def ztstr(value):
   return value.split('\x00')[0]


