#include "wPictureList.h"
#include "ui_wPictureList.h"

#include <QDebug>
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDrag>
#include <QPainter>
#include "CAppInfo.h"

wPictureList::wPictureList(int nItemWidth, int nItemSpace, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::wPictureList),
    m_nItemWidth(nItemWidth),
    m_nItemSpace(nItemSpace),
    m_nColNum(6)
{
    ui->setupUi(this);

    setStyleSheet(g_appInfoPtr->m_sQssStr);

    m_isDragout = false;
    m_dargItemstr = "application/x-dnditemdata";
    setAcceptDrops(true);
}

wPictureList::~wPictureList()
{
    for_each(m_vPicList.begin(), m_vPicList.end(), [](wPictureItem *item){delete item;item=nullptr;});
    m_vPicList.clear();
    delete ui;
}

int wPictureList::setUI(const int nLeft, const int nTop, const int nWidth)
{
	int nRowNum = m_vPicList.size() / m_nColNum + (m_vPicList.size() % m_nColNum + m_nColNum - 1) / m_nColNum;
	setGeometry(nLeft, nTop, nWidth, nRowNum*(m_nItemWidth+ m_nItemSpace));
	return height();
}

void wPictureList::setColNum(int nColNum)
{
    m_nColNum = nColNum;
}

void wPictureList::clearPic()
{
	m_vPicList.clear();
}

void wPictureList::AddPic(QString sUrl)
{
    wPictureItem *item = new wPictureItem(sUrl, this);
    int nSize = m_vPicList.size();
    int nRow = nSize/m_nColNum;
    int nCol = nSize%m_nColNum;
    item->setUI((m_nItemWidth + m_nItemSpace)*nCol,nRow*(m_nItemWidth + m_nItemSpace), m_nItemWidth, m_nItemWidth);
    connect(item, &wPictureItem::viewPhoto, this, [&](QString sFileUrl)
    {
        QStringList list;
        int nIndex = 0;
        std::list<wPictureItem*>::iterator it = m_vPicList.begin();
        for (size_t i = 0; it != m_vPicList.end(); ++i,++it)
        {
            list<<(*it)->getUrl();
            if((*it)->getUrl() == sFileUrl)
            {
                nIndex = i;
            }
        }

        if(m_pViewPhoto == nullptr)
        {
            m_pViewPhoto = std::make_shared<widgetViewPhoto>(nIndex, list, g_appInfoPtr->m_pAnsBgWidget);
            connect(m_pViewPhoto.get(), &widgetViewPhoto::viewImgClose, this, [&](){
                m_pViewPhoto.reset();
            });
        }
        m_pViewPhoto->show();
    });

    connect(item, &wPictureItem::delFile, this, [&](QString sFileUrl)
    {
        for(std::list<wPictureItem*>::iterator it = m_vPicList.begin(); it != m_vPicList.end(); ++it)
        {
            if((*it)->getUrl() == sFileUrl)
            {
				wPictureItem* item = *it;
				delete item;
                m_vPicList.erase(it);
                break;
            }
        }

        std::list<wPictureItem*>::iterator it = m_vPicList.begin();
        for (size_t i = 0; i < m_vPicList.size(); ++i)
        {
            wPictureItem *item = *it;
            int nRow = i / m_nColNum;
            int nCol = i % m_nColNum;
            item->setGeometry((m_nItemWidth + m_nItemSpace)*nCol, nRow*(m_nItemWidth + m_nItemSpace), m_nItemWidth, m_nItemWidth);
            ++it;
        }
        emit picChange();
    });
	item->show();
    m_vPicList.push_back(item);
}

QString wPictureList::getFileUrls()
{
    QStringList list;
    for(std::list<wPictureItem*>::iterator it = m_vPicList.begin(); it != m_vPicList.end(); ++it)
    {
        list<<(*it)->getUrl();
    }
    return list.join(",");
}

