/* -*- C++ -*-
 
  This file is part of ViPEC
  Copyright (C) 1991-2001 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 <SubstrateWindow.h>

#include <Utils.h>
#include <Setup.h>
#include <Strings.h>
#include <Exception.h>
#include <SmithView.h>
#include <MainWindow.h>

#include <qlabel.h>
#include <qpixmap.h>
#include <qlayout.h>
#include <qcombobox.h>
#include <qlineedit.h>
#include <qpushbutton.h>
#include <qapplication.h>
#include <qmessagebox.h>

#include "../images/striplinesub.xpm"
#include "../images/microstripsub.xpm"

#include <iostream>

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

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

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

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

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

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

  QString nameLabelText = Strings::translate( Strings::LabelSubstrateName );
  QString typeLabelText = Strings::translate( Strings::LabelSubstrateType );
  QString erLabelText = Strings::translate( Strings::LabelDielectricConst );
  QString heightLabelText = Strings::translate( Strings::LabelHeight );
  QString thicknessLabelText = Strings::translate( Strings::LabelConductorThickness );
  QString rhoLabelText = Strings::translate( Strings::LabelLossTangent );

  gridLayout->expand( 7, 2 );
  gridLayout->addColSpacing( 0, 30 );
  gridLayout->addColSpacing( 1, 100 );
  gridLayout->addColSpacing( 2, 10 );
  gridLayout->addColSpacing( 3, 100 );
  gridLayout->addColSpacing( 4, 30 );
  gridLayout->addColSpacing( 5, 300 );
  gridLayout->addColSpacing( 6, 30 );

  for ( uint i=0; i<6; i++ )
    {
      gridLayout->addRowSpacing( i, 35 );
    }

  QLabel* nameLabel = new QLabel( nameLabelText, this );
  substrateName_ = new QLineEdit( this );
  gridLayout->addWidget( nameLabel, 0, 1 );
  gridLayout->addWidget( substrateName_, 0, 3 );

  QLabel* typeLabel = new QLabel( typeLabelText, this );
  substrateType_ = new QComboBox( this );
  gridLayout->addWidget( typeLabel, 1, 1 );
  gridLayout->addWidget( substrateType_, 1, 3 );

  QString microStripTypeText
  = Strings::translate( Strings::LabelMicroStripType );
  QString striplineTypeText
  = Strings::translate( Strings::LabelStripLineType );

  substrateType_->insertItem( striplineTypeText,
                              SubstrateDefinition::stripline );
  substrateType_->insertItem( microStripTypeText,
                              SubstrateDefinition::microstrip );

  connect( substrateType_, SIGNAL( activated( int ) ),
           this, SLOT( substrateTypeChanged( int ) ) );

  QLabel* erLabel = new QLabel( erLabelText, this );
  er_ = new QLineEdit( this );
  gridLayout->addWidget( erLabel, 2, 1 );
  gridLayout->addWidget( er_, 2, 3 );

  QLabel* heightLabel = new QLabel( heightLabelText, this );
  h_ = new QLineEdit( this );
  gridLayout->addWidget( heightLabel, 3, 1 );
  gridLayout->addWidget( h_, 3, 3 );

  QLabel* thicknessLabel = new QLabel( thicknessLabelText, this );
  t_ = new QLineEdit( this );
  gridLayout->addWidget( thicknessLabel, 4, 1 );
  gridLayout->addWidget( t_, 4, 3 );

  QLabel* rhoLabel = new QLabel( rhoLabelText, this );
  rho_ = new QLineEdit( this );
  gridLayout->addWidget( rhoLabel, 5, 1 );
  gridLayout->addWidget( rho_, 5, 3 );

  QPixmap image( striplinesub_xpm );
  imageLabel_ = new QLabel( "", this );
  imageLabel_->setPixmap( image );
  gridLayout->addMultiCellWidget( imageLabel_, 1, 5, 5, 5, Qt::AlignCenter );

  resize( topLayout_->sizeHint() );
}

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

//----------------------------------------------------------------------------
void SubstrateWindow::enableNameField( bool enable )
{
  substrateName_->setReadOnly( !enable );
}

//----------------------------------------------------------------------------
void SubstrateWindow::update( const QString& name,
                              const SubstrateDefinition& sub )
{
  substrateName_->setText( name );
  substrateType_->setCurrentItem( sub.type() );
  substrateTypeChanged( sub.type() );
  QString tmp;
  tmp.setNum( sub.er() );
  er_->setText( tmp );
  tmp.setNum( sub.height() );
  h_->setText( tmp );
  tmp.setNum( sub.thickness() );
  t_->setText( tmp );
  tmp.setNum( sub.rho() );
  rho_->setText( tmp );
}

//----------------------------------------------------------------------------
void SubstrateWindow::ok()
{
  QString name = substrateName_->text();
  name = name.upper();
  if ( name.isEmpty() )
    {
      return;
    }
  SubstrateDefinition::SubstrateType substrateType
  = (SubstrateDefinition::SubstrateType)substrateType_->currentItem();
  try
    {
      TReal er = getValue( er_->text() );
      TReal h = getValue( h_->text() );
      TReal t = getValue( t_->text() );
      TReal rho = getValue( rho_->text() );
      SubstrateDefinition sub;
      sub.setType( substrateType );
      sub.setEr( er );
      sub.setHeight( h );
      sub.setThickness( t );
      sub.setRho( rho );
      MainWindow::instance()->updateSubstrate( name, sub );
      close();
    }
  catch ( Exception::InvalidNumericalValue )
    {
      QMessageBox::warning( this, Strings::LabelApplicationName,
                            "Invalid numerical value(s)!" );
    }
}

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

//----------------------------------------------------------------------------
void SubstrateWindow::substrateTypeChanged( int type )
{
  SubstrateDefinition::SubstrateType substrateType
  = (SubstrateDefinition::SubstrateType) type;
  switch ( substrateType )
    {
    case SubstrateDefinition::microstrip:
      {
        QPixmap image( microstripsub_xpm );
        imageLabel_->setPixmap( image );
      }
      break;
    case SubstrateDefinition::stripline:
      {
        QPixmap image2( striplinesub_xpm );
        imageLabel_->setPixmap( image2 );
      }
      break;
    }
}

//----------------------------------------------------------------------------
double SubstrateWindow::getValue( const QString& text )
{
  bool ok = FALSE;
  TReal value = 0;
  value = text.toDouble( &ok );
  if ( ( !ok ) || ( value <= 0 ) )
    {
      throw Exception::InvalidNumericalValue();
    }
  return value;
}
