//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      GUI/View/Mask/RectangleView.cpp
//! @brief     Implements RectangleView class
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#include "GUI/View/Mask/RectangleView.h"
#include "GUI/Model/Data/MaskItems.h"
#include <QGraphicsSceneMouseEvent>
#include <QPainter>

RectangleView::RectangleView(RectangleItem* item)
    : RectangleBaseView(item)
    , m_item(item)
{
    m_item->maskVisibilityChanged();
}

QPainterPath RectangleView::shape() const
{
    QPainterPath path;
    path.addRect(m_mask_rect);
    return path;
}

MaskItemObject* RectangleView::parameterizedItem() const
{
    return m_item;
}

void RectangleView::onChangedX()
{
    setBlockOnProperty(true);
    m_item->setXLow(fromSceneX(this->x()));
    m_item->setXUp(fromSceneX(this->x() + m_mask_rect.width()));
    setBlockOnProperty(false);
}

void RectangleView::onChangedY()
{
    setBlockOnProperty(true);
    m_item->setYLow(fromSceneY(this->y() + m_mask_rect.height()));
    m_item->setYUp(fromSceneY(this->y()));
    setBlockOnProperty(false);
}

void RectangleView::onPropertyChange()
{
    update_view();
}

void RectangleView::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
    if (m_activeHandleElement) {
        qreal xmin = std::min(event->scenePos().x(), m_resize_opposite_origin.x());
        qreal xmax = std::max(event->scenePos().x(), m_resize_opposite_origin.x());
        qreal ymin = std::min(event->scenePos().y(), m_resize_opposite_origin.y());
        qreal ymax = std::max(event->scenePos().y(), m_resize_opposite_origin.y());

        if (m_activeHandleElement->getHandleType() == SizeHandleElement::RESIZE) {
            m_item->setXLow(fromSceneX(xmin));
            m_item->setYLow(fromSceneY(ymax));
            m_item->setXUp(fromSceneX(xmax));
            m_item->setYUp(fromSceneY(ymin));
        } else if (m_activeHandleElement->getHandleType() == SizeHandleElement::RESIZE_HEIGHT) {
            m_item->setYLow(fromSceneY(ymax));
            m_item->setYUp(fromSceneY(ymin));
        } else if (m_activeHandleElement->getHandleType() == SizeHandleElement::RESIZE_WIDTH) {
            m_item->setXLow(fromSceneX(xmin));
            m_item->setXUp(fromSceneX(xmax));
        }
        update_view();
    } else {
        IShape2DView::mouseMoveEvent(event);
    }
}

//! updates position of view using item properties
void RectangleView::update_position()
{
    setX(toSceneX(m_item->xLow()));
    setY(toSceneY(m_item->yUp()));
}

QRectF RectangleView::mask_rectangle()
{
    return QRectF(0.0, 0.0, width(), height());
}

//! Returns the x-coordinate of the rectangle's left edge

qreal RectangleView::left() const
{
    return toSceneX(m_item->xLow());
}

//! Returns the x-coordinate of the rectangle's right edge

qreal RectangleView::right() const
{
    return toSceneX(m_item->xUp());
}

//! Returns the y-coordinate of the rectangle's top edge.

qreal RectangleView::top() const
{
    return toSceneY(m_item->yUp());
}

//! Returns the y-coordinate of the rectangle's bottom edge.

qreal RectangleView::bottom() const
{
    return toSceneY(m_item->yLow());
}
