QModelIndex SceneLayersModel::index(int row, int column,const QModelIndex &parent) const {
  if(!hasIndex(row,column,parent))
    return QModelIndex();

  if (!parent.isValid()) { // Top level: layers
    GlLayer* layer = _scene->getLayersList()[row].second;
    assert(layer != NULL);
    return createIndex(row,column,layer);
  }

  GlComposite* composite = NULL;

  if (!parent.parent().isValid())  {// 1st sublevel, parent is a layer
    GlLayer *layer = reinterpret_cast<GlLayer*>(parent.internalPointer());
    composite = layer->getComposite();
  }
  else {  // Deeper sublevel, the parent is a composite
    composite = reinterpret_cast<GlComposite*>(parent.internalPointer());
  }

  if (_scene->getGlGraphComposite() == composite)
    return createIndex(row,column,GRAPH_COMPOSITE_IDS[row]);

  int i=0;
  std::map<std::string, GlSimpleEntity*> entities = composite->getGlEntities();

  for (std::map<std::string,GlSimpleEntity*>::iterator it = entities.begin(); it != entities.end(); ++it) {
    if (i++ == row)
      return createIndex(row,column,it->second);
  }

  return QModelIndex();
}
int SceneLayersModel::rowCount(const QModelIndex &parent) const {
  if (!parent.isValid()) { // Top level, layers count
    return _scene->getLayersList().size();
  }

  if (!parent.parent().isValid()) {// First sublevel: parent is a GlLayer
    GlLayer* layer = reinterpret_cast<GlLayer*>(parent.internalPointer());
    return layer->getComposite()->getGlEntities().size();
  }

  if (GRAPH_COMPOSITE_IDS.contains(parent.internalId()))
    return 0;

  GlSimpleEntity* entity = reinterpret_cast<GlSimpleEntity*>(parent.internalPointer());

  if (_scene->getGlGraphComposite() == entity)
    return GRAPH_COMPOSITE_IDS.size();

  if (dynamic_cast<GlComposite*>(entity) != NULL)
    return static_cast<GlComposite*>(entity)->getGlEntities().size();

  return 0;
}
bool SceneLayersModel::setData(const QModelIndex &index, const QVariant &value, int role) {
  if (index.column() == 0 || role != Qt::CheckStateRole)
    return false;

  if (GRAPH_COMPOSITE_IDS.contains(index.internalId())) {
    quint32 id = index.internalId();
    GlGraphRenderingParameters* p = _scene->getGlGraphComposite()->getRenderingParametersPointer();

    if (index.column() == 1) {
      bool visible = value.value<int>() == (int)(Qt::Checked);

      if (id == NODES_ID)
        p->setDisplayNodes(visible);
      else if (id == EDGES_ID)
        p->setDisplayEdges(visible);
      else if (id == META_NODES_ID)
        p->setDisplayMetaNodes(visible);
      else if (id == NODES_LABELS_ID)
        p->setViewNodeLabel(visible);
      else if (id == EDGES_LABELS_ID)
        p->setViewEdgeLabel(visible);
      else if (id == META_NODES_LABELS_ID)
        p->setViewMetaLabel(visible);
    }
    else if (index.column() == 2) {
      int stencil = (value.value<int>() == (int)(Qt::Checked) ? FULL_STENCIL : NO_STENCIL);

      if (id == NODES_ID)
        p->setNodesStencil(stencil);
      else if (id == EDGES_ID)
        p->setEdgesStencil(stencil);
      else if (id == SELECTED_NODES_ID)
        p->setSelectedNodesStencil(stencil);
      else if (id == SELECTED_EDGES_ID)
        p->setSelectedEdgesStencil(stencil);
      else if (id == META_NODES_ID)
        p->setMetaNodesStencil(stencil);
      else if (id == SELECTED_META_NODES_ID)
        p->setSelectedMetaNodesStencil(stencil);
      else if (id == META_NODES_LABELS_ID)
        p->setMetaNodesLabelStencil(stencil);
      else if (id == NODES_LABELS_ID)
        p->setNodesLabelStencil(stencil);
      else if (id == EDGES_LABELS_ID)
        p->setEdgesLabelStencil(stencil);
    }

    emit drawNeeded(_scene);
    return true;
  }

  GlSimpleEntity* entity = NULL;
  GlLayer* layer = NULL;

  if (!index.parent().isValid()) {
    layer = reinterpret_cast<GlLayer*>(index.internalPointer());
    entity = layer->getComposite();
  }
  else
    entity = reinterpret_cast<GlSimpleEntity*>(index.internalPointer());

  bool val = value.value<int>() == (int)Qt::Checked;

  if (index.column() == 1) {
    if (layer)
      layer->setVisible(val);

    entity->setVisible(val);
  }
  else if (index.column() == 2)
    entity->setStencil(val ? FULL_STENCIL : 0xFFFF);

  emit drawNeeded(_scene);
  return true;
}
QVariant SceneLayersModel::data(const QModelIndex &index, int role) const {
  GlComposite* parent = NULL;
  GlSimpleEntity* entity = NULL;
  GlLayer* layer = NULL;

  if (GRAPH_COMPOSITE_IDS.contains(index.internalId())) {
    quint32 id = index.internalId();
    GlGraphRenderingParameters* parameters = _scene->getGlGraphComposite()->getRenderingParametersPointer();
    QString display;
    int stencil = NO_STENCIL;
    bool visible = false;

    if (id == NODES_ID) {
      display = trUtf8("Nodes");
      stencil = parameters->getNodesStencil();
      visible = parameters->isDisplayNodes();
    }
    else if (id == EDGES_ID) {
      display = trUtf8("Edges");
      stencil = parameters->getEdgesStencil();
      visible = parameters->isDisplayEdges();
    }
    else if (id == SELECTED_NODES_ID) {
      display = trUtf8("Selected nodes");
      stencil = parameters->getSelectedNodesStencil();
      visible = parameters->isDisplayNodes();
    }
    else if (id == SELECTED_EDGES_ID) {
      display = trUtf8("Selected edges");
      stencil = parameters->getSelectedEdgesStencil();
      visible = parameters->isDisplayEdges();
    }
    else if (id == META_NODES_ID) {
      display = trUtf8("Meta nodes content");
      stencil = parameters->getMetaNodesStencil();
      visible = parameters->isDisplayMetaNodes();
    }
    else if (id == SELECTED_META_NODES_ID) {
      display = trUtf8("Selected meta nodes");
      stencil = parameters->getSelectedMetaNodesStencil();
      visible = parameters->isDisplayMetaNodes();
    }
    else if (id == META_NODES_LABELS_ID) {
      display = trUtf8("Meta nodes content labels");
      stencil = parameters->getMetaNodesLabelStencil();
      visible = parameters->isViewMetaLabel();
    }
    else if (id == NODES_LABELS_ID) {
      display = trUtf8("Nodes labels");
      stencil = parameters->getNodesLabelStencil();
      visible = parameters->isViewNodeLabel();
    }
    else if (id == EDGES_LABELS_ID) {
      display = trUtf8("Edges labels");
      stencil = parameters->getEdgesLabelStencil();
      visible = parameters->isViewEdgeLabel();
    }

    if (role == Qt::DisplayRole && index.column() == 0)
      return display;

    if (role == Qt::CheckStateRole) {
      if (index.column() == 1)
        return (visible ? Qt::Checked : Qt::Unchecked);

      if (index.column() == 2)
        return (stencil == NO_STENCIL ? Qt::Unchecked : Qt::Checked);
    }

    return QVariant();
  }

  if (!index.parent().isValid()) {
    layer = reinterpret_cast<GlLayer*>(index.internalPointer());
    entity = layer->getComposite();
  }
  else {
    entity = reinterpret_cast<GlSimpleEntity*>(index.internalPointer());
    parent = entity->getParent();
  }

  if (role == Qt::DisplayRole && index.column() == 0) {
    if (layer != NULL)
      return layer->getName().c_str();

    std::map<std::string, GlSimpleEntity*> siblings = parent->getGlEntities();

    for(std::map<std::string, GlSimpleEntity*>::iterator it = siblings.begin(); it != siblings.end(); ++it) {
      if (it->second == entity)
        return it->first.c_str();
    }
  }

  if (role == Qt::FontRole && layer != NULL) {
    QFont f;
    f.setBold(true);
    return f;
  }

  if (role == Qt::CheckStateRole) {
    if (index.column() == 1)
      return (entity->isVisible() ? Qt::Checked : Qt::Unchecked);

    if (index.column() == 2)
      return (entity->getStencil() == NO_STENCIL ? Qt::Unchecked : Qt::Checked);
  }

  if (role == Qt::TextAlignmentRole && index.column() != 0)
    return Qt::AlignCenter;

  return QVariant();
}