#!/bin/python

from prettytable import PrettyTable


class MBIOConfig(object):
    def __init__(self):
        self._data={}
        # self._updated=False

    def RAZ(self):
        while self._data:
            item=self._data.popitem()
            if item:
                name=item[0]
                self.delete(name)

    def reinit(self, name=None):
        if self.isData(name):
            setattr(self, name, self._data[name])
            return self.get(name)

        for name in self._data.keys():
            setattr(self, name, self._data[name])

    def reset(self):
        if self.isData(name):
            setattr(self, name, None)
            return self.get(name)

        for name in self._data.keys():
            setattr(self, name, None)

    def delete(self, name):
        if self.isData(name):
            try:
                delattr(self, name.lower())
                del(self._data[name])
            except:
                pass

    def updatedata(self, data):
        try:
            for name in data.keys():
                self.set(name, data[name])
        except:
            pass

    # Force return None if called with an unknown attribute (config name)
    def __getattr__(self, name):
        try:
            return getattr(self, name)
        except:
            pass
        return None

    def get(self, name, default=None):
        try:
            return getattr(self, name.lower())
        except:
            pass
        return default

    # def updated(self, reset=True):
        # if self._updated:
            # if reset:
                # self._updated=False
                # return True
        # return False

    def set(self, name, value=None):
        if name is not None:
            name=name.lower()
            # create the object's variable attribute
            setattr(self, name, value)
            # declare the value and keep it's initial value
            if not name in self._data:
                self._data[name]=value

    def declare(self, name):
        self.set(name, None)

    def isData(self, name):
        if name and name.lower() in self._data:
            return True
        return False

    def update(self, name, value):
        if value is not None and self.isData(name):
            self.set(name, value)

    def xmlUpdate(self, xml, name):
        data=xml.get(name)
        self.update(name, data)

    def xmlUpdateBool(self, xml, name):
        data=xml.getBool(name)
        self.update(name, data)

    def xmlUpdateFloat(self, xml, name, vmin=None, vmax=None):
        data=xml.getFloat(name, vmin=vmin, vmax=vmax)
        self.update(name, data)

    def xmlUpdateInt(self, xml, name, vmin=None, vmax=None):
        data=xml.getInt(name, vmin=vmin, vmax=vmax)
        self.update(name, data)

    def __getkey__(self, key):
        return self.get(key)

    def getBool(self, name, default=None):
        try:
            value=self.get(name)
            if type(value) is bool:
                return value
            if type(value) is int:
                return bool(value)
            if value.lower() in ['1', 'yes', 'true']:
                return True
            if value.lower() in ['0', 'no', 'false']:
                return False
        except:
            pass
        return default

    def contains(self, name, data):
        try:
            value=self.get(name)
            if data.lower() in value:
                return True
        except:
            return False

    def bool(self, name, default=None):
        return self.getBool(name, default)

    def getInt(self, name, default=None, vmin=None, vmax=None):
        try:
            value=int(self.get(name))
            if vmin is not None:
                value=max(value, int(vmin))
            if vmax is not None:
                value=min(value, int(vmax))
            return value
        except:
            pass
        return default

    def int(self, name, default=None):
        return self.getInt(name, default)

    def getFloat(self, name, default=None, vmin=None, vmax=None):
        try:
            value=float(self.get(name))
            if vmin is not None:
                value=max(value, int(vmin))
            if vmax is not None:
                value=min(value, int(vmax))
            return value
        except:
            pass
        return default

    def float(self, name, default=None):
        return self.getFloat(name, default)

    def count(self):
        return len(self._data)

    def __len__(self):
        return self.count()

    def all(self):
        data={}
        for name in self._data.keys():
            data[name]=getattr(self, name)
        return data

    def __iter__(self):
        return iter(self.all())

    def dump(self):
        t=PrettyTable()
        t.field_names=['Config', 'Value']
        t.align='l'

        for data in self._data:
            v=None
            try:
                v=getattr(self, data)
            except:
                pass
            t.add_row([data, v])

        print(t.get_string())

    def __repr__(self):
        return '%s(%d items)' % (self.__class__.__name__, self.count())


if __name__=='__main__':
    pass
