from PyQt4.QtGui import *
from PyQt4.QtCore import *
from logging import warning, debug, critical

from lechat.DataTree import DataTree

# TODO: get rid of TDBItem by accessing DataTree directly
class TDBItem:
    def __init__(self, data = None, parent = None):
        self._data = data
        self._parent = parent
        self._child = []

    def appendChild(self, item):
        item._parent = self
        self._child.append(item)

    def child(self, row):
        if self._child:
            return self._child[row]
        return None
    
    def childCount(self):
        return len(self._child)

    def data(self):
        return self._data

    def row(self):
        if self._parent:
            return self._parent._child.index(self)
        else:
            return 0

    def parent(self):
        return self._parent

class TDBBrowserModel(QAbstractItemModel):
    def __init__(self, tdb, parent = None):
        QAbstractItemModel.__init__(self, parent)
        self.root_item = None
        self._parent = parent
        self.indices = {}

        parent.ui.parent.entries_changed.addWatcher(self.updateDB)

    def __del__(self):
        parent.ui.parent.entries_changed.delWatcher(self.updateDB)

    def updateDB(self, filter_re = None):
        self.root_item = self.setupModelData( self._parent.ui.parent.entries, filter_re )
        self.indices = {}
        self.reset()
        
    def setupModelData(self, tdb, filter_re = None):
        if tdb.has_key('node'):
            node = tdb['node'].value[0]
        else:
            node = ''
        item = TDBItem(node)
        for k in [_k for _k in tdb.keys() if isinstance(tdb[_k], DataTree) ] :
            child = self.setupModelData(tdb[k], filter_re)
            if child:
                item.appendChild(child)
        if item.childCount() == 0 and (filter_re and not filter_re.search(node)):
            return None
        else:
            return item

    def data(self, index, role):
        if not index.isValid():
            return QVariant()

        item = self.indices[index.internalId()]

        if index.column() == 0:
            if role == Qt.DisplayRole:
                return QVariant( QString(item.data()) )
            elif role == Qt.DecorationRole:
                return QVariant( QIcon(":/lechat/resources/user.png") )
        elif index.column() == 1:
            if role == Qt.DecorationRole:
                return QVariant( QIcon(":/lechat/resources/trashcan_full.png") )

        return QVariant()
        

    def flags(self, index):
        if not index.isValid():
            return Qt.ItemIsEnabled

        return Qt.ItemIsEnabled | Qt.ItemIsSelectable

    def index(self, row, column, parent = QModelIndex()):
        if not parent.isValid():
            parent_item = self.root_item
        else:
            parent_item = self.indices[parent.internalId()]

        if not parent_item:
            return QModelIndex()

        child_item = parent_item.child(row)

        if child_item:
            self.indices[id(child_item)] = child_item
            result = self.createIndex(row, column, id(child_item))
            return result
        else:
            return QModelIndex()

    def parent(self, index):

        if not index.isValid():
            return QModelIndex()

        child_item = self.indices[index.internalId()]
        parent_item = child_item.parent()

        if not parent_item or parent_item == self.root_item:
            return QModelIndex()

        return self.createIndex(parent_item.row(), 0, id(parent_item))

    def rowCount(self, parent):
        if not parent.isValid():
            parent_item = self.root_item
        else:
            parent_item = self.indices[parent.internalId()]

        if not parent_item:
            return 0
        
        return parent_item.childCount()

    def columnCount(self, parent):
        return 3

    def headerData(self, section, orientation, role):
        if role != Qt.DisplayRole or orientation == Qt.Horizontal:
            return QVariant()
        return QVariant(section)

    def hasChildren(self, parent):
        if not parent.isValid():
            return True
        
        parent_item = parent.internalPointer()

        if len(parent_item._child) > 0:
            return True
        else:
            return False
    

