/*
 * Copyright (c) 2019 Frank Fischer <frank-fischer@shadow-soft.de>
 *
 * 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 3 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/>
 */

#ifndef __KOLLAGEIMAGEVIEW_HXX__
#define __KOLLAGEIMAGEVIEW_HXX__

#include <QtWidgets/QWidget>

#include <memory>

class KollageImage;

class KollageImageView : public QWidget
{
    Q_OBJECT

public:
    KollageImageView(const std::shared_ptr<KollageImage>& kollage, QWidget* parent = nullptr);

    KollageImageView(QWidget* parent = nullptr) : KollageImageView(nullptr, parent) {}

    ~KollageImageView();

    void setKollageImage(const std::shared_ptr<KollageImage>& image);

    std::shared_ptr<KollageImage> kollageImage();

    /// Sets the maximal number of pixels in the major direction.
    ///
    /// The number of pixels in the other directions is determined by the aspect
    /// ratio of the current image. If the image is changed the size of the view
    /// will be changed, too.
    void setMajorSize(int numPixels);

    /// Sets the currently active sub image.
    ///
    /// A value < 0 deselects all images.
    void setCurrentImage(int index);

    /// Return the currently selected sub image or -1.
    int currentImage() const;

    /// Return the rectangle containing the given sub image.
    QRect imageRect(int index) const;

    /// Return the scale of the current image.
    ///
    /// The function returns 0 if there is no current image.
    double currentScale() const;

public slots:
    /// Rotate the current image counterclockwise.
    void rotateCurrentLeft();

    /// Rotate the current image clockwise.
    void rotateCurrentRight();

    /// Set the scale of the current image.
    void setCurrentScale(double scale);

protected:
    void paintEvent(QPaintEvent* event) override;

    void wheelEvent(QWheelEvent* event) override;

    void mousePressEvent(QMouseEvent* event) override;

    void mouseReleaseEvent(QMouseEvent* event) override;

    void mouseMoveEvent(QMouseEvent* event) override;

    void dragEnterEvent(QDragEnterEvent* event) override;

    void dragLeaveEvent(QDragLeaveEvent* event) override;

    void dragMoveEvent(QDragMoveEvent* event) override;

    void dropEvent(QDropEvent* event) override;

    void resizeEvent(QResizeEvent* event) override;

private:
    /// Resize the view if the aspect ratio or major size has been changed.
    void updateSize();
    QRect computeTargetRect() const;

    int getImageAt(const QPoint& pos) const;

    int getSplitterAt(const QPoint& pos) const;

private slots:
    /// Called if the layout/shape of the image has been changed.
    void onLayoutChanged();

    void onImageScaleChanged(int index);

    void onRepaintImage(int index);

signals:
    void kollageImageChanged();

    void sizeChanged();

    void currentImageChanged();

    void currentScaleChanged();

private:
    struct Data;
    std::unique_ptr<Data> d;
};

#endif
