/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qcameraimagecapture.h>
#include <qcameraimagecapturecontrol.h>
#include <qmediaencodersettings.h>
#include <qcameracapturedestinationcontrol.h>
#include <qcameracapturebufferformatcontrol.h>

#include <qimageencodercontrol.h>
#include "qmediaobject_p.h"
#include <qmediaservice.h>
#include <qcamera.h>
#include <qcameracontrol.h>
#include <QtCore/qdebug.h>
#include <QtCore/qurl.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qmetaobject.h>

QT_BEGIN_NAMESPACE

/*!
    \class QCameraImageCapture
    \inmodule QtMultimedia
    \ingroup multimedia
    \ingroup multimedia_camera


    \brief The QCameraImageCapture class is used for the recording of media content.

    The QCameraImageCapture class is a high level images recording class.
    It's not intended to be used alone but for accessing the media
    recording functions of other media objects, like QCamera.

    \snippet multimedia-snippets/camera.cpp Camera

    \snippet multimedia-snippets/camera.cpp Camera keys

    \sa QCamera
*/

/*!
    \enum QCameraImageCapture::CaptureDestination

    \value CaptureToFile  Capture the image to a file.
    \value CaptureToBuffer  Capture the image to a buffer for further processing.
*/

static void qRegisterCameraImageCaptureMetaTypes()
{
    qRegisterMetaType<QCameraImageCapture::Error>("QCameraImageCapture::Error");
    qRegisterMetaType<QCameraImageCapture::CaptureDestination>("QCameraImageCapture::CaptureDestination");
    qRegisterMetaType<QCameraImageCapture::CaptureDestinations>("QCameraImageCapture::CaptureDestinations");
}

Q_CONSTRUCTOR_FUNCTION(qRegisterCameraImageCaptureMetaTypes)


class QCameraImageCapturePrivate
{
    Q_DECLARE_NON_CONST_PUBLIC(QCameraImageCapture)
public:
    QCameraImageCapturePrivate();

    QMediaObject *mediaObject;

    QCameraImageCaptureControl *control;
    QImageEncoderControl *encoderControl;
    QCameraCaptureDestinationControl *captureDestinationControl;
    QCameraCaptureBufferFormatControl *bufferFormatControl;

    QCameraImageCapture::Error error;
    QString errorString;

    void _q_error(int id, int error, const QString &errorString);
    void _q_readyChanged(bool);
    void _q_serviceDestroyed();

    void unsetError() { error = QCameraImageCapture::NoError; errorString.clear(); }

    QCameraImageCapture *q_ptr;
};

QCameraImageCapturePrivate::QCameraImageCapturePrivate():
     mediaObject(nullptr),
     control(nullptr),
     encoderControl(nullptr),
     captureDestinationControl(nullptr),
     bufferFormatControl(nullptr),
     error(QCameraImageCapture::NoError)
{
}

void QCameraImageCapturePrivate::_q_error(int id, int error, const QString &errorString)
{
    Q_Q(QCameraImageCapture);

    this->error = QCameraImageCapture::Error(error);
    this->errorString = errorString;

    emit q->error(id, this->error, errorString);
}

void QCameraImageCapturePrivate::_q_readyChanged(bool ready)
{
    Q_Q(QCameraImageCapture);
    emit q->readyForCaptureChanged(ready);
}

void QCameraImageCapturePrivate::_q_serviceDestroyed()
{
    mediaObject = nullptr;
    control = nullptr;
    encoderControl = nullptr;
    captureDestinationControl = nullptr;
    bufferFormatControl = nullptr;
}

/*!
    Constructs a media recorder which records the media produced by \a mediaObject.

    The \a parent is passed to QMediaObject.
*/

QCameraImageCapture::QCameraImageCapture(QMediaObject *mediaObject, QObject *parent):
    QObject(parent), d_ptr(new QCameraImageCapturePrivate)
{
    Q_D(QCameraImageCapture);

    d->q_ptr = this;

    if (mediaObject)
        mediaObject->bind(this);
}

/*!
    Destroys images capture object.
*/

QCameraImageCapture::~QCameraImageCapture()
{
    Q_D(QCameraImageCapture);

    if (d->mediaObject)
        d->mediaObject->unbind(this);

    delete d_ptr;
}

/*!
  \reimp
*/
QMediaObject *QCameraImageCapture::mediaObject() const
{
    return d_func()->mediaObject;
}