void wPictureList::rePos(QPoint startPt, QPoint endPt)
{
    int nStartX = 0;
    int nEndX = 0;
    int nStartY = 0;
    int nEndY = 0;
    std::list<wPictureItem*>::iterator it = m_vPicList.begin();
    nStartX = startPt.x()/(m_nItemWidth + m_nItemSpace);
    if(startPt.x() <= endPt.x())
    {
        nEndX = abs(endPt.x()-startPt.x())/(m_nItemWidth + m_nItemSpace);
    }
    else
    {
        nEndX = (abs(endPt.x()-startPt.x()) + (m_nItemWidth + m_nItemSpace)/2)/(m_nItemWidth + m_nItemSpace);
    }

    nStartY = startPt.y()/(m_nItemWidth + m_nItemSpace);
    nEndY = (abs(endPt.y()-startPt.y()) + (m_nItemWidth + m_nItemSpace)/2)/(m_nItemWidth + m_nItemSpace);



    int nRowNum = m_vPicList.size()/m_nColNum + (m_vPicList.size()%m_nColNum + m_nColNum -1)/m_nColNum;
    if(startPt.x() < endPt.x())
    {
        if((nStartY+1)*m_nColNum > m_vPicList.size())
        {
            if(nStartX + nEndX > m_vPicList.size() - nStartY*m_nColNum - 1)
            {
                nEndX = m_vPicList.size() - nStartY*m_nColNum - nStartX -1;
            }
        }
        else
        {
            if(nStartX + nEndX > m_nColNum - 1)
            {
                nEndX = m_nColNum - nStartX -1;
            }
        }

        if(nEndY > 0 && startPt.y() > endPt.y())
        {//上移
            if(nEndY > nStartY)
            {
                nEndY = nStartY;
            }

            std::list<wPictureItem*>::iterator s = it;
            advance(s, nStartX + nStartY*m_nColNum - nEndY*m_nColNum + nEndX +1);
            std::list<wPictureItem*>::iterator s1 = it;
            advance(s1, nStartX + nStartY*m_nColNum);

            m_vPicList.splice(s, m_vPicList, s1);
        }
        else
        {
            if(nEndY > nRowNum - nStartY -1)
            {
                nEndY = nRowNum - nStartY -1;
            }

            std::list<wPictureItem*>::iterator s = it;
            advance(s, nStartX + nStartY*m_nColNum);
            std::list<wPictureItem*>::iterator s1 = it;
            advance(s1, nStartX + nStartY*m_nColNum+1);
            std::list<wPictureItem*>::iterator s2 = it;
            if(nStartX + nStartY*m_nColNum + nEndY*m_nColNum + nEndX + 1 > m_vPicList.size())
            {
                 advance(s2, m_vPicList.size());
            }
            else
            {
                advance(s2, nStartX + nStartY*m_nColNum + nEndY*m_nColNum + nEndX + 1);
            }

            m_vPicList.splice(s, m_vPicList, s1, s2);
        }
    }
    else
    {
        if(nEndX > 0 && nEndX > nStartX)
        {
            nEndX = nStartX;
        }

        if(nEndY > 0 && startPt.y() < endPt.y())
        {//下移
            if(nEndY > nRowNum - nStartY -1)
            {
                nEndY = nRowNum - nStartY -1;
            }
            std::list<wPictureItem*>::iterator s = it;
            advance(s, nStartX + nStartY*m_nColNum);
            std::list<wPictureItem*>::iterator s1 = it;
            advance(s1, nStartX + nStartY*m_nColNum+1);
            std::list<wPictureItem*>::iterator s2 = it;
            if(nStartX + nStartY*m_nColNum + nEndY*m_nColNum - nEndX  > m_vPicList.size())
            {
                advance(s2, m_vPicList.size());
            }
            else
            {
                advance(s2, nStartX + nStartY*m_nColNum + nEndY*m_nColNum - nEndX );
            }

            m_vPicList.splice(s, m_vPicList, s1, s2);
        }
        else
        {
            if(nEndY > nStartY)
            {
                nEndY = nStartY;
            }
            std::list<wPictureItem*>::iterator s = it;
            advance(s, nStartX + nStartY*m_nColNum - nEndY*m_nColNum - nEndX);
            std::list<wPictureItem*>::iterator s1 = it;
            advance(s1, nStartX + nStartY*m_nColNum);

            m_vPicList.splice(s, m_vPicList, s1);
        }
    }

    for_each(m_vPicList.begin(), m_vPicList.end(), [](wPictureItem *item){
        qDebug()<<item->getUrl();
    });

    it = m_vPicList.begin();
    for(size_t i = 0; i < m_vPicList.size(); ++i)
    {
        wPictureItem *item = *it;
        int nRow = i/m_nColNum;
        int nCol = i%m_nColNum;
        item->setGeometry((m_nItemWidth + m_nItemSpace)*nCol,nRow*(m_nItemWidth + m_nItemSpace), m_nItemWidth, m_nItemWidth);
        ++it;
    }

}


void  wPictureList::dragEnterEvent(QDragEnterEvent * event)
{
    if (event->mimeData()->hasFormat(m_dargItemstr))
    {
        m_isDragout = false;
//        highlightWidget(m_widget, event->pos());
        event->setDropAction(Qt::MoveAction);
        event->accept();
    }
    else {
        event->ignore();
    }
}


int wPictureList::itemCount() const
{
    return m_vPicList.size();
}

void  wPictureList::dragMoveEvent(QDragMoveEvent * event)
{
    if (event->mimeData()->hasFormat(m_dargItemstr))
    {
        m_isDragout = false;
//        highlightWidget(m_widget, event->pos());
        event->setDropAction(Qt::MoveAction);
        event->accept();
    }
    else {
        event->ignore();
    }
}

void  wPictureList::dragLeaveEvent(QDragLeaveEvent*)
{
    m_isDragout = true;
}

void  wPictureList::dropEvent(QDropEvent * event)
{
    if (event->mimeData()->hasFormat(m_dargItemstr))
    {
        m_pos = event->pos();
        event->setDropAction(Qt::MoveAction);
        event->accept();
    }
    else {
        event->ignore();
    }
}

void wPictureList::mousePressEvent(QMouseEvent *event)
{
    QObject  *obj = static_cast<QObject*>(childAt(event->pos()));
	if (!obj)
	{
		return;
	}
    QString objName = obj->objectName();
    if(objName != "widget_operation")
    {
        return;
    }

    QWidget *child = static_cast<QWidget*>(obj->parent());
    if (!child)
        return;

    QPixmap pixmap = child->grab();

    QByteArray itemData;
    QDataStream dataStream(&itemData, QIODevice::WriteOnly);
    dataStream << pixmap << QPoint(event->pos() - child->pos());
//! [1]

//! [2]
    QMimeData *mimeData = new QMimeData;
    mimeData->setData("application/x-dnditemdata", itemData);
//! [2]

//! [3]
    QDrag *drag = new QDrag(this);
    drag->setMimeData(mimeData);
    drag->setPixmap(pixmap);
    drag->setHotSpot(event->pos() - child->pos());
//! [3]

    QPixmap tempPixmap = pixmap;
    QPainter painter;
    painter.begin(&tempPixmap);
    painter.fillRect(pixmap.rect(), QColor(127, 127, 127, 127));
    painter.end();

//    child->setPixmap(tempPixmap);

    if (drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction) == Qt::MoveAction)
    {
        rePos(event->pos(), m_pos);
    } else {
        child->show();
    }
}



