#include "internalnode.h"

#include "../virtualmodeladapter/virtualmodeladapter.h"

VirtualTreeModel::InternalNode::InternalNode(
    VirtualTreeModel::InternalNode *parent, void *obj, size_t index)
    : parent(parent), item(obj), parentIndex(index) {}

bool VirtualTreeModel::InternalNode::isInitialized(
    VirtualModelAdapter *adapter) {
  if (!childInitialized) {
    // if node children have not been added to model
    // but model asks node by hasChildren()
    // the only way to notify model about changes is to initialize node
    // children
    if (hasChildrenQueryed) {
      if (hasChildren != (adapter->getItemsCount(item) > 0))
        childInitialized = true;
    }
    return childInitialized;
  } else
    return true;
}

void VirtualTreeModel::InternalNode::loadChildren(
    VirtualModelAdapter *adapter) {
  if (!childInitialized) {
    if (adapter->hasItems(item)) {
      int childCount = adapter->getItemsCount(item);
      for (int k = 0; k < childCount; ++k)
        children.emplace_back(
            new InternalNode(this, adapter->getItem(item, k), k));
    }
    childInitialized = true;
  }
}

int VirtualTreeModel::InternalNode::childCount(VirtualModelAdapter *adapter) {
  loadChildren(adapter);
  return static_cast<int>(children.size());
}

void VirtualTreeModel::InternalNode::eraseChildren(
    const InternalChildren::iterator &begin,
    const InternalChildren::iterator &end) {
  size_t curParent = begin->get()->parentIndex;
  auto newEnd = children.erase(begin, end);
  for (auto it = newEnd; it != children.end(); ++it)
    it->get()->parentIndex = curParent++;
}

void VirtualTreeModel::InternalNode::insertedChildren(size_t lastIndex) {
  for (auto index = lastIndex; index < children.size(); ++index)
    children[index]->parentIndex = index;
}