/*!
  \reimp
*/
bool QCameraImageCapture::setMediaObject(QMediaObject *mediaObject)
{
    Q_D(QCameraImageCapture);

    if (d->mediaObject) {
        if (d->control) {
            disconnect(d->control, SIGNAL(imageExposed(int)),
                       this, SIGNAL(imageExposed(int)));
            disconnect(d->control, SIGNAL(imageCaptured(int,QImage)),
                       this, SIGNAL(imageCaptured(int,QImage)));
            disconnect(d->control, SIGNAL(imageAvailable(int,QVideoFrame)),
                       this, SIGNAL(imageAvailable(int,QVideoFrame)));
            disconnect(d->control, SIGNAL(imageMetadataAvailable(int,QString,QVariant)),
                       this, SIGNAL(imageMetadataAvailable(int,QString,QVariant)));
            disconnect(d->control, SIGNAL(imageSaved(int,QString)),
                       this, SIGNAL(imageSaved(int,QString)));
            disconnect(d->control, SIGNAL(readyForCaptureChanged(bool)),
                       this, SLOT(_q_readyChanged(bool)));
            disconnect(d->control, SIGNAL(error(int,int,QString)),
                       this, SLOT(_q_error(int,int,QString)));

            if (d->captureDestinationControl) {
                disconnect(d->captureDestinationControl, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)),
                           this, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)));
            }

            if (d->bufferFormatControl) {
                disconnect(d->bufferFormatControl, SIGNAL(bufferFormatChanged(QVideoFrame::PixelFormat)),
                           this, SIGNAL(bufferFormatChanged(QVideoFrame::PixelFormat)));
            }

            QMediaService *service = d->mediaObject->service();
            service->releaseControl(d->control);
            if (d->encoderControl)
                service->releaseControl(d->encoderControl);
            if (d->captureDestinationControl)
                service->releaseControl(d->captureDestinationControl);
            if (d->bufferFormatControl)
                service->releaseControl(d->bufferFormatControl);

            disconnect(service, SIGNAL(destroyed()), this, SLOT(_q_serviceDestroyed()));
        }
    }

    d->mediaObject = mediaObject;

    if (d->mediaObject) {
        QMediaService *service = mediaObject->service();
        if (service) {
            d->control = qobject_cast<QCameraImageCaptureControl*>(service->requestControl(QCameraImageCaptureControl_iid));

            if (d->control) {
                d->encoderControl = qobject_cast<QImageEncoderControl *>(service->requestControl(QImageEncoderControl_iid));
                d->captureDestinationControl = qobject_cast<QCameraCaptureDestinationControl *>(
                    service->requestControl(QCameraCaptureDestinationControl_iid));
                d->bufferFormatControl = qobject_cast<QCameraCaptureBufferFormatControl *>(
                    service->requestControl(QCameraCaptureBufferFormatControl_iid));

                connect(d->control, SIGNAL(imageExposed(int)),
                        this, SIGNAL(imageExposed(int)));
                connect(d->control, SIGNAL(imageCaptured(int,QImage)),
                        this, SIGNAL(imageCaptured(int,QImage)));
                connect(d->control, SIGNAL(imageMetadataAvailable(int,QString,QVariant)),
                        this, SIGNAL(imageMetadataAvailable(int,QString,QVariant)));
                connect(d->control, SIGNAL(imageAvailable(int,QVideoFrame)),
                        this, SIGNAL(imageAvailable(int,QVideoFrame)));
                connect(d->control, SIGNAL(imageSaved(int,QString)),
                        this, SIGNAL(imageSaved(int,QString)));
                connect(d->control, SIGNAL(readyForCaptureChanged(bool)),
                        this, SLOT(_q_readyChanged(bool)));
                connect(d->control, SIGNAL(error(int,int,QString)),
                        this, SLOT(_q_error(int,int,QString)));

                if (d->captureDestinationControl) {
                    connect(d->captureDestinationControl, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)),
                            this, SIGNAL(captureDestinationChanged(QCameraImageCapture::CaptureDestinations)));
                }

                if (d->bufferFormatControl) {
                    connect(d->bufferFormatControl, SIGNAL(bufferFormatChanged(QVideoFrame::PixelFormat)),
                            this, SIGNAL(bufferFormatChanged(QVideoFrame::PixelFormat)));
                }

                connect(service, SIGNAL(destroyed()), this, SLOT(_q_serviceDestroyed()));

                return true;
            }
        }
    }

    // without QCameraImageCaptureControl discard the media object
    d->mediaObject = nullptr;
    d->control = nullptr;
    d->encoderControl = nullptr;
    d->captureDestinationControl = nullptr;
    d->bufferFormatControl = nullptr;

    return false;
}

/*!
    Returns true if the images capture service ready to use.
*/
bool QCameraImageCapture::isAvailable() const
{
    if (d_func()->control != nullptr)
        return true;
    else
        return false;
}

