/***************************************************************************
 *   Copyright (C) 2004 by Armando Navarro-Vazquez                         *
 *   qoajnv@usc.es                                                         *
 *                                                                         *
 *   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.             *
 ***************************************************************************/

#include <iostream>

#include <q3table.h>
#include <qpushbutton.h>
#include <q3filedialog.h>
#include <qlineedit.h>
#include <qmessagebox.h>
#include <qvalidator.h>
#include <qslider.h>
#include <qspinbox.h>
#include <qcombobox.h>

#include "qfreqwidget.h"
#include "irspectrum.h"
#include "qlogtable.h"

QFreqWidget::QFreqWidget(const QString& file,QWidget* parent)
    : QWidget(parent)
{
  setupUi(this);
  if( file != QString::null)
    m_file=file.latin1();
  else
    m_file="Unnamed";

  Q3Header* vheader= freqTable->verticalHeader();
  Q3Header*  hheader=freqTable->horizontalHeader();
  hheader->setLabel(0,"Freq (cm-1)");
  vheader->setResizeEnabled(false);
  hheader->setResizeEnabled(false);
  connect(vheader,SIGNAL(clicked(int)),this,SLOT(OnTableSelection(int)));
  connect(freqTable,SIGNAL(currentChanged(int,int)),this,SLOT(OnTableSelection(int)));
  freqTable->setReadOnly(true);
  freqTable->setSorting(true);
  freqTable->setColumnStretchable(0,true);
  freqTable->setColumnStretchable(1,true);

  m_bshowspectrum=true;

  connect(showSpecButton,SIGNAL(clicked()),this,SLOT(OnShowSpectrum()));
  connect(_exportIRButton,SIGNAL(clicked()),this,SLOT(OnWriteJCampDX()));

  connect(_leftLimitLineEdit,SIGNAL(returnPressed()),this,SLOT(OnChangeLimits()));
  connect(_rightLimitLineEdit,SIGNAL(returnPressed()),this,SLOT(OnChangeLimits()));
  connect(_resetLimitsButton,SIGNAL(clicked()),this,SLOT(OnResetLimits()));

  connect(_movieButton,SIGNAL(toggled(bool)),this,SLOT(OnRecordMovie(bool)));

  connect(_distortionSlider,SIGNAL(valueChanged(int)),this,SLOT(OnDistort(int)));
  //connect(this,SIGNAL(distort(int)),this,SLOT(OnDistort(int)));
  connect(_resetDistortionButton,SIGNAL(clicked()),this,SLOT(OnResetDistortions()));

  //Setup between 1 and 50 cm-1
   float linewidth=LineWidth();
  _lineWidthSpinBox->setMinimum(1);
  _lineWidthSpinBox->setMaximum(500);
  _lineWidthSpinBox->setValue(linewidth);
  connect(_lineWidthSpinBox,SIGNAL(valueChanged(double)),this,SLOT(OnSetLineWidth(double)));

  QDoubleValidator* val= new QDoubleValidator(this);
  val->setBottom(0);
  val->setTop(1);
  _scaleLineEdit->setValidator(val);
  _scaleLineEdit->setText("1.00");
  connect(_scaleLineEdit,SIGNAL(returnPressed()),this,SLOT(OnScaling()));

  connect(_spectrumTypeComboBox,SIGNAL(activated(int)),this,SLOT(OnSpectrumTypeChanged(int)));

  m_activemode=0;
}


QFreqWidget::~QFreqWidget()
{}

void QFreqWidget::InitTable()
{

  QString sheader;
  switch(GetType())
  {
  case IR:
    sheader="IR Intensity";
    break;
  case VCD:
    sheader="Rotatory Strength";
    break;
  }
  freqTable->horizontalHeader()->setLabel(1,sheader);
  //SetFrequencies(m_list);
  std::vector<frequency>::iterator it;

  freqTable->setNumRows(m_frequencies.size());
  m_distortframes.resize(m_frequencies.size());
  for(size_t i=0;i<m_frequencies.size();i++)
  {
    m_distortframes[i]=0;
  }

  int i;
  Q3Header* vh=freqTable->verticalHeader();
  for(it=m_frequencies.begin(),i=0;it!=m_frequencies.end();it++,i++)
  {
    QString sf, si;
    sf.setNum(it->x,'f',1);
    switch(GetType())
    {
    case VCD:
      si.setNum(it->z,'f',3);
      break;
    default:
      si.setNum(it->y,'f',1);
    }
    freqTable->setText(i,0,sf);
    freqTable->setText(i,1,si);
    QString str;
    str.sprintf("%d",i+1);
    vh->setLabel(i,str);
  }

  //initialize the irspectrum object

  SetAutoLimits();
  //write the limits
  QString max,min;
  max.setNum(Max());
  min.setNum(Min());
  _leftLimitLineEdit->setText(max);
  _rightLimitLineEdit->setText(min);
  SetLineWidth(_lineWidthSpinBox->value());
  CalculateSpectrum();
  emit Type(GetType()); //to stablish the baseline

}

