/*
 *  dlg_imagesize.cpp - part of KimageShop^WKrayon^WChalk
 *
 *  Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <config.h>

#include <math.h>

#include <iostream>

using namespace std;

#include <tqradiobutton.h>
#include <tqcheckbox.h>
#include <tqbuttongroup.h>
#include <tqlabel.h>
#include <tqcombobox.h>

#include <tdelocale.h>
#include <knuminput.h>
#include <kdebug.h>

#include <kis_cmb_idlist.h>
#include <kis_filter_strategy.h>

#include "dlg_imagesize.h"
#include "wdg_imagesize.h"


// XXX: I'm really real bad at arithmetic, let alone math. Here
// be rounding errors. (Boudewijn)
DlgImageSize::DlgImageSize( TQWidget *  parent,
                const char * name)
    : super (parent, name, true, i18n("Image Size"), Ok | Cancel, Ok)
{
    m_lock = false;

    m_page = new WdgImageSize(this, "image_size");
    TQ_CHECK_PTR(m_page);

    m_page->cmbFilterType->setIDList(KisFilterStrategyRegistry::instance()->listKeys());
    m_page->cmbFilterType->setCurrentText("Mitchell");

    setMainWidget(m_page);
    resize(m_page->sizeHint());

    unblockAll();


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

}

DlgImageSize::~DlgImageSize()
{
    delete m_page;
}

void DlgImageSize::hideScaleBox()
{
    m_page->grpResizeScale->hide();
}

void DlgImageSize::setWidth(TQ_UINT32 w)
{
    blockAll();

    m_page->lblWidthOriginal->setNum((int)w);
    m_page->intWidth->setValue(w);
    m_oldW = w;
    m_origW = w;

    unblockAll();
}

void DlgImageSize::setWidthPercent(TQ_UINT32 w)
{
    blockAll();

    m_page->intWidthPercent->setValue(w);
    m_oldWPercent = w;

    unblockAll();
}


void DlgImageSize::setMaximumWidth(TQ_UINT32 w)
{
    m_page->intWidth->setMaxValue(w);
    m_maxW = w;
}

TQ_INT32 DlgImageSize::width()
{
    //return (TQ_INT32)tqRound(m_oldW);
    return (TQ_INT32)tqRound(m_page->intWidth->value());
}

void DlgImageSize::setHeight(TQ_UINT32 h)
{
    blockAll();

    m_page->lblHeightOriginal->setNum((int)h);
    m_page->intHeight->setValue(h);
    m_oldH = h;
    m_origH = h;

    unblockAll();
}


void DlgImageSize::setHeightPercent(TQ_UINT32 h)
{
    blockAll();

    m_page->intHeightPercent->setValue(h);
    m_oldHPercent = h;

    unblockAll();
}



void DlgImageSize::setMaximumHeight(TQ_UINT32 h)
{
    m_page->intHeight->setMaxValue(h);
    m_maxH = h;
}


TQ_INT32 DlgImageSize::height()
{
    //return (TQ_INT32)tqRound(m_oldH);
    return (TQ_INT32)tqRound(m_page->intHeight->value());
}

bool DlgImageSize::scale()
{
    return m_page->radioScale->isChecked();
}

bool DlgImageSize::cropLayers()
{
    return m_page->chkCrop->isChecked();
}

KisFilterStrategy *DlgImageSize::filterType()
{
    KisID filterID = m_page->cmbFilterType->currentItem();
    KisFilterStrategy *filter = KisFilterStrategyRegistry::instance()->get(filterID);
    return filter;
}

// SLOTS

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

void DlgImageSize::slotWidthPixelsChanged(int w)
{
    blockAll();

    double wPercent = double(w) * 100 / double(m_origW);

    m_page->intWidthPercent->setValue(tqRound(wPercent));

    // Set height in pixels and percent of necessary
    if (m_page->chkConstrain->isChecked()) {
        m_page->intHeightPercent->setValue(tqRound(wPercent));

        m_oldH = tqRound(m_origH * wPercent / 100);
        m_page->intHeight->setValue(tqRound(m_oldH));

    }
    m_oldW = w;

    unblockAll();
}

void DlgImageSize::slotHeightPixelsChanged(int h)
{
    blockAll();

    double hPercent = double(h) * 100 / double(m_origH);

    m_page->intHeightPercent->setValue(tqRound(hPercent));

    // Set width in pixels and percent of necessary
    if (m_page->chkConstrain->isChecked()) {
        m_page->intWidthPercent->setValue(tqRound(hPercent));

        m_oldW = tqRound(m_origW * hPercent / 100);
        m_page->intWidth->setValue(tqRound(m_oldW));

    }
    m_oldH = h;

    unblockAll();
}

void DlgImageSize::slotWidthPercentChanged(int w)
{
    blockAll();

    m_page->intWidth->setValue(tqRound(w * m_origW / 100));

    if (m_page->chkConstrain->isChecked()) {
        m_page->intHeightPercent->setValue(w);
        m_page->intHeight->setValue(tqRound( w * m_origH / 100));
    }

    unblockAll();
}

void DlgImageSize::slotHeightPercentChanged(int h)
{
    blockAll();

    m_page->intHeight->setValue(tqRound(h * m_origH / 100));
    if (m_page->chkConstrain->isChecked()) {
        m_page->intWidthPercent->setValue(h);
        m_page->intWidth->setValue(tqRound( h * m_origW / 100));
    }

    unblockAll();

}


void DlgImageSize::blockAll()
{
    // XXX: more efficient to use blockSignals?
    m_page->intWidth->disconnect();
    m_page->intHeight->disconnect();
    m_page->intWidthPercent->disconnect();
    m_page->intHeightPercent->disconnect();

}

void DlgImageSize::unblockAll()
{
    // XXX: more efficient to use blockSignals?
    connect (m_page->intWidth, TQ_SIGNAL(valueChanged(int)),
         this, TQ_SLOT(slotWidthPixelsChanged(int)));

    connect (m_page->intHeight, TQ_SIGNAL(valueChanged(int)),
         this, TQ_SLOT(slotHeightPixelsChanged(int)));

    connect (m_page->intWidthPercent, TQ_SIGNAL(valueChanged(int)),
         this, TQ_SLOT(slotWidthPercentChanged(int)));

    connect (m_page->intHeightPercent, TQ_SIGNAL(valueChanged(int)),
         this, TQ_SLOT(slotHeightPercentChanged(int)));


}

#include "dlg_imagesize.moc"