/*!
    Returns the availability of this functionality.
*/
QMultimedia::AvailabilityStatus QCameraImageCapture::availability() const
{
    if (d_func()->control != nullptr)
        return QMultimedia::Available;
    else
        return QMultimedia::ServiceMissing;
}

/*!
    Returns the current error state.

    \sa errorString()
*/

QCameraImageCapture::Error QCameraImageCapture::error() const
{
    return d_func()->error;
}

/*!
    Returns a string describing the current error state.

    \sa error()
*/

QString QCameraImageCapture::errorString() const
{
    return d_func()->errorString;
}


/*!
    Returns a list of supported image codecs.
*/
QStringList QCameraImageCapture::supportedImageCodecs() const
{
    return d_func()->encoderControl ?
           d_func()->encoderControl->supportedImageCodecs() : QStringList();
}

/*!
    Returns a description of an image \a codec.
*/
QString QCameraImageCapture::imageCodecDescription(const QString &codec) const
{
    return d_func()->encoderControl ?
           d_func()->encoderControl->imageCodecDescription(codec) : QString();
}

/*!
    Returns a list of resolutions images can be encoded at.

    If non null image \a settings parameter is passed,
    the returned list is reduced to resolution supported with partial settings like image codec or quality applied.

    If the encoder supports arbitrary resolutions within the supported range,
    *\a continuous is set to true, otherwise *\a continuous is set to false.

    \sa QImageEncoderSettings::resolution()
*/
QList<QSize> QCameraImageCapture::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const
{
    if (continuous)
        *continuous = false;

    return d_func()->encoderControl ?
           d_func()->encoderControl->supportedResolutions(settings, continuous) : QList<QSize>();
}

/*!
    Returns the image encoder settings being used.

    \sa setEncodingSettings()
*/

QImageEncoderSettings QCameraImageCapture::encodingSettings() const
{
    return d_func()->encoderControl ?
           d_func()->encoderControl->imageSettings() : QImageEncoderSettings();
}

/*!
    Sets the image encoding \a settings.

    If some parameters are not specified, or null settings are passed,
    the encoder choose the default encoding parameters.

    \sa encodingSettings()
*/

void QCameraImageCapture::setEncodingSettings(const QImageEncoderSettings &settings)
{
    Q_D(QCameraImageCapture);

    if (d->encoderControl) {
        QCamera *camera = qobject_cast<QCamera*>(d->mediaObject);
        if (camera && camera->captureMode() == QCamera::CaptureStillImage) {
            QMetaObject::invokeMethod(camera,
                                      "_q_preparePropertyChange",
                                      Qt::DirectConnection,
                                      Q_ARG(int, QCameraControl::ImageEncodingSettings));
        }

        d->encoderControl->setImageSettings(settings);
    }
}

/*!
    Returns the list of supported buffer image capture formats.

    \sa bufferFormat(), setBufferFormat()
*/
QList<QVideoFrame::PixelFormat> QCameraImageCapture::supportedBufferFormats() const
{
    if (d_func()->bufferFormatControl)
        return d_func()->bufferFormatControl->supportedBufferFormats();
    else
        return QList<QVideoFrame::PixelFormat>();
}

/*!
    Returns the buffer image capture format being used.

    \sa supportedBufferFormats(), setBufferFormat()
*/
QVideoFrame::PixelFormat QCameraImageCapture::bufferFormat() const
{
    if (d_func()->bufferFormatControl)
        return d_func()->bufferFormatControl->bufferFormat();
    else
        return QVideoFrame::Format_Invalid;
}

/*!
    Sets the buffer image capture \a format to be used.

    \sa bufferFormat(), supportedBufferFormats(), captureDestination()
*/
void QCameraImageCapture::setBufferFormat(const QVideoFrame::PixelFormat format)
{
    if (d_func()->bufferFormatControl)
        d_func()->bufferFormatControl->setBufferFormat(format);
}

/*!
    Returns true if the image capture \a destination is supported; otherwise returns false.

    \sa captureDestination(), setCaptureDestination()
*/
bool QCameraImageCapture::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const
{
    if (d_func()->captureDestinationControl)
        return d_func()->captureDestinationControl->isCaptureDestinationSupported(destination);
    else
        return destination == CaptureToFile;
}

/*!
    Returns the image capture destination being used.

    \sa isCaptureDestinationSupported(), setCaptureDestination()
*/
QCameraImageCapture::CaptureDestinations QCameraImageCapture::captureDestination() const
{
    if (d_func()->captureDestinationControl)
        return d_func()->captureDestinationControl->captureDestination();
    else
        return CaptureToFile;
}

