#include "scene.h"



Scene::Scene(      )
{
    root = new SceneNode();
    root->setName("<NONE>");
    active = root;
    activeIndex = QModelIndex();
}

Scene::~Scene(      )
{
    delete root;
}

int Scene::simpleScene()
{
    addCube();
    moveActive(QVector3D(4,0,0));

    addSphere();
    moveActive(QVector3D(1.5,0,0));

    addCylinder();
    moveActive(QVector3D(0,1.5,-1.5));

    addNode();

    addTorus();
    moveActive(QVector3D(0,0,-3));

    addCone();
    moveActive(QVector3D(0,-1.5,-1.5));

    return active->getID();

}

void Scene::addSceneObjectTaActive(SceneObject *obj){

    SceneNode* parent;
    QModelIndex parentIndex;


    if(active->isNode()){
        parent = static_cast<SceneNode*>(active);
        parentIndex = activeIndex;

    } else {
        parent  = static_cast<SceneNode*>(active->getParent());
        parentIndex = activeIndex.parent();
    }

    beginInsertRows(parentIndex, parent->childCount(), parent->childCount());
    parent->add(obj);
    obj->setParent(parent);
    endInsertRows();

    activeIndex = index(parent->childCount()-1,0,parentIndex);
    active = obj;
    qDebug()<<"Adding"<<obj->getName()<<" to "<<getItem(parentIndex)->getName()<<" Active"<<getItem(activeIndex)->getName();

    emit activChanged();
}

void Scene::addCube()
{
    float color[] = {0.0,0.0,1.0};
    ScenePrimitive *primitive = new ScenePrimitive(PrimitiveType::Quader,tesselation);
    primitive->setMaterial(color);
    addSceneObjectTaActive(primitive);
}

void Scene::addSphere()
{
    float color[] = {0.0,1.0,0.0};
    ScenePrimitive *primitive = new ScenePrimitive(PrimitiveType::Sphere,tesselation);
    primitive->setMaterial(color);
addSceneObjectTaActive(primitive);
}

void Scene::addCylinder()
{
    float color[] = {1.0,0.0,0.0};
    ScenePrimitive *primitive = new ScenePrimitive(PrimitiveType::Cylinder,tesselation);
    primitive->setMaterial(color);
    addSceneObjectTaActive(primitive);
}

void Scene::addTorus()
{
    float color[] = {1.0,0.0,1.0};
    ScenePrimitive *primitive = new ScenePrimitive(PrimitiveType::Torus,tesselation);
    primitive->setMaterial(color);
    addSceneObjectTaActive(primitive);
}

void Scene::addCone()
{
    float color[] = {0.0,1.0,1.0};
    ScenePrimitive *primitive = new ScenePrimitive(PrimitiveType::Cone,tesselation);
    primitive->setMaterial(color);
    addSceneObjectTaActive(primitive);
}

void Scene::addNode()
{
    SceneNode *node = new SceneNode();
    node->setName("Graph Node");

    addSceneObjectTaActive(node);
}

void Scene::deletActive()
{
    QModelIndex parentIndex = activeIndex.parent();

    SceneNode *parent  = static_cast<SceneNode*>(active->getParent());

    int pos = active->childNumber();
    qDebug()<<"Delet Active in Scene"<<parentIndex<<parent->childCount()<<pos;
    foreach (SceneObject * t, parent->getChildren()) {
        qDebug()<<t->getName()<<t->childNumber();
    }

    beginRemoveRows(parentIndex, pos, pos);
    parent->remove(pos);
    endRemoveRows();
    active = parent;
    activeIndex = parentIndex;
    qDebug()<<"Delet Active in Scene"<<active<<activeIndex<<active->getName();

    emit activChanged();

}




void Scene::setTesselation(int tesselation)
{
    this->tesselation = tesselation;
}

SceneObject *Scene::setActive(int id){
    active = root->find(id);
    emit activChanged();
    return active;
}

SceneObject *Scene::getActive(){
    return active;
}

void Scene::draw(QGLShaderProgram *shader)
{
    root->draw(shader);
}

SceneNode *Scene::getRoot()
{
    return root;
}

void Scene::moveActive(QVector3D dir)
{
    if(active != NULL)
        active->move(dir);

}

void Scene::rotateActive(QQuaternion rot)
{
    if(active != NULL)
        active->rotate(rot);
}

//Model funktions
SceneObject *Scene::getItem(const QModelIndex &index) const
{
    if (index.isValid()) {
        SceneObject *item = static_cast<SceneObject*>(index.internalPointer());
        if (item)
            return item;
    }
    return root;
}

int Scene::rowCount(const QModelIndex &parent) const
{
    SceneObject *parentItem = getItem(parent);
   // qDebug()<<"ChildCount:"<<parentItem->childCount();

    return parentItem->childCount();
}

int Scene::columnCount(const QModelIndex & parent ) const
{
    SceneObject *item = getItem(parent);

   // qDebug()<<"ColumnCount:"<<item->columnCount();
    return item->columnCount();
}

Qt::ItemFlags Scene::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return 0;

    return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
}

QModelIndex Scene::index(int row, int column, const QModelIndex &parent) const
{
    if (parent.isValid() && parent.column() != 0)
        return QModelIndex();

    SceneObject *parentItem = getItem(parent);

    SceneObject *childItem = parentItem->children(row);
    if (childItem)
        return createIndex(row, column, childItem);
    else
        return QModelIndex();
}

QModelIndex Scene::parent(const QModelIndex &index) const
{
    if (!index.isValid())
        return QModelIndex();

    SceneObject *childItem = getItem(index);
    SceneObject *parentItem = childItem->getParent();

    if (parentItem == root)
        return QModelIndex();

    return createIndex(parentItem->childNumber(), 0, parentItem);
}

QVariant Scene::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    if (role != Qt::DisplayRole && role != Qt::EditRole)
        return QVariant();

    SceneObject *item = getItem(index);

    return item->data(index.column());
}

QVariant Scene::headerData(int section, Qt::Orientation orientation,
                               int role) const
{

    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
        return root->data(section);

    return QVariant();
}


void Scene::objectSelected(QModelIndex index)
{

    activeIndex = index;
    active = getItem(index);
    emit activChanged();

}

