/************************************************************************
 *									*
 *  This file is part of Kooka, a scanning/OCR application using	*
 *  Qt <http://www.qt.io> and KDE Frameworks <http://www.kde.org>.	*
 *									*
 *  Copyright (C) 2000-2018 Klaas Freitag <freitag@suse.de>		*
 *                          Jonathan Marten <jjm@keelhaul.me.uk>	*
 *									*
 *  Kooka is free software; you can redistribute it and/or modify it	*
 *  under the terms of the GNU Library General Public License as	*
 *  published by the Free Software Foundation and appearing in the	*
 *  file COPYING included in the packaging of this file;  either	*
 *  version 2 of the License, or (at your option) any later version.	*
 *									*
 *  As a special exception, permission is given to link this program	*
 *  with any version of the KADMOS OCR/ICR engine (a product of		*
 *  reRecognition GmbH, Kreuzlingen), and distribute the resulting	*
 *  executable without including the source code for KADMOS in the	*
 *  source distribution.						*
 *									*
 *  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;  see the file COPYING.  If		*
 *  not, see <http://www.gnu.org/licenses/>.				*
 *									*
 ************************************************************************/

#ifndef ABSTRACTDESTINATION_H
#define ABSTRACTDESTINATION_H

#include <klocalizedstring.h>

#include "abstractplugin.h"
#include "scanimage.h"
#include "imageformat.h"


class QComboBox;
class ScanGallery;
class ScanParamsPage;

#ifndef PLUGIN_EXPORT
#define PLUGIN_EXPORT
#endif


class PLUGIN_EXPORT AbstractDestination : public AbstractPlugin
{
    Q_OBJECT

public:
    /**
     * Destructor.
     **/
    virtual ~AbstractDestination() = default;

    /**
     * Indicates that a scan is starting.  The plugin should prepare
     * to receive the image.
     *
     * This is always called before the start of the scan, but not for
     * a preview.  However, if SANE did not provide enough information
     * to determine the format of the scanned image then @p type may be
     * @c ScanImage::None.  If the plugin needs to ask for a file name
     * to save or send the scan, then it should take account of the @p type
     * and should also honour the "ask before or after scan" setting.
     *
     * The base class implementation ignores the image type and always
     * returns @c true.  There is no need for a plugin which overrides
     * this function to call the base class implementation.
     *
     * @param type The type of the image that is about to be scanned.
     * @return @c true if the scan is to go ahead, or @c false if it
     * is to be cancelled.
     **/
    virtual bool scanStarting(ScanImage::ImageType type)	{ return (true); }

    /**
     * Indicates that an image has been scanned.  The plugin should
     * save or send the image as required.
     *
     * @param img The image that has been scanned,
     **/
    virtual void imageScanned(ScanImage::Ptr img) = 0;

    /**
     * Get a description string for the scan destination.
     *
     * This is shown along with the scan progress indicator.  It may
     * contain KUIT markup, which will be finalised when the progress
     * is shown.  If the string contains KUIT markup then it should be
     * generated by @c kxi18n(), although no context is required.
     * Otherwise, it may be generated by @c ki18n().
     *
     * If the description is an empty string then only the default label
     * ("Scan in progress") will be shown.  The base class implementation
     * returns an empty string.

     * @return The descriptive title, or an empty string for none.
     * @note @c scanStarting() will always be called before this function.
     **/
    virtual KLocalizedString scanDestinationString()		{ return (KLocalizedString()); }

    /**
     * Create GUI widgets as required for the selected destination
     * plugin.  This includes loading the saved settings if the
     * plugin has any.
     *
     * The base class implementation adds nothing.
     *
     * @param page The parent frame.
     *
     * @note The current row of the @p page is the first reserved
     * parameter row.
     **/
    virtual void createGUI(ScanParamsPage *page)		{ }

    /**
     * Sets the scan gallery, in the event that the plugin needs
     * to locate it.
     *
     * @param gallery The scan gallery.
     * @see @c gallery()
     **/
    void setScanGallery(ScanGallery *gallery)			{ mGallery = gallery; }

    /**
     * Save the plugin settings, either to the application settings or
     * a private configuration.
     *
     * The base class implementation does nothing.
     **/
    virtual void saveSettings() const				{ }

protected:
    /**
     * Constructor.
     *
     * @param pnt The parent object.
     * @param name The Qt object name.
     **/
    explicit AbstractDestination(QObject *pnt, const char *name);

    /**
     * Get the scan gallery, if needed by the plugin.
     *
     * @return the scan gallery, or @c nullptr if none has been set.
     * @see @c setScanGallery()
     **/
    ScanGallery *gallery() const				{ return (mGallery); }

    /**
     * Get a format to save the image, from the user specified MIME type.
     *
     * If a valid MIME type is selected, then use that.  If "Other" is
     * selected or the selected format is not valid for saving, then use
     * a @c FormatDialog to prompt for a format.
     *
     * @param mimeName The MIME type name.
     * @param img The image which is to be saved,
     * @return an @c ImageFormat for saving the image.
     **/
    ImageFormat getSaveFormat(const QString &mimeName, ScanImage::Ptr img);

    /**
     * Save a temporary image for sending to a destination.
     *
     * @param fmt The image format to save in.
     * @param img The image which is to be saved,
     * @return the URL of a temporary file, or a null URL if there was
     * a problem saving the image. If the URL is valid then the temporary
     * file will not be deleted even when the application exits, the
     * caller must delete the file when it is no longer required.
     **/
    QUrl saveTempImage(const ImageFormat &fmt, ScanImage::Ptr img);

    /**
     * Create a combo box for selecting an image format.
     *
     * @param mimeTypes A list of MIME types to show in the combo box.
     * @param configuredType The MIME type that is to be initially
     * selected, or @c QString() if the "Other" option is to be selected.
     * @return a combo box, with no parent widget assigned.  The caller may
     * assign the combo box a parent or delete it when it is no longer required.
     * @note The relevant MIME type is stored in the @c data(Qt::UserRole)
     * of the combo box items, with a null string for "Other".
     **/
    QComboBox *createFormatCombo(const QStringList &mimeTypes, const QString &configuredType);

    /**
     * Delete a file in the background, after a time delay.
     *
     * @param url The file to delete.
     **/
    void delayedDelete(const QUrl &url);

private:
    ScanGallery *mGallery;
    ImageFormat mLastUsedFormat;
};

#endif							// ABSTRACTDESTINATION_H