/*!
    Sets the capture \a destination to be used.

    \sa isCaptureDestinationSupported(), captureDestination()
*/
void QCameraImageCapture::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination)
{
    Q_D(QCameraImageCapture);

    if (d->captureDestinationControl)
        d->captureDestinationControl->setCaptureDestination(destination);
}

/*!
  \property QCameraImageCapture::readyForCapture
  \brief whether the service is ready to capture a an image immediately.

  Calling capture() while \e readyForCapture is \c false is not permitted and
  results in an error.
*/

bool QCameraImageCapture::isReadyForCapture() const
{
    if (d_func()->control)
        return d_func()->control->isReadyForCapture();
    else
        return false;
}

/*!
    \fn QCameraImageCapture::readyForCaptureChanged(bool ready)

    Signals that a camera's \a ready for capture state has changed.
*/


/*!
    Capture the image and save it to \a file.
    This operation is asynchronous in majority of cases,
    followed by signals QCameraImageCapture::imageExposed(),
    QCameraImageCapture::imageCaptured(), QCameraImageCapture::imageSaved()
    or QCameraImageCapture::error().

    If an empty \a file is passed, the camera backend choses
    the default location and naming scheme for photos on the system,
    if only file name without full path is specified, the image will be saved to
    the default directory, with a full path reported with imageCaptured() and imageSaved() signals.

    QCamera saves all the capture parameters like exposure settings or
    image processing parameters, so changes to camera parameters after
    capture() is called do not affect previous capture requests.

    QCameraImageCapture::capture returns the capture Id parameter, used with
    imageExposed(), imageCaptured() and imageSaved() signals.

    \sa isReadyForCapture()
*/
int QCameraImageCapture::capture(const QString &file)
{
    Q_D(QCameraImageCapture);

    d->unsetError();

    if (d->control) {
        return d->control->capture(file);
    } else {
        d->error = NotSupportedFeatureError;
        d->errorString = tr("Device does not support images capture.");

        emit error(-1, d->error, d->errorString);
    }

    return -1;
}

/*!
    Cancel incomplete capture requests.
    Already captured and queused for proicessing images may be discarded.
*/
void QCameraImageCapture::cancelCapture()
{
    Q_D(QCameraImageCapture);

    d->unsetError();

    if (d->control) {
        d->control->cancelCapture();
    } else {
        d->error = NotSupportedFeatureError;
        d->errorString = tr("Device does not support images capture.");

        emit error(-1, d->error, d->errorString);
    }
}


/*!
    \enum QCameraImageCapture::Error

    \value NoError         No Errors.
    \value NotReadyError   The service is not ready for capture yet.
    \value ResourceError   Device is not ready or not available.
    \value OutOfSpaceError No space left on device.
    \value NotSupportedFeatureError Device does not support stillimages capture.
    \value FormatError     Current format is not supported.
*/

/*!
    \enum QCameraImageCapture::DriveMode

    \value SingleImageCapture Drive mode is capturing a single picture.
*/

/*!
    \fn QCameraImageCapture::error(int id, QCameraImageCapture::Error error, const QString &errorString)

    Signals that the capture request \a id has failed with an \a error
    and \a errorString description.
*/

/*!
    \fn QCameraImageCapture::bufferFormatChanged(QVideoFrame::PixelFormat format)

    Signal emitted when the buffer \a format for the buffer image capture has changed.
*/

/*!
    \fn QCameraImageCapture::captureDestinationChanged(CaptureDestinations destination)

    Signal emitted when the capture \a destination has changed.
*/

/*!
    \fn QCameraImageCapture::imageExposed(int id)

    Signal emitted when the frame with request \a id was exposed.
*/

/*!
    \fn QCameraImageCapture::imageCaptured(int id, const QImage &preview);

    Signal emitted when the frame with request \a id was captured, but not processed and saved yet.
    Frame \a preview can be displayed to user.
*/

/*!
    \fn QCameraImageCapture::imageMetadataAvailable(int id, const QString &key, const QVariant &value)

    Signals that a metadata for an image with request \a id is available. Also
    includes the \a key and \a value of the metadata.

    This signal is emitted between imageExposed and imageSaved signals.
*/

/*!
    \fn QCameraImageCapture::imageAvailable(int id, const QVideoFrame &frame)

    Signal emitted when the \a frame with request \a id is available.
*/

/*!
    \fn QCameraImageCapture::imageSaved(int id, const QString &fileName)

    Signal emitted when the frame with request \a id was saved to \a fileName.
*/

QT_END_NAMESPACE

#include "moc_qcameraimagecapture.cpp"
