/*
 * Copyright 2009-2010  Stefan Gehn <stefan@srcbox.net>
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of 
 * the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "Draggable.hpp"
#include "DropTarget.hpp"

#include <qdebug.h>
#include <qgraphicssceneevent.h>

Draggable::Draggable(QGraphicsItem *parent) : QtGraphicsWidget(parent)
{
  setFlags(ItemIsMovable | ItemIsSelectable);
  setAcceptedMouseButtons(Qt::LeftButton);
}

Draggable::~Draggable()
{
}

DropTarget *Draggable::collidingDropTarget() const
{
  DropTarget *dt = 0;

  Q_FOREACH(QGraphicsItem *item, collidingItems())
  {
    dt = dynamic_cast<DropTarget *>(item);
    if (!dt)
      continue;

    const QPolygonF ownPoly = mapToScene(boundingRect());
    const QRectF ownRect = ownPoly.boundingRect();
    int ownSize = ownRect.width() * ownRect.height();

    const QPolygonF targetPoly = item->mapToScene(item->boundingRect());
    const QRectF targetRect = targetPoly.boundingRect();
    int targetSize = targetRect.width() * targetRect.height();

    const QPolygonF interPoly = ownPoly.intersected(targetPoly);
    const QRectF interRect = interPoly.boundingRect();
    int interSize = interRect.width() * interRect.height();

    //qDebug() << "own:" << ownSize << " target:" << targetSize << " inter:" << interSize;

    // more than 70% of photo overlap with drop-target
    if (interSize > (ownSize * 0.70))
      break;
    // more than 70% of drop-target overlap with photo
    if (interSize > (targetSize * 0.70))
      break;
  }

  return dt;
}

void Draggable::reparent(QGraphicsItem *parentItem)
{
  // save current transformation matrix
  QTransform oldTrans = transform();

  // Reset transformation to get the "proper" position of this item
  // in relation to its new parentItem
  resetTransform();

  // save current screen position relative to our new parentItem
  QPointF onParentPos = mapToItem(parentItem, 0, 0);

  // reparent ourselves
  setParentItem(parentItem);

  // fix position after reparenting
  setPos(onParentPos);

  // reapply transformation matrix
  setTransform(oldTrans, false);
}

void Draggable::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
  if (event->button() == Qt::LeftButton)
  {
    DropTarget *dt = collidingDropTarget();
    if (dt)
    {
      qDebug() << "Draggable was dropped onto a DropTarget";
      event->accept();
      dt->dropped(this);
      return;
    }
  }
  QtGraphicsWidget::mouseReleaseEvent(event);
}
