/**
 * This file is a part of LuminanceHDR package.
 * ----------------------------------------------------------------------
 * Copyright (C) 2006,2007 Giuseppe Rota
 *
 *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * ----------------------------------------------------------------------
 *
 * @author Giuseppe Rota <grota@users.sourceforge.net>
 */

#include "ResizeDialog.h"
#include "ui_ResizeDialog.h"

#include "Libpfs/frame.h"
#include "Libpfs/manip/resize.h"

ResizeDialog::ResizeDialog(QWidget *parent, pfs::Frame *orig):
    QDialog(parent),
    m_original(orig),
    m_resized(NULL),
    m_Ui(new Ui::ResizeDialog)
{
    m_Ui->setupUi(this);

    orig_width = m_original->getWidth();
    orig_height = m_original->getHeight();
    resized_width = orig_width;
    resized_height = orig_height;

    m_Ui->widthSpinBox->setSuffix("");
    m_Ui->widthSpinBox->setDecimals(0);
    m_Ui->widthSpinBox->setMaximum(2*orig_width);
    m_Ui->widthSpinBox->setMinimum(1);

    m_Ui->heightSpinBox->setSuffix("");
    m_Ui->heightSpinBox->setDecimals(0);
    m_Ui->heightSpinBox->setMaximum(2*orig_height);
    m_Ui->heightSpinBox->setMinimum(1);
    //we are now in pixel mode, put directly original pixel values.
    m_Ui->widthSpinBox->setValue(orig_width);
    m_Ui->heightSpinBox->setValue(orig_height);

    from_other_spinbox = false;
    updatelabel();

    connect(m_Ui->scaleButton,SIGNAL(clicked()),this,SLOT(scaledPressed()));
    connect(m_Ui->widthSpinBox,SIGNAL(editingFinished()),this,SLOT(update_heightSpinBox()));
    connect(m_Ui->widthSpinBox,SIGNAL(valueChanged(double)),this,SLOT(update_heightSpinBox()));
    connect(m_Ui->heightSpinBox,SIGNAL(editingFinished()),this,SLOT(update_widthSpinBox()));
    connect(m_Ui->heightSpinBox,SIGNAL(valueChanged(double)),this,SLOT(update_widthSpinBox()));
    connect(m_Ui->px_or_percentage,SIGNAL(activated(int)),this,SLOT(switch_px_percentage(int)));
    connect(m_Ui->restoredefault,SIGNAL(clicked()),this,SLOT(defaultpressed()));
}

ResizeDialog::~ResizeDialog() {
//we don't delete *original, because in maingui_impl.cpp we will later call mdiwin->updateHDR which takes care of deleting its previous pfs::Frame* buffer.
}

pfs::Frame* ResizeDialog::getResizedFrame() {
    return m_resized;
}

void ResizeDialog::scaledPressed() {
    if (orig_width==resized_width) {
        emit reject();
        return;
    }
    m_resized = pfs::resize(m_original, resized_width, BilinearInterp);
    accept();
}

void ResizeDialog::switch_px_percentage(int px_per) {

    switch (px_per) {
    case 0:
        m_Ui->widthSpinBox->setMaximum(2*orig_width);
        m_Ui->heightSpinBox->setMaximum(2*orig_height);
        from_other_spinbox = true;
        m_Ui->widthSpinBox->setValue((int)(m_Ui->widthSpinBox->value()*(float)orig_width/100.0)); //from perc to px
        from_other_spinbox = true;
        m_Ui->heightSpinBox->setValue((int)(m_Ui->heightSpinBox->value()*(float)orig_height/100.0)); //from perc to px
        m_Ui->widthSpinBox->setSuffix("");
        m_Ui->widthSpinBox->setDecimals(0);
        m_Ui->widthSpinBox->setMinimum(1);
        m_Ui->heightSpinBox->setSuffix("");
        m_Ui->heightSpinBox->setDecimals(0);
        m_Ui->heightSpinBox->setMinimum(1);
        break;
    case 1:
        m_Ui->widthSpinBox->setDecimals(2);
        m_Ui->heightSpinBox->setDecimals(2);
        from_other_spinbox = true;
        m_Ui->widthSpinBox->setValue(100*m_Ui->widthSpinBox->value()/(float)orig_width); //from px to perc
        from_other_spinbox = true;
        m_Ui->heightSpinBox->setValue(100*m_Ui->heightSpinBox->value()/(float)orig_height); //from px to perc
        m_Ui->widthSpinBox->setSuffix("%");
        m_Ui->widthSpinBox->setMaximum(200);
        m_Ui->widthSpinBox->setMinimum(1);
        m_Ui->heightSpinBox->setSuffix("%");
        m_Ui->heightSpinBox->setMaximum(200);
        m_Ui->heightSpinBox->setMinimum(1);
        break;
    }
    from_other_spinbox = false;
    updatelabel();
}
//get a proper resized_width from a resized_height
int ResizeDialog::rw_from_rh() {
    return (int)((float)orig_width*(float)resized_height/(float)orig_height);
}
//get a proper resized_height from a resized_width
int ResizeDialog::rh_from_rw() {
    return (int)((float)orig_height*(float)resized_width/(float)orig_width);
}
void ResizeDialog::update_heightSpinBox() {
    if (from_other_spinbox) {
        from_other_spinbox=false;
        return;
    }
    switch (m_Ui->px_or_percentage->currentIndex()) {
    case 0:
        resized_width=(int)m_Ui->widthSpinBox->value();
        resized_height=rh_from_rw();
        from_other_spinbox=true;
        //update directly resized_height
        m_Ui->heightSpinBox->setValue(resized_height);
    break;
    case 1:
        resized_width=(int)(orig_width*m_Ui->widthSpinBox->value()/100.0);
        resized_height=rh_from_rw();
        from_other_spinbox=true;
        m_Ui->heightSpinBox->setValue((double)resized_height/(double)orig_height*100.0);
    break;
    }
    updatelabel();
}
void ResizeDialog::update_widthSpinBox() {
    if (from_other_spinbox) {
        from_other_spinbox=false;
        return;
    }
    switch (m_Ui->px_or_percentage->currentIndex()) {
    case 0:
        resized_height=(int)m_Ui->heightSpinBox->value();
        resized_width=rw_from_rh();
        from_other_spinbox=true;
        //update directly resized_width
        m_Ui->widthSpinBox->setValue(resized_width);
        break;
    case 1:
        resized_height=(int)(orig_height*m_Ui->heightSpinBox->value()/100.0);
        resized_width=rw_from_rh();
        from_other_spinbox=true;
        m_Ui->widthSpinBox->setValue((double)resized_width/(double)orig_width*100.0);
        break;
    }
    updatelabel();
}
void ResizeDialog::updatelabel() {
    m_Ui->sizepreview->setText(QString("%1x%2").arg(resized_width).arg(resized_height));
}

void ResizeDialog::defaultpressed() {
    resized_height=orig_height;
    resized_width=orig_width;
    switch (m_Ui->px_or_percentage->currentIndex()) {
    case 0:
        from_other_spinbox=true;
        m_Ui->widthSpinBox->setValue(resized_width);
        from_other_spinbox=true;
        m_Ui->heightSpinBox->setValue(resized_height);
        from_other_spinbox=false;
        break;
    case 1:
        from_other_spinbox=true;
        m_Ui->widthSpinBox->setValue(100);
        from_other_spinbox=true;
        m_Ui->heightSpinBox->setValue(100);
        from_other_spinbox=false;
        break;
    }
    updatelabel();
}
