/* -*- 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 <ModifyOutputParameterWindow.h>

#include <Setup.h>
#include <Strings.h>
#include <GraphDefinition.h>
#include <MainWindow.h>
#include <NavigationWindow.h>

#include <qlabel.h>
#include <qlayout.h>
#include <qcombobox.h>
#include <qlineedit.h>
#include <qcheckbox.h>
#include <qpushbutton.h>
#include <qradiobutton.h>
#include <qhbuttongroup.h>
#include <qapplication.h>
#include <qvalidator.h>
#include <qmessagebox.h>

#include <iostream>

//----------------------------------------------------------------------------
ModifyOutputParameterWindow::ModifyOutputParameterWindow( QWidget* parent, const char* name )
    : QDialog(parent, name, TRUE),
    topLayout_(0),
    definition_(0)
{
  setCaption( name );

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

  topLayout_->addSpacing( 10 );
  topLayout_->addItem( grid );
  topLayout_->addSpacing( 10 );
  topLayout_->addItem( buttonLayout );

  QPushButton* ok = new QPushButton( Strings::translate( Strings::LabelOk ), this );
  QPushButton* cancel = new QPushButton( Strings::translate( Strings::LabelCancel ), this );

  buttonLayout->addWidget( ok );
  buttonLayout->addWidget( cancel );

  connect ( ok, SIGNAL( clicked() ),
            this, SLOT( ok() ) );
  connect ( cancel, SIGNAL( clicked() ),
            this, SLOT( cancel() ) );


  grid->expand( 13, 7 );
  grid->addColSpacing( 0, 30 );
  grid->addColSpacing( 12, 30 );
  for ( uint i=1; i<12; i++ )
    {
      grid->addColSpacing( i, 10 );
    }
  grid->addColSpacing( 1, 100 );
  grid->addColSpacing( 3, 100 );
  grid->addColSpacing( 4, 30 );

  for (uint j=0; j<7; j++)
    {
      grid->addRowSpacing( j, 5 );
    }

  measurementType_ =  new QComboBox( this );
  measurementType_->insertItem( Strings::translate( Strings::LabelPortParameters ),
                                ResultDefinition::portParameters );
  measurementType_->insertItem( Strings::translate( Strings::LabelLinvillStablilityFactor ),
                                ResultDefinition::linvillStabilityFactor );
  measurementType_->insertItem( Strings::translate( Strings::LabelSternStabilityFactor ),
                                ResultDefinition::sternStabilityFactor );

  measurement_ = new QComboBox( this );
  measurement_->insertItem( Strings::translate( Strings::LabelS_Parameters ) );
  measurement_->insertItem( Strings::translate( Strings::LabelY_Parameters ) );
  measurement_->insertItem( Strings::translate( Strings::LabelZ_Parameters ) );
  measurement_->insertItem( Strings::translate( Strings::LabelGroupDelay ) );

  grid->addWidget( new QLabel( Strings::translate( Strings::LabelMeasurementType ), this), 1, 1 );
  grid->addWidget( measurementType_, 1, 3 );
  grid->addWidget( new QLabel( Strings::translate( Strings::LabelMeasurement ), this), 3, 1 );
  grid->addWidget( measurement_, 3, 3 );

  buttonGroup_ = new QHButtonGroup( Strings::translate( Strings::LabelFormat ), this );
  realFormat_ = new QRadioButton( Strings::translate( Strings::LabelReal ), buttonGroup_ );
  realFormat_->setChecked( TRUE );
  imagFormat_ = new QRadioButton( Strings::translate( Strings::LabelImag ), buttonGroup_ );
  magFormat_ = new QRadioButton( Strings::translate( Strings::LabelMagnitude ), buttonGroup_ );
  angFormat_ = new QRadioButton( Strings::translate( Strings::LabelAngle ), buttonGroup_ );
  grid->addMultiCellWidget( buttonGroup_, 5, 5, 1, 3 );

  dataSource_ = new QComboBox( this );
  fromPort_ = new QComboBox( this );
  toPort_ = new QComboBox( this );
  dbResults_ = new QCheckBox( Strings::translate( Strings::LabelResultsInDB ), this );

  grid->addMultiCellWidget( new QLabel( Strings::translate( Strings::LabelDataSource ), this),
                            1, 1, 5, 7 );
  grid->addMultiCellWidget( dataSource_, 1, 1, 9, 11 );
  grid->addWidget( new QLabel(Strings::translate( Strings::LabelToPort ), this), 3, 5 );
  grid->addWidget( toPort_, 3, 7 );
  grid->addWidget( new QLabel(Strings::translate( Strings::LabelFromPort ), this), 3, 9 );
  grid->addWidget( fromPort_, 3, 11 );
  grid->addMultiCellWidget( dbResults_, 5, 5, 5, 11, Qt::AlignHCenter);

  connect( dataSource_, SIGNAL( activated( int ) ),
           this, SLOT( slotDataSourceChanged( int ) ) );

  connect( measurementType_, SIGNAL( activated( int ) ),
           this, SLOT( measurementTypeChanged( int ) ) );

  resize( topLayout_->sizeHint() );
}

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

//----------------------------------------------------------------------------
void ModifyOutputParameterWindow::ok()
{
  GraphDefinition* graph = MainWindow::instance()->findGraph( name_ );
  ASSERT( graph != 0 );

  if ( definition_ == 0 )
    {
      definition_ = new ResultDefinition();
      graph->addOutputDefinition( definition_ );
    }

  definition_->setType( (ResultDefinition::MeasurementType) measurementType_->currentItem() );
  definition_->setMeasurement( (ResultDefinition::Measurement) measurement_->currentItem() );

  ResultDefinition::MeasurementFormat format = ResultDefinition::realFormat;
  if ( realFormat_->isChecked() )
    format = ResultDefinition::realFormat;
  if ( imagFormat_->isChecked() )
    format = ResultDefinition::imagFormat;
  if ( magFormat_->isChecked() )
    format = ResultDefinition::magnitudeFormat;
  if ( angFormat_->isChecked() )
    format = ResultDefinition::angleFormat;

  definition_->setDbResults( dbResults_->isChecked() );
  definition_->setFormat( format );
  definition_->setSource( dataSource_->currentText() );
  definition_->setTo( toPort_->currentItem() + 1 );
  definition_->setFrom( fromPort_->currentItem() + 1 );

  MainWindow::instance()->setFileChanged();
  NavigationWindow::instance()->updateOutputDefinition( name_, *definition_ );

  close();
}

//----------------------------------------------------------------------------
void ModifyOutputParameterWindow::cancel()
{
  close();
}

//----------------------------------------------------------------------------
bool ModifyOutputParameterWindow::initialize( const QString& name,
    ResultDefinition* definition )
{
  name_ = name;
  definition_ = definition;

  GraphDefinition* graph = MainWindow::instance()->findGraph( name );
  GraphDefinition::GraphType type = graph->graphType();

  bool isSmithView = ( type == GraphDefinition::smithType ) ? TRUE : FALSE;

  dbResults_->setEnabled( !isSmithView );
  buttonGroup_->setEnabled( !isSmithView );

  if ( isSmithView )
    {
      measurementType_->setCurrentItem( 0 );
      measurement_->setCurrentItem( 0 );
    }

  measurementType_->setEnabled( !isSmithView );
  measurement_->setEnabled( !isSmithView );

  //Initialize data source
  QStringList list;
  MainWindow::instance()->getSchematicNames( list );
  bool result = TRUE;
  dataSource_->clear();

  if ( list.isEmpty() )
    {
      QMessageBox::warning( MainWindow::instance(), Strings::LabelApplicationName,
                            tr(Strings::MsgNoSchematicsDefined),
                            tr(Strings::LabelOk),
                            0, 0, 0, 0);
      result = FALSE;
    }
  else
    {
      QString currentSource;
      if ( definition )
        {
          currentSource = definition_->source();
        }
      int currentItem = 0;
      int index = 0;
      for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
        {
          const QString& source = (*it);
          if ( (currentSource.isNull() == false) &&
               (source.compare(currentSource) == 0) )
            {
              currentItem = index;
            }
          dataSource_->insertItem( (*it).latin1() );
          index++;
        }
      dataSource_->setCurrentItem( currentItem );
      slotDataSourceChanged( currentItem );
    }

  if ( definition )
    {
      measurementType_->setCurrentItem( definition->type() );
      measurement_->setCurrentItem( definition->measurement() );
      fromPort_->setCurrentItem( definition->from() - 1 );
      dbResults_->setChecked( definition->db() );
      toPort_->setCurrentItem( definition->to() - 1 );
      if ( definition->format() == ResultDefinition::realFormat )
        {
          realFormat_->setChecked( TRUE );
        }
      if ( definition->format() == ResultDefinition::imagFormat )
        {
          imagFormat_->setChecked( TRUE );
        }
      if ( definition->format() == ResultDefinition::magnitudeFormat )
        {
          magFormat_->setChecked( TRUE );
        }
      if ( definition->format() == ResultDefinition::angleFormat )
        {
          angFormat_->setChecked( TRUE );
        }
    }

  return result;
}

//----------------------------------------------------------------------------
void ModifyOutputParameterWindow::slotDataSourceChanged( int )
{
  QString name = dataSource_->currentText();
  Schematic* schematic = MainWindow::instance()->getSchematic( name );
  ASSERT( schematic != 0 );
  uint nrPorts = schematic->getNumberOfPorts();
  toPort_->clear();
  fromPort_->clear();
  for ( uint i=0; i<nrPorts; i++ )
    {
      QString nrStr;
      nrStr.setNum( i+1 );
      toPort_->insertItem( nrStr );
      fromPort_->insertItem( nrStr );
    }
}

//----------------------------------------------------------------------------
void ModifyOutputParameterWindow::measurementTypeChanged( int )
{
  QString text = measurementType_->currentText();
  bool portParameter = ( text == Strings::translate( Strings::LabelPortParameters ) );
  measurement_->setEnabled( portParameter );
  buttonGroup_->setEnabled( portParameter );
  toPort_->setEnabled( portParameter );
  fromPort_->setEnabled( portParameter );
  dbResults_->setEnabled( portParameter );
}
