/* -*- C++ -*-
 
  This file is part of ViPEC
  Copyright (C) 1991-2000 Johan Rossouw (jrossouw@alcatel.altech.co.za)
 
  This program 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 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 Library General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
*/

#include <TunerWindow.h>
#include <Utils.h>
#include <Strings.h>
#include <RealSlider.h>
#include <MainWindow.h>
#include <SchematicFrame.h>

#include <qlabel.h>
#include <qlayout.h>
#include <qcheckbox.h>
#include <qpushbutton.h>
#include <qapplication.h>
#include <qabstractlayout.h>

#include <iostream>

//----------------------------------------------------------------------------
TunerWindow::TunerWindow( QWidget*, const char* name )
    : QDialog( 0, name, FALSE ),
    topLayout_(0),
    gridLayout_(0),
    updateCheckbox_(0)
{
  setCaption( name );

  topLayout_ = new QVBoxLayout( this );
  QHBoxLayout* buttonLayout = new QHBoxLayout( 0 );
  gridLayout_ = new QGridLayout( 0 );

  QHBoxLayout* optionsLayout = new QHBoxLayout( 0 );
  updateCheckbox_ = new QCheckBox( this );
  QString autoLabel = Strings::translate( Strings::LabelAutoSweep );
  updateCheckbox_->setText( autoLabel );
  optionsLayout->addSpacing( 30 );
  optionsLayout->addWidget( updateCheckbox_ );

  topLayout_->addSpacing( 10 );
  topLayout_->addItem( optionsLayout );
  topLayout_->addSpacing( 10 );
  topLayout_->addItem( gridLayout_ );
  topLayout_->addSpacing( 10 );
  topLayout_->addItem( buttonLayout );

  QString sweepLabel = Strings::translate( Strings::LabelSweep );
  QString closeLabel = Strings::translate( Strings::LabelClose );
  QPushButton* sweep = new QPushButton( sweepLabel, this );
  QPushButton* close = new QPushButton( closeLabel, this );
  connect ( sweep, SIGNAL( clicked() ),
            this, SLOT( sweepSlot() ) );
  connect ( close, SIGNAL( clicked() ),
            this, SLOT( closeSlot() ) );


  buttonLayout->addWidget( sweep );
  buttonLayout->addWidget( close );

  resize( topLayout_->sizeHint() );

  labelList_.setAutoDelete( TRUE );
  valueList_.setAutoDelete( TRUE );
}

//----------------------------------------------------------------------------
TunerWindow::~TunerWindow()
{
  delete topLayout_;
}

//----------------------------------------------------------------------------
void TunerWindow::destroyWidgets()
{
  QMap< QString, RealSlider* >::Iterator it;
  for( it = rangeControlMap_.begin(); it != rangeControlMap_.end(); it++ )
    {
      delete (RealSlider*) it.data();
      it.data() = 0;
    }
  rangeControlMap_.clear();
  labelList_.clear();
  valueList_.clear();
}

//----------------------------------------------------------------------------
void TunerWindow::sweepSlot()
{
  for ( unsigned int i=0; i<labelList_.count(); i++ )
    {
      const QString& name = labelList_.at( i )->text();
      RealSlider* slider = rangeControlMap_[name];
      MainWindow::instance()->updateVariable( name, slider->rangeStr() );
    }
  MainWindow::instance()->calculateResponse();
}

//----------------------------------------------------------------------------
void TunerWindow::closeSlot()
{
  close();
}

//----------------------------------------------------------------------------
void TunerWindow::setRangeList( QList<QString> nameList,
                                QList<QString> rangeList )
{
  ASSERT( nameList.count() == rangeList.count() );
  destroyWidgets();
  gridLayout_->expand( nameList.count(), 7 );
  gridLayout_->addColSpacing( 0, 30 );
  gridLayout_->addColSpacing( 1, 80 );
  gridLayout_->addColSpacing( 2, 10 );
  gridLayout_->addColSpacing( 3, 120 );
  gridLayout_->addColSpacing( 4, 10 );
  gridLayout_->addColSpacing( 5, 50 );
  gridLayout_->addColSpacing( 6, 30 );
  int row = 0;
  QString* str = 0;
  for( str = nameList.first(); str != 0; str = nameList.next() )
    {
      //Get range
      const QString* rangeStr = rangeList.at( row );
      ASSERT( rangeStr != 0 );
      TReal min = Utils::getNumericRangePart( *rangeStr, 0 );
      TReal current = Utils::getNumericRangePart( *rangeStr, 1 );
      TReal max = Utils::getNumericRangePart( *rangeStr, 2 );
      //Create label
      QLabel* label = new QLabel( this, "name" );
      label->setText( *str );
      labelList_.append( label );
      gridLayout_->addWidget( label, row, 1 );
      //Create slider
      RealSlider* slider = new RealSlider( this );
      slider->setRange( min, max );
      slider->setCurrent( current );
      connect( slider, SIGNAL( valueChanged( int ) ),
               this, SLOT( updateLabels( int ) ) );
      connect( slider, SIGNAL( sliderReleased() ),
               this, SLOT( sliderReleased() ) );
      rangeControlMap_[ *str ] = slider;
      gridLayout_->addWidget( slider, row, 3 );
      //Create value label
      QLabel* valueLabel = new QLabel( this, "name" );
      QString currentStr;
      currentStr = currentStr.sprintf("%3.3f", current);
      valueLabel->setText( currentStr );
      valueList_.append( valueLabel );
      gridLayout_->addWidget( valueLabel, row, 5 );
      row++;
    }
  resize( topLayout_->sizeHint() );
}

//----------------------------------------------------------------------------
void TunerWindow::updateLabels( int )
{
  for ( unsigned int i=0; i<labelList_.count(); i++ )
    {
      const QString& name = labelList_.at( i )->text();
      RealSlider* slider = rangeControlMap_[name];
      QLabel* label = valueList_.at(i);
      QString valueStr;
      valueStr = valueStr.sprintf("%3.3f", slider->current());
      label->setText( valueStr );
    }
  if ( updateCheckbox_ )
    {
      if ( updateCheckbox_->isChecked() )
        {
          sweepSlot();
        }
    }
}

//----------------------------------------------------------------------------
void TunerWindow::sliderReleased()
{
  //sweepSlot();
}