void QFreqWidget::OnWriteJCampDX()
{

  //propose a name for the file
  QString sfile(m_file.c_str());
  QString sfilename=sfile.section('.',0,-2)+".jdx"; //change out extension by jdx
  QString file= Q3FileDialog::getSaveFileName(sfilename,"JCAMP-DX (*.jdx)",
                this,
                "KryoMoll",
                "Write JCAMP-DX spectrum" );
  if( file != QString::null)
  {
    m_file=file.latin1();
    WriteJCampDX();
  }

}

void QFreqWidget::OnChangeLimits()
{
  float min =_rightLimitLineEdit->text().toFloat();
  float max =_leftLimitLineEdit->text().toFloat();
  if( max < min)
  {
    QMessageBox mb;
    mb.setText("Sorry, limits are inverted");
    mb.exec();
    return;
  }
  SetLimits(max,min);
  emit data(GetData(),Max(),Min());

}

void QFreqWidget::OnResetLimits()
{
  SetAutoLimits();
  //write the limits
  QString max,min;
  max.setNum(Max());
  min.setNum(Min());
  _leftLimitLineEdit->setText(max);
  _rightLimitLineEdit->setText(min);
  CalculateSpectrum();
  emit data(GetData(),Max(),Min());

}

void QFreqWidget::OnSetLimits(float max,float min)
{
  QString smax,smin;
  smax.setNum(max);
  smin.setNum(min);
  _leftLimitLineEdit->setText(smax);
  _rightLimitLineEdit->setText(smin);
  SetLimits(max,min);
  emit data(GetData(),Max(),Min());
}
void QFreqWidget::OnShowSpectrum()
{
  emit showspectrum(m_bshowspectrum);
  emit Type(GetType()); //to stablish the baseline
  m_bshowspectrum=!m_bshowspectrum;

  QString buttontext;
  if(!m_bshowspectrum)
  {
    buttontext=tr("Hide Spectrum");
  }
  else buttontext=tr("Show Spectrum");

  showSpecButton->setText(buttontext);

}

void QFreqWidget::OnScaling()
{

  float scale=_scaleLineEdit->text().toFloat();

  std::vector<frequency>::iterator it;
  IRSpectrum::SetFrequencies(m_list,scale);

  int i;
  for(it=m_frequencies.begin(),i=0;it!=m_frequencies.end();it++,i++)
  {
    QString sf, si;
    sf.setNum(it->x,'f',1);
    si.setNum(it->y,'f',1);
    freqTable->setText(i,0,sf);
    freqTable->setText(i,1,si);
  }

  //initialize the irspectrum object

  SetAutoLimits();
  //write the limits
  QString max,min;
  max.setNum(Max());
  min.setNum(Min());
  _leftLimitLineEdit->setText(max);
  _rightLimitLineEdit->setText(min);
  CalculateSpectrum();
  emit data(GetData(),Max(),Min());

}


void QFreqWidget::SetFrequencies(std::vector<frequency>& v)
{
  m_list=v;
  IRSpectrum::SetFrequencies(v);


}

void QFreqWidget::OnTableSelection(int s)
{
  if ( s < 0 || s > freqTable->numRows()-1 ) return;
  int signal=freqTable->verticalHeader()->label(s).toInt();
  OnAnimate(signal-1);
  
}
void QFreqWidget::OnAnimate(int m)
{
  m_activemode=m;
  _distortionSlider->blockSignals(true);
  _distortionSlider->setValue(m_distortframes[m_activemode]);
  _distortionSlider->blockSignals(false);
  emit mode(m,m_distortframes[m]);
}

void QFreqWidget::OnDisableControls(bool b)
{
  _distortionSlider->setEnabled(!b);
  _resetDistortionButton->setEnabled(!b);
}

void QFreqWidget::OnSetLineWidth(double lw)
{
  std::cout << "line width set to " << lw << std::endl;
  SetLineWidth(lw);
  CalculateSpectrum();
  emit data(GetData(),Max(),Min());
}

void QFreqWidget::OnDistort(int d)
{
  std::cout << "distort values is " << d << std::endl;
  m_distortframes[m_activemode]=_distortionSlider->value();
  emit distort(d);
}

void QFreqWidget::OnResetDistortions()
{
  emit reset();
  for(size_t i=0;i<m_distortframes.size();i++)
  {
    m_distortframes[i]=0;
  }
  _distortionSlider->blockSignals(true);
  _distortionSlider->setValue(0);
  _distortionSlider->blockSignals(false);
}

void QFreqWidget::OnSpectrumTypeChanged(int t)
{
  SetType(static_cast<SpectrumType>(t));
  InitTable();
  emit data(GetData(),Max(),Min());
  emit Type(GetType()); //to stablish the baseline
}
