/*****************************************************************************
*
* Copyright (c) 2000 - 2018, Lawrence Livermore National Security, LLC
* Produced at the Lawrence Livermore National Laboratory
* LLNL-CODE-442911
* All rights reserved.
*
* This file is  part of VisIt. For  details, see https://visit.llnl.gov/.  The
* full copyright notice is contained in the file COPYRIGHT located at the root
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
*
* Redistribution  and  use  in  source  and  binary  forms,  with  or  without
* modification, are permitted provided that the following conditions are met:
*
*  - Redistributions of  source code must  retain the above  copyright notice,
*    this list of conditions and the disclaimer below.
*  - Redistributions in binary form must reproduce the above copyright notice,
*    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
*    documentation and/or other materials provided with the distribution.
*  - Neither the name of  the LLNS/LLNL nor the names of  its contributors may
*    be used to endorse or promote products derived from this software without
*    specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
* ARE  DISCLAIMED. IN  NO EVENT  SHALL LAWRENCE  LIVERMORE NATIONAL  SECURITY,
* LLC, THE  U.S.  DEPARTMENT OF  ENERGY  OR  CONTRIBUTORS BE  LIABLE  FOR  ANY
* DIRECT,  INDIRECT,   INCIDENTAL,   SPECIAL,   EXEMPLARY,  OR   CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
* SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
* CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
* LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
* OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
*****************************************************************************/

#include "QvisSPHResampleWindow.h"

#include <SPHResampleAttributes.h>

#include <QCheckBox>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QvisVariableButton.h>


// ****************************************************************************
// Method: QvisSPHResampleWindow::QvisSPHResampleWindow
//
// Purpose: 
//   Constructor
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

QvisSPHResampleWindow::QvisSPHResampleWindow(const int type,
                         SPHResampleAttributes *subj,
                         const QString &caption,
                         const QString &shortName,
                         QvisNotepadArea *notepad)
    : QvisOperatorWindow(type,subj, caption, shortName, notepad)
{
    atts = subj;
}


// ****************************************************************************
// Method: QvisSPHResampleWindow::~QvisSPHResampleWindow
//
// Purpose: 
//   Destructor
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

QvisSPHResampleWindow::~QvisSPHResampleWindow()
{
}


// ****************************************************************************
// Method: QvisSPHResampleWindow::CreateWindowContents
//
// Purpose: 
//   Creates the widgets for the window.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

void
QvisSPHResampleWindow::CreateWindowContents()
{
    QGridLayout *mainLayout = new QGridLayout(0);
    topLayout->addLayout(mainLayout);

    minXLabel = new QLabel(tr("Minimum X"), central);
    mainLayout->addWidget(minXLabel,0,0);
    minX = new QLineEdit(central);
    connect(minX, SIGNAL(returnPressed()),
            this, SLOT(minXProcessText()));
    mainLayout->addWidget(minX, 0,1);

    maxXLabel = new QLabel(tr("Maximum X"), central);
    mainLayout->addWidget(maxXLabel,1,0);
    maxX = new QLineEdit(central);
    connect(maxX, SIGNAL(returnPressed()),
            this, SLOT(maxXProcessText()));
    mainLayout->addWidget(maxX, 1,1);

    xnumLabel = new QLabel(tr("X Grid Cells"), central);
    mainLayout->addWidget(xnumLabel,2,0);
    xnum = new QLineEdit(central);
    connect(xnum, SIGNAL(returnPressed()),
            this, SLOT(xnumProcessText()));
    mainLayout->addWidget(xnum, 2,1);

    minYLabel = new QLabel(tr("Minimum Y"), central);
    mainLayout->addWidget(minYLabel,3,0);
    minY = new QLineEdit(central);
    connect(minY, SIGNAL(returnPressed()),
            this, SLOT(minYProcessText()));
    mainLayout->addWidget(minY, 3,1);

    maxYLabel = new QLabel(tr("Maximum Y"), central);
    mainLayout->addWidget(maxYLabel,4,0);
    maxY = new QLineEdit(central);
    connect(maxY, SIGNAL(returnPressed()),
            this, SLOT(maxYProcessText()));
    mainLayout->addWidget(maxY, 4,1);

    ynumLabel = new QLabel(tr("Y Grid Cells"), central);
    mainLayout->addWidget(ynumLabel,5,0);
    ynum = new QLineEdit(central);
    connect(ynum, SIGNAL(returnPressed()),
            this, SLOT(ynumProcessText()));
    mainLayout->addWidget(ynum, 5,1);

    minZLabel = new QLabel(tr("Minimum Z"), central);
    mainLayout->addWidget(minZLabel,6,0);
    minZ = new QLineEdit(central);
    connect(minZ, SIGNAL(returnPressed()),
            this, SLOT(minZProcessText()));
    mainLayout->addWidget(minZ, 6,1);

    maxZLabel = new QLabel(tr("Maximum Z"), central);
    mainLayout->addWidget(maxZLabel,7,0);
    maxZ = new QLineEdit(central);
    connect(maxZ, SIGNAL(returnPressed()),
            this, SLOT(maxZProcessText()));
    mainLayout->addWidget(maxZ, 7,1);

    znumLabel = new QLabel(tr("Z Grid Cells"), central);
    mainLayout->addWidget(znumLabel,8,0);
    znum = new QLineEdit(central);
    connect(znum, SIGNAL(returnPressed()),
            this, SLOT(znumProcessText()));
    mainLayout->addWidget(znum, 8,1);

    tensorSupportVariableLabel = new QLabel(tr("Tensor Support"), central);
    mainLayout->addWidget(tensorSupportVariableLabel,9,0);
    int tensorSupportVariableMask = QvisVariableButton::Scalars | QvisVariableButton::Tensors | QvisVariableButton::SymmetricTensors;
    tensorSupportVariable = new QvisVariableButton(true, true, true, tensorSupportVariableMask, central);
    tensorSupportVariable->setDefaultVariable("H");
    connect(tensorSupportVariable, SIGNAL(activated(const QString&)),
            this, SLOT(tensorSupportVariableChanged(const QString&)));
    mainLayout->addWidget(tensorSupportVariable, 9,1);

    weightVariableLabel = new QLabel(tr("Weight"), central);
    mainLayout->addWidget(weightVariableLabel,10,0);
    int weightVariableMask = QvisVariableButton::Scalars;
    weightVariable = new QvisVariableButton(true, true, true, weightVariableMask, central);
    weightVariable->setDefaultVariable("mass");
    connect(weightVariable, SIGNAL(activated(const QString&)),
            this, SLOT(weightVariableChanged(const QString&)));
    mainLayout->addWidget(weightVariable, 10,1);

    RK = new QCheckBox(tr("Enable first order (more accurate) corrective kernel interpolations"), central);
    connect(RK, SIGNAL(toggled(bool)),
            this, SLOT(RKChanged(bool)));
    mainLayout->addWidget(RK, 11, 0, 1, -1, Qt::AlignLeft);
}


