{{
import datetime
import malcat
import itertools
from helpers import naturalsize

DD_NAMES = [
"Export Table",
"Import Table",
"Resource Directory",
"Exception Table",
"Certificate Table",
"Relocation Table",
"Debug Data",
"Architecture",
"Global Pointer",
"TLS Table",
"Load Config Table",
"Bound Import Table",
"Import Address Table",
"Delay Import Descriptor",
"CLR Runtime",
"Unused"
]



def pval(key, val=None, fmt="{}", va=False, fa=False, rva=False, size=False, kalign=30, valign=0, formated=False):
    r = "[normal]{}[/normal]:".format(key)
    lr = len(r) - 17
    if lr < kalign:
        r += (" "*(kalign-lr))
    if isinstance(val, malcat.StructAccess) or isinstance(val, malcat.FieldAccess):
        if val.has_enum and val.enum:
            d = "[color6]{}[/color6]([dim]{}[/dim])".format(val.enum, fmt.format(val.value))
            formated = True
            ld = len(d) - len("[color3][/color3][dim][/dim]")
        else:
            if size:
                d = naturalsize(val.value, binary=True)
            else:
                toprint = val.value
                if type(toprint) == str:
                    toprint = toprint.replace("[", "\\[")
                d = fmt.format(toprint)
            ld = len(d)
        val = val.value
    elif size and type(val) == int:
        d = naturalsize(val, binary=True)
        ld = len(d)
    else:
        d = fmt.format(val)
        ld = len(d)
    if not formated:
        if type(val) == int: 
            if val == 0:
                grp = "dim"
            elif fa:
                grp = "fa"
            elif rva:
                grp = "rva"
            elif va:
                grp = "va"
            else:
                grp = "normal"
        else:
            grp = "normal"
        d = "[{}]{}[/{}]".format(grp,d,grp)
    if ld < valign:
        d += (" "*(valign-ld))
    write(r+d)  

def bitfieldpp(fa):
    s = []
    for i in range(fa.count - 1, -1, -1):
        bit = fa.at(i)
        if bit.value:
            s.append("[color5]{}[/color5]([dim]{:X}[/dim])".format(bit.name, 1 << i))
    if s:
        return  " + ".join(s)
    else:
        return "[dim]0[/dim]"

def pbitfield(key, fa, kalign=30):    
    r = "[normal]{}[/normal]:".format(key)
    lr = len(r) - 17
    if lr < kalign:
        r += (" "*(kalign-lr))
    write(r + bitfieldpp(fa))


def display_entropy(start, size):
    if start is None or size <= 0:
        return " "
    entropy = analysis.entropy[start:start+size]
    return "[ent-{val}:{ent}] [/ent-{val}]".format(val=entropy//4, ent=entropy)
}}
[color1]DEX Header[/color1]
  {{ pval("File Size", analysis.struct.DexHeader.FileSize, size=True, valign=24) }} {{ pval("Endianeness", analysis.parser.lsb and "LSB" or "MSB") }} 
  {{ pval("Data Offset", analysis.struct.DexHeader.DataOffset, "{:08x}", fa=True, valign=24) }} {{ pval("Data Size",  analysis.struct.DexHeader.DataSize, size=True) }} 
  {{ pval("Strings Offset", analysis.struct.DexHeader.StringsOffset, "{:08x}", fa=True, valign=24) }} {{ pval("Strings Count",  analysis.struct.DexHeader.StringsCount) }} 
  {{ pval("Types Offset", analysis.struct.DexHeader.TypesOffset, "{:08x}", fa=True, valign=24) }} {{ pval("Types Count",  analysis.struct.DexHeader.TypesCount) }} 
  {{ pval("Proto Offset", analysis.struct.DexHeader.ProtoOffset, "{:08x}", fa=True, valign=24) }} {{ pval("Proto Count",  analysis.struct.DexHeader.ProtoCount) }} 
  {{ pval("Fields Offset", analysis.struct.DexHeader.FieldsOffset, "{:08x}", fa=True, valign=24) }} {{ pval("Fields Count",  analysis.struct.DexHeader.FieldsCount) }} 
  {{ pval("Methods Offset", analysis.struct.DexHeader.MethodsOffset, "{:08x}", fa=True, valign=24) }} {{ pval("Methods Count",  analysis.struct.DexHeader.MethodsCount) }} 
  {{ pval("Classes Offset", analysis.struct.DexHeader.ClassesOffset, "{:08x}", fa=True, valign=24) }} {{ pval("Classes Count",  analysis.struct.DexHeader.ClassesCount) }} 
