/***************************************************************************
                           overscan.cpp
                           ------------
    begin                : Thu Jun 24 2004
    copyright            : (C) 2004 by Dirk Ziegelmeier
    email                : dziegel@gmx.de
 ***************************************************************************/

/*
 * This library 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; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <kdebug.h>
#include <klocale.h>
#include <kconfig.h>
#include <kxmlguifactory.h>
#include <KActionCollection>
#include <KConfigGroup>
#include "overscan.h"
#include "kdetv.h"
#include "osdmanager.h"
#include "kdetvimage.h"
#include "kdetvimagepool.h"
#include "kdetvimagefilter.h"
#include "kdetvimagefiltercontext.h"
#include "overscanadaptor.h"

class OverscanImageFilter : public KdetvImageFilter
{
public:
    OverscanImageFilter()
        : KdetvImageFilter(i18n("Overscan"))
    {
    }

    virtual ~OverscanImageFilter()
    {
    }

    virtual KdetvImageFilterContext* operator<< (KdetvImageFilterContext* ctx)
    {
        if(_percent == 0) {
            return ctx;
        }

        KdetvSharedImage* img = ctx->out;

        float aspect = (float)img->size().height() / (float)img->size().width();

        // Use a multiple of two pixels (YUV data has half horizontal color resolution)
        int pixels = (_percent * img->size().width() / 100) & 0xFFFFFFFe;

        // calc new size
        int sx = img->size().width() - pixels;
        int sy = (int)(img->size().height() - pixels*aspect);

        ctx->out_x      = pixels / 2;
        ctx->out_y      = (int)((pixels*aspect) / 2);
        ctx->out_width  = sx;
        ctx->out_height = sy;

        return ctx;
    }

    virtual KdetvImage::ImageFormat inputFormats()
    {
        return KdetvImage::FORMAT_ALL;
    };


private:
    friend class OverscanPlugin;

    int _percent;
};

// -----------------------------------------------------------------------

OverscanPlugin::OverscanPlugin(Kdetv *ktv, const QString& cfgkey, QObject *parent, const char* name)
    : KXMLGUIClient(),
      KdetvFilterPlugin(ktv, cfgkey, parent, name)
{
    new OverscanAdaptor(this);
    QDBusConnection::sessionBus().registerObject("/Kdetv/Overscan", this);

    _filter = new OverscanImageFilter();
    KConfigGroup grp = _cfg->group("");
    static_cast<OverscanImageFilter*>(_filter)->_percent = grp.readEntry("Overscan", 2);

    setXMLFile("overscanui.rc");

    _plusAction = actionCollection()->addAction("overscan_plus");
    _plusAction->setText(i18n("Increase Overscan"));
    _plusAction->setIcon(KIcon("viewmag+"));
    _plusAction->setShortcut(Qt::Key_Z);
    connect(_plusAction, SIGNAL(triggered()), this, SLOT(overscanPlus()));

    _minusAction = actionCollection()->addAction("overscan_minus");
    _minusAction->setText(i18n("Increase Overscan"));
    _minusAction->setIcon(KIcon("viewmag-"));
    _minusAction->setShortcut(Qt::Key_G);
    connect(_minusAction, SIGNAL(triggered()), this, SLOT(overscanMinus()));
}

OverscanPlugin::~OverscanPlugin()
{
    delete _filter;
}

void OverscanPlugin::installGUIElements(KXMLGUIFactory* guiFactory, KActionCollection*)
{
    if ( guiFactory ) {
        guiFactory->addClient(static_cast<KXMLGUIClient*>(this));
    }
}

void OverscanPlugin::removeGUIElements(KXMLGUIFactory* guiFactory, KActionCollection*)
{
    if ( guiFactory ) {
        guiFactory->removeClient(static_cast<KXMLGUIClient*>(this));
    }
}

void OverscanPlugin::overscanPlus()
{
    static_cast<OverscanImageFilter*>(_filter)->_percent = qMin(static_cast<OverscanImageFilter*>(_filter)->_percent + 1, 50);
    overscanChanged();
}

void OverscanPlugin::overscanMinus()
{
    static_cast<OverscanImageFilter*>(_filter)->_percent = qMax(0, static_cast<OverscanImageFilter*>(_filter)->_percent - 1);
    overscanChanged();
}

void OverscanPlugin::overscanChanged()
{
    int p = static_cast<OverscanImageFilter*>(_filter)->_percent;
    driver()->osdManager()->displayMisc(i18n("Overscan: %1%",QString::number(p)));

    KConfigGroup grp = _cfg->group("");
    grp.writeEntry("Overscan", p);
}

extern "C" {
    KDETV_EXPORT OverscanPlugin* create_overscan(Kdetv* ktv)
    {
        return new OverscanPlugin(ktv, "overscan", 0, "Overscan");
    }
}

#include "overscan.moc"