// ****************************************************************************
// Method: QvisSPHResampleWindow::UpdateWindow
//
// Purpose: 
//   Updates the widgets in the window when the subject changes.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

void
QvisSPHResampleWindow::UpdateWindow(bool doAll)
{

    for(int i = 0; i < atts->NumAttributes(); ++i)
    {
        if(!doAll)
        {
            if(!atts->IsSelected(i))
            {
                continue;
            }
        }

        switch(i)
        {
          case SPHResampleAttributes::ID_minX:
            minX->setText(FloatToQString(atts->GetMinX()));
            break;
          case SPHResampleAttributes::ID_maxX:
            maxX->setText(FloatToQString(atts->GetMaxX()));
            break;
          case SPHResampleAttributes::ID_xnum:
            xnum->setText(IntToQString(atts->GetXnum()));
            break;
          case SPHResampleAttributes::ID_minY:
            minY->setText(FloatToQString(atts->GetMinY()));
            break;
          case SPHResampleAttributes::ID_maxY:
            maxY->setText(FloatToQString(atts->GetMaxY()));
            break;
          case SPHResampleAttributes::ID_ynum:
            ynum->setText(IntToQString(atts->GetYnum()));
            break;
          case SPHResampleAttributes::ID_minZ:
            minZ->setText(FloatToQString(atts->GetMinZ()));
            break;
          case SPHResampleAttributes::ID_maxZ:
            maxZ->setText(FloatToQString(atts->GetMaxZ()));
            break;
          case SPHResampleAttributes::ID_znum:
            znum->setText(IntToQString(atts->GetZnum()));
            break;
          case SPHResampleAttributes::ID_tensorSupportVariable:
            tensorSupportVariable->blockSignals(true);
            tensorSupportVariable->setText(QString(atts->GetTensorSupportVariable().c_str()));
            tensorSupportVariable->blockSignals(false);
            break;
          case SPHResampleAttributes::ID_weightVariable:
            weightVariable->blockSignals(true);
            weightVariable->setText(QString(atts->GetWeightVariable().c_str()));
            weightVariable->blockSignals(false);
            break;
          case SPHResampleAttributes::ID_RK:
            RK->blockSignals(true);
            RK->setChecked(atts->GetRK());
            RK->blockSignals(false);
            break;
        }
    }
}


// ****************************************************************************
// Method: QvisSPHResampleWindow::GetCurrentValues
//
// Purpose: 
//   Gets values from certain widgets and stores them in the subject.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

