#include <QDropEvent>
#include <QDragMoveEvent>
#include <QDragEnterEvent>
#include <QMimeData>
#include<QList>
#include "viteqtreewidget.hpp"
#include "stdio.h"
 
viteQTreeWidget::viteQTreeWidget(QWidget *parent)
    : QTreeWidget(parent)
{
 
}

    viteQTreeWidget::~viteQTreeWidget() = default;

void viteQTreeWidget::dropEvent(QDropEvent *e){

       
    //we want to avoid to destroy the hierarchy of the trace, so let's only move containers near a container with the same parent 

    
    //QTreeWidgetItem* item= itemAt(event->pos());//get the item where we want to move
    //printf("drop %s to %s!\n", );

         //   const QPoint pos = e->pos();
            QTreeWidgetItem* target = itemAt(e->pos());
            
            if(target==nullptr){
                e->ignore();
                return;
            }

            bool do_move = true;

            // this is used to determine if the target is itself a child
          
                foreach(QTreeWidgetItem* item, selected_items)
                {

                    // if target and item don't share the same parent...
                    if(target->parent() != item->parent())
                    {
                        // ...then don't allow the move
                        do_move = false;
                        break;
                    }
                    
                    if(target==item){
                        // ...do nothing
                        do_move = false;
                        break;
                    }
                    
                }
          

            if(!do_move)
                e->setDropAction(Qt::IgnoreAction);
            else
            {
                //QTreeWidget::dropEvent(e);
                int index=0;
                if(target->parent())
                index=target->parent()->indexOfChild(target);
                else
                index = indexOfTopLevelItem(target);
                
                int modifier=0;
                
                int initial_count=0;
                if(target->parent())
                initial_count=target->parent()->childCount();
                else
                initial_count=topLevelItemCount();
                
                //we want to insert below the pointed event
                foreach(QTreeWidgetItem* item, selected_items)
                {
                    //remove all items from their parent
                    
                   if(item->parent()) {
                        if(item->parent()->indexOfChild(item)<index)modifier++;
                        item->parent()->removeChild(item);
                    }else{
                        if(indexOfTopLevelItem(item)<index)modifier++; 
                        takeTopLevelItem(indexOfTopLevelItem(item));
                    }

                }
                //insert them again in the right position and order

                if(target->parent())
                index=target->parent()->indexOfChild(target);
                else
                index = indexOfTopLevelItem(target);
               
                int max=0;
                if(target->parent()){
                    if(index+modifier > target->parent()->childCount()){
                        max=target->parent()->childCount();
                        foreach(QTreeWidgetItem* item, selected_items)
                        {
                            target->parent()->insertChild(max, item);
                            max++;
                        } 
                    }else{
                        max=index+modifier;
                        target->parent()->insertChildren(max, selected_items); 
                    }
                }else{
                    if(index+modifier > topLevelItemCount()){
                        max=topLevelItemCount();
                        foreach(QTreeWidgetItem* item, selected_items)
                        {
                            insertTopLevelItem(max, item);
                            max++;
                        }
                    } else{
                        max=index+modifier;
                        	insertTopLevelItems(max,selected_items); 
                }
                    
                    }
                    
               int count=0;
                if(target->parent())
                    count=target->parent()->childCount();
                else
                    count=topLevelItemCount();
                                
                if (count!=initial_count){
                   //prevent loss of elements if insertions failed (can happen sometimes)
                   //try to reinsert all elements at the end
                    foreach(QTreeWidgetItem* item, selected_items)
                    {
                        if(target->parent())
                            target->parent()->insertChild(target->parent()->childCount(), item);
                        else
                            insertTopLevelItem(topLevelItemCount(), item);
                    }
                    
                }
                e->setDropAction(Qt::TargetMoveAction);
            }

            e->accept();
            selected_items.clear();
    
    }
    


void viteQTreeWidget::dragEnterEvent(QDragEnterEvent *event)
{
            selected_items = selectedItems();
            if (event->source() == this)
            {
                event->setDropAction(Qt::MoveAction);
                event->accept();
            }
            else
                event->acceptProposedAction();

}

void viteQTreeWidget::dragMoveEvent(QDragMoveEvent *e)
{
e->accept();	
}

QMimeData *viteQTreeWidget::mimeData(const QList<QTreeWidgetItem *>) const
{
return new QMimeData;
}

bool viteQTreeWidget::dropMimeData ( QTreeWidgetItem * , int , const QMimeData * , Qt::DropAction  ) 
{
return true;
}

Qt::DropActions viteQTreeWidget::supportedDropActions () const
{
return Qt::CopyAction|Qt::MoveAction;
}

