/* This file is part of the KDE project
   Copyright (C) 2002 Lukas Tinkl <lukas@kde.org>

   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 Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/

#include <tqcombobox.h>
#include <tqlabel.h>
#include <tqspinbox.h>
#include <tqwidgetstack.h>
#include <tqcheckbox.h>
#include <tqimage.h>

#include <kimageeffect.h>
#include <tdelocale.h>
#include <knuminput.h>
#include <kcolorbutton.h>

#include "KPrImageEffectDia.h"

KPrImageEffectDia::KPrImageEffectDia(TQWidget * parent, const char * name):
    KDialogBase(parent, name, true, i18n("Image Effect"), Ok|Cancel, Ok)
{
    m_pix = TQPixmap();

    m_effect = IE_NONE;
    m_param1 = TQVariant();
    m_param2 = TQVariant();
    m_param3 = TQVariant();

    base = new EffectBrowserBase(this, "effect_base");

    setMainWidget(base);

    setupSignals();

    connect((TQWidget *)base->m_effectCombo, TQ_SIGNAL(activated(int)),
            this, TQ_SLOT(effectChanged(int)));

    connect(this, TQ_SIGNAL(okClicked()),
            this, TQ_SLOT(okClicked()));
}

KPrImageEffectDia::~KPrImageEffectDia()
{
    delete base;
}

void KPrImageEffectDia::effectChanged(int eff)
{
    TQImage _tmpImage = m_origpix.convertToImage();

    //clear the (unused) params
    m_param1 = TQVariant();
    m_param2 = TQVariant();
    m_param3 = TQVariant();

    m_effect = static_cast<ImageEffect>(eff);

    switch (m_effect) {
    case IE_CHANNEL_INTENSITY: {
        m_param1 = TQVariant(base->chanInt_value->value());
        m_param2 = TQVariant(base->chanInt_component->currentItem());
        _tmpImage = KImageEffect::channelIntensity(_tmpImage, m_param1.toDouble()/100.0,
                                                   static_cast<KImageEffect::RGBComponent>(m_param2.toInt()));
        break;
    }
    case IE_FADE: {
        m_param1 = TQVariant(base->fade_value->value());
        m_param2 = TQVariant(base->fade_color->color());
        _tmpImage = KImageEffect::fade(_tmpImage, m_param1.toDouble(), m_param2.toColor());
        break;
    }
    case IE_FLATTEN: {
        m_param1 = TQVariant(base->flatten_color1->color());
        m_param2 = TQVariant(base->flatten_color2->color());
        _tmpImage = KImageEffect::flatten(_tmpImage, m_param1.toColor(), m_param2.toColor());
        break;
    }
    case IE_INTENSITY: {
        m_param1 = TQVariant(base->intensity_value->value());
        _tmpImage = KImageEffect::intensity(_tmpImage, m_param1.toDouble()/100.0);
        break;
    }
    case IE_DESATURATE: {
        m_param1 = TQVariant(base->desaturate_value->value());
        _tmpImage = KImageEffect::desaturate(_tmpImage, m_param1.toDouble());
        break;
    }
    case IE_CONTRAST: {
        m_param1 = TQVariant(base->contrast_value->value());
        _tmpImage = KImageEffect::contrast(_tmpImage, m_param1.toInt());
        break;
    }
    case IE_NORMALIZE: {
        KImageEffect::normalize(_tmpImage);
        break;
    }
    case IE_EQUALIZE: {
        KImageEffect::equalize(_tmpImage);
        break;
    }
    case IE_THRESHOLD: {
        m_param1 = TQVariant(base->threshold_value->value());
        KImageEffect::threshold(_tmpImage, m_param1.toInt());
        break;
    }
    case IE_SOLARIZE: {
        m_param1 = TQVariant(base->solarize_value->value());
        KImageEffect::solarize(_tmpImage, m_param1.toDouble());
        break;
    }
    case IE_EMBOSS: {
        _tmpImage = KImageEffect::emboss(_tmpImage);
        break;
    }
    case IE_DESPECKLE: {
        _tmpImage = KImageEffect::despeckle(_tmpImage);
        break;
    }
    case IE_CHARCOAL: {
        m_param1 = TQVariant(base->charcoal_value->value());
        _tmpImage = KImageEffect::charcoal(_tmpImage, m_param1.toDouble());
        break;
    }
    case IE_NOISE: {
        m_param1 = TQVariant(base->noise_type->currentItem());
        _tmpImage = KImageEffect::addNoise(_tmpImage, static_cast<KImageEffect::NoiseType>(m_param1.toInt()));
        break;
    }
    case IE_BLUR: {
        m_param1 = TQVariant(base->blur_value->value());
        _tmpImage = KImageEffect::blur(_tmpImage, m_param1.toDouble());
        break;
    }
    case IE_EDGE: {
        m_param1 = TQVariant(base->edge_value->value());
        _tmpImage = KImageEffect::edge(_tmpImage, m_param1.toDouble());
        break;
    }
    case IE_IMPLODE: {
        m_param1 = TQVariant(base->implode_value->value());
        _tmpImage = KImageEffect::implode(_tmpImage, m_param1.toDouble());
        break;
    }
    case IE_OIL_PAINT: {
        m_param1 = TQVariant(base->oilPaint_radius->value());
        _tmpImage = KImageEffect::oilPaint(_tmpImage, m_param1.toInt());
        break;
    }
    case IE_SHARPEN: {
        m_param1 = TQVariant(base->sharpen_value->value());
        _tmpImage = KImageEffect::sharpen(_tmpImage, m_param1.toDouble());
        break;
    }
    case IE_SPREAD: {
        m_param1 = TQVariant(base->spread_value->value());
        _tmpImage = KImageEffect::spread(_tmpImage, m_param1.toInt());
        break;
    }
    case IE_SHADE: {
        m_param1 = TQVariant(base->shade_color->isChecked());
        m_param2 = TQVariant(base->shade_azimuth->value());
        m_param3 = TQVariant(base->shade_elevation->value());
        _tmpImage = KImageEffect::shade(_tmpImage, m_param1.toBool(), m_param2.toDouble(), m_param3.toDouble());
        break;
    }
    case IE_SWIRL: {
        m_param1 = TQVariant(base->swirl_value->value());
        _tmpImage = KImageEffect::swirl(_tmpImage, m_param1.toDouble());
        break;
    }
    case IE_WAVE: {
        m_param1 = TQVariant(base->wave_amplitude->value());
        m_param2 = TQVariant(base->wave_length->value());
        _tmpImage = KImageEffect::wave(_tmpImage, m_param1.toDouble(), m_param2.toDouble());
        break;
    }
    case IE_NONE:
    default:
        break;
    }

    m_pix.convertFromImage(_tmpImage);

    updatePreview();
}

void KPrImageEffectDia::okClicked()
{
    accept();
}


void KPrImageEffectDia::setPixmap(TQPixmap pix)
{
    m_pix = pix;
    m_origpix = pix;
    m_pix.detach();
    m_origpix.detach();
}

void KPrImageEffectDia::updatePreview()
{
    base->m_previewLabel->setPixmap(m_pix);
    base->m_previewLabel->repaint(false);
}

void KPrImageEffectDia::setEffect(ImageEffect eff, TQVariant p1, TQVariant p2, TQVariant p3)
{
    m_effect = eff;
    m_param1 = p1;
    m_param2 = p2;
    m_param3 = p3;

    switch (m_effect) {
    case IE_CHANNEL_INTENSITY: {
        base->chanInt_value->setValue(m_param1.toInt());
        base->chanInt_component->setCurrentItem(m_param2.toInt());
        break;
    }
    case IE_FADE: {
        base->fade_value->setValue(m_param1.toDouble());
        base->fade_color->setColor(m_param2.toColor());
        break;
    }
    case IE_FLATTEN: {
        base->flatten_color1->setColor(m_param1.toColor());
        base->flatten_color2->setColor(m_param2.toColor());
        break;
    }
    case IE_INTENSITY: {
        base->intensity_value->setValue(m_param1.toInt());
        break;
    }
    case IE_DESATURATE: {
        base->desaturate_value->setValue(m_param1.toDouble());
        break;
    }
    case IE_CONTRAST: {
        base->contrast_value->setValue(m_param1.toInt());
        break;
    }
    case IE_THRESHOLD: {
        base->threshold_value->setValue(m_param1.toInt());
        break;
    }
    case IE_SOLARIZE: {
        base->solarize_value->setValue(m_param1.toDouble());
        break;
    }
    case IE_CHARCOAL: {
        base->charcoal_value->setValue(m_param1.toDouble());
        break;
    }
    case IE_NOISE: {
        base->noise_type->setCurrentItem(m_param1.toInt());
        break;
    }
    case IE_BLUR: {
        base->blur_value->setValue(m_param1.toDouble());
        break;
    }
    case IE_EDGE: {
        base->edge_value->setValue(m_param1.toDouble());
        break;
    }
    case IE_IMPLODE: {
        base->implode_value->setValue(m_param1.toDouble());
        break;
    }
    case IE_OIL_PAINT: {
        base->oilPaint_radius->setValue(m_param1.toInt());
        break;
    }
    case IE_SHARPEN: {
        base->sharpen_value->setValue(m_param1.toDouble());
        break;
    }
    case IE_SPREAD: {
        base->spread_value->setValue(m_param1.toInt());
        break;
    }
    case IE_SHADE: {
        base->shade_color->setChecked(m_param1.toBool());
        base->shade_azimuth->setValue(m_param2.toDouble());
        base->shade_elevation->setValue(m_param3.toDouble());
        break;
    }
    case IE_SWIRL: {
        base->swirl_value->setValue(m_param1.toDouble());
        break;
    }
    case IE_WAVE: {
        base->wave_amplitude->setValue(m_param1.toDouble());
        base->wave_length->setValue(m_param2.toDouble());
        break;
    }

        //no params
    case IE_NORMALIZE:
    case IE_EQUALIZE:
    case IE_EMBOSS:
    case IE_DESPECKLE:

    case IE_NONE:
    default:
        break;
    }

    base->m_effectCombo->setCurrentItem(static_cast<int>(m_effect));
    base->m_widgetStack->raiseWidget(static_cast<int>(m_effect)); //bug in TQt? the above doesn't emit this :(
}

void KPrImageEffectDia::showEvent(TQShowEvent * e)
{
    KDialogBase::showEvent(e);
    effectChanged((int)m_effect);
}

void KPrImageEffectDia::setupSignals()
{
    connect((TQWidget *)base->chanInt_value, TQ_SIGNAL(valueChanged(int)),
            this, TQ_SLOT(effectParamChanged()));
    connect((TQWidget *)base->chanInt_component, TQ_SIGNAL(activated(int)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->fade_value, TQ_SIGNAL(valueChanged(double)),
            this, TQ_SLOT(effectParamChanged()));
    connect((TQWidget *)base->fade_color, TQ_SIGNAL(changed(const TQColor&)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->flatten_color1, TQ_SIGNAL(changed(const TQColor&)),
            this, TQ_SLOT(effectParamChanged()));
    connect((TQWidget *)base->flatten_color2, TQ_SIGNAL(changed(const TQColor&)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->intensity_value, TQ_SIGNAL(valueChanged(int)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->desaturate_value, TQ_SIGNAL(valueChanged(double)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->contrast_value, TQ_SIGNAL(valueChanged(int)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->threshold_value, TQ_SIGNAL(valueChanged(int)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->solarize_value, TQ_SIGNAL(valueChanged(double)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->charcoal_value, TQ_SIGNAL(valueChanged(double)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->noise_type, TQ_SIGNAL(activated(int)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->blur_value, TQ_SIGNAL(valueChanged(double)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->edge_value, TQ_SIGNAL(valueChanged(double)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->implode_value, TQ_SIGNAL(valueChanged(double)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->oilPaint_radius, TQ_SIGNAL(valueChanged(int)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->sharpen_value, TQ_SIGNAL(valueChanged(double)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->spread_value, TQ_SIGNAL(valueChanged(int)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->shade_color, TQ_SIGNAL(toggled(bool)),
            this, TQ_SLOT(effectParamChanged()));
    connect((TQWidget *)base->shade_elevation, TQ_SIGNAL(valueChanged(double)),
            this, TQ_SLOT(effectParamChanged()));
    connect((TQWidget *)base->shade_azimuth, TQ_SIGNAL(valueChanged(double)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->swirl_value, TQ_SIGNAL(valueChanged(double)),
            this, TQ_SLOT(effectParamChanged()));

    connect((TQWidget *)base->wave_amplitude, TQ_SIGNAL(valueChanged(double)),
            this, TQ_SLOT(effectParamChanged()));
    connect((TQWidget *)base->wave_length, TQ_SIGNAL(valueChanged(double)),
            this, TQ_SLOT(effectParamChanged()));
}

void KPrImageEffectDia::effectParamChanged()
{
    effectChanged(base->m_effectCombo->currentItem());
}

#include "KPrImageEffectDia.moc"