void
QvisSPHResampleWindow::GetCurrentValues(int which_widget)
{
    bool doAll = (which_widget == -1);

    // Do minX
    if(which_widget == SPHResampleAttributes::ID_minX || doAll)
    {
        float val;
        if(LineEditGetFloat(minX, val))
            atts->SetMinX(val);
        else
        {
            ResettingError(tr("Minimum X"),
                FloatToQString(atts->GetMinX()));
            atts->SetMinX(atts->GetMinX());
        }
    }

    // Do maxX
    if(which_widget == SPHResampleAttributes::ID_maxX || doAll)
    {
        float val;
        if(LineEditGetFloat(maxX, val))
            atts->SetMaxX(val);
        else
        {
            ResettingError(tr("Maximum X"),
                FloatToQString(atts->GetMaxX()));
            atts->SetMaxX(atts->GetMaxX());
        }
    }

    // Do xnum
    if(which_widget == SPHResampleAttributes::ID_xnum || doAll)
    {
        int val;
        if(LineEditGetInt(xnum, val))
            atts->SetXnum(val);
        else
        {
            ResettingError(tr("X Grid Cells"),
                IntToQString(atts->GetXnum()));
            atts->SetXnum(atts->GetXnum());
        }
    }

    // Do minY
    if(which_widget == SPHResampleAttributes::ID_minY || doAll)
    {
        float val;
        if(LineEditGetFloat(minY, val))
            atts->SetMinY(val);
        else
        {
            ResettingError(tr("Minimum Y"),
                FloatToQString(atts->GetMinY()));
            atts->SetMinY(atts->GetMinY());
        }
    }

    // Do maxY
    if(which_widget == SPHResampleAttributes::ID_maxY || doAll)
    {
        float val;
        if(LineEditGetFloat(maxY, val))
            atts->SetMaxY(val);
        else
        {
            ResettingError(tr("Maximum Y"),
                FloatToQString(atts->GetMaxY()));
            atts->SetMaxY(atts->GetMaxY());
        }
    }

    // Do ynum
    if(which_widget == SPHResampleAttributes::ID_ynum || doAll)
    {
        int val;
        if(LineEditGetInt(ynum, val))
            atts->SetYnum(val);
        else
        {
            ResettingError(tr("Y Grid Cells"),
                IntToQString(atts->GetYnum()));
            atts->SetYnum(atts->GetYnum());
        }
    }

    // Do minZ
    if(which_widget == SPHResampleAttributes::ID_minZ || doAll)
    {
        float val;
        if(LineEditGetFloat(minZ, val))
            atts->SetMinZ(val);
        else
        {
            ResettingError(tr("Minimum Z"),
                FloatToQString(atts->GetMinZ()));
            atts->SetMinZ(atts->GetMinZ());
        }
    }

    // Do maxZ
    if(which_widget == SPHResampleAttributes::ID_maxZ || doAll)
    {
        float val;
        if(LineEditGetFloat(maxZ, val))
            atts->SetMaxZ(val);
        else
        {
            ResettingError(tr("Maximum Z"),
                FloatToQString(atts->GetMaxZ()));
            atts->SetMaxZ(atts->GetMaxZ());
        }
    }

    // Do znum
    if(which_widget == SPHResampleAttributes::ID_znum || doAll)
    {
        int val;
        if(LineEditGetInt(znum, val))
            atts->SetZnum(val);
        else
        {
            ResettingError(tr("Z Grid Cells"),
                IntToQString(atts->GetZnum()));
            atts->SetZnum(atts->GetZnum());
        }
    }

}


//
// Qt Slot functions
//


void
QvisSPHResampleWindow::minXProcessText()
{
    GetCurrentValues(SPHResampleAttributes::ID_minX);
    Apply();
}


void
QvisSPHResampleWindow::maxXProcessText()
{
    GetCurrentValues(SPHResampleAttributes::ID_maxX);
    Apply();
}


void
QvisSPHResampleWindow::xnumProcessText()
{
    GetCurrentValues(SPHResampleAttributes::ID_xnum);
    Apply();
}


void
QvisSPHResampleWindow::minYProcessText()
{
    GetCurrentValues(SPHResampleAttributes::ID_minY);
    Apply();
}


void
QvisSPHResampleWindow::maxYProcessText()
{
    GetCurrentValues(SPHResampleAttributes::ID_maxY);
    Apply();
}


void
QvisSPHResampleWindow::ynumProcessText()
{
    GetCurrentValues(SPHResampleAttributes::ID_ynum);
    Apply();
}


void
QvisSPHResampleWindow::minZProcessText()
{
    GetCurrentValues(SPHResampleAttributes::ID_minZ);
    Apply();
}


void
QvisSPHResampleWindow::maxZProcessText()
{
    GetCurrentValues(SPHResampleAttributes::ID_maxZ);
    Apply();
}


void
QvisSPHResampleWindow::znumProcessText()
{
    GetCurrentValues(SPHResampleAttributes::ID_znum);
    Apply();
}


void
QvisSPHResampleWindow::tensorSupportVariableChanged(const QString &varName)
{
    atts->SetTensorSupportVariable(varName.toStdString());
    SetUpdate(false);
    Apply();
}


void
QvisSPHResampleWindow::weightVariableChanged(const QString &varName)
{
    atts->SetWeightVariable(varName.toStdString());
    SetUpdate(false);
    Apply();
}


void
QvisSPHResampleWindow::RKChanged(bool val)
{
    atts->SetRK(val);
    SetUpdate(false);
    Apply();
}
