/***************************************************************************
                           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 "overscan.h"
#include "kdetv.h"
#include "osdmanager.h"
#include "kdetvimage.h"
#include "kdetvimagepool.h"
#include "kdetvimagefilter.h"
#include "kdetvimagefiltercontext.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(),
      DCOPObject("OverscanIface"),
      KdetvFilterPlugin(ktv, cfgkey, parent, name)
{
    _filter = new OverscanImageFilter();
    static_cast<OverscanImageFilter*>(_filter)->_percent = _cfg->readNumEntry("Overscan", 2);

    setXMLFile("overscanui.rc");
    _plusAction = new KAction( i18n( "Increase Overscan" ), "viewmag+", Key_Z,
                               actionCollection(), "overscan_plus" );
    connect( _plusAction, SIGNAL( activated() ),
             this, SLOT( overscanPlus() ) );

    _minusAction = new KAction( i18n( "Decrease Overscan" ), "viewmag-", Key_G,
                                actionCollection(), "overscan_minus" );
    connect( _minusAction, SIGNAL( activated() ),
             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%").arg(p));
    _cfg->writeEntry("Overscan", p);
}

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

#include "overscan.moc"
