/* -*- 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 <Strings.h>
#include <Utils.h>
#include <MainWindow.h>
#include <ResultDefinition.h>

#include <qdom.h>
#include <qtextstream.h>

QList<ResultDefinition>* ResultDefinition::resultDefinitions_ = 0;

//-----------------------------------------------------------------
ResultDefinition::ResultDefinition()
    : measurementType_( portParameters ),
    measurement_( sParameters ),
    format_( magnitudeFormat ),
    dataSource_( 0 ),
    toPort_( 1 ),
    fromPort_( 1 ),
    dbResults_( TRUE )
{
  resultId_ = MainWindow::instance()->getUniqueID();
  if ( resultDefinitions_ == 0 )
    {
      resultDefinitions_ = new QList<ResultDefinition>;
    }
  resultDefinitions_->append( this );
}

//-----------------------------------------------------------------
ResultDefinition::~ResultDefinition()
{
  resultDefinitions_->remove
  ( this );
}

//-----------------------------------------------------------------
long int ResultDefinition::id() const
  {
    return resultId_;
  }

//-----------------------------------------------------------------
ResultDefinition::MeasurementType ResultDefinition::type() const
  {
    return measurementType_;
  }

//-----------------------------------------------------------------
ResultDefinition::Measurement ResultDefinition::measurement() const
  {
    return measurement_;
  }

//-----------------------------------------------------------------
ResultDefinition::MeasurementFormat ResultDefinition::format() const
  {
    return format_;
  }

//-----------------------------------------------------------------
const QString& ResultDefinition::source() const
  {
    return dataSource_;
  }

//-----------------------------------------------------------------
uint ResultDefinition::to() const
  {
    return toPort_;
  }

//-----------------------------------------------------------------
uint ResultDefinition::from() const
  {
    return fromPort_;
  }

//-----------------------------------------------------------------
bool ResultDefinition::db() const
  {
    return dbResults_;
  }

//-----------------------------------------------------------------
void ResultDefinition::setType( MeasurementType type )
{
  measurementType_ = type;
}

//-----------------------------------------------------------------
void ResultDefinition::setMeasurement( Measurement measure )
{
  measurement_ = measure;
}

//-----------------------------------------------------------------
void ResultDefinition::setFormat( MeasurementFormat format )
{
  format_ = format;
}

//-----------------------------------------------------------------
void ResultDefinition::setSource( const QString& source )
{
  dataSource_ = source;
}

//-----------------------------------------------------------------
void ResultDefinition::setTo( uint port )
{
  toPort_ = port;
}

//-----------------------------------------------------------------
void ResultDefinition::setFrom( uint port )
{
  fromPort_ = port;
}

//-----------------------------------------------------------------
void ResultDefinition::setDbResults( bool dbResults )
{
  dbResults_ = dbResults;
}

//-----------------------------------------------------------------
QString ResultDefinition::buildResultDefinitionStr( bool isSmith,
    ResultDefinition& definition )
{
  QString result;
  switch ( definition.type() )
    {
    case ResultDefinition::portParameters:
      switch ( definition.measurement() )
        {
        case ResultDefinition::sParameters:
          result = "S";
          break;

        case ResultDefinition::yParameters:
          result = "Y";
          break;

        case ResultDefinition::zParameters:
          result = "Z";
          break;

        case ResultDefinition::groupDelay:
          result = "GD";
          break;

        default:
          ASSERT( "Unhandled switch statement!" == 0 );
        }
      result += "[" + QString::number( definition.to() ) + ",";
      result += QString::number( definition.from() ) + "]";
      if ( (!isSmith) && (definition.measurement() != ResultDefinition::groupDelay) )
        {
          switch ( definition.format() )
            {
            case ResultDefinition::realFormat:
              result = "RE(" + result + ")";
              break;

            case ResultDefinition::imagFormat:
              result = "IM(" + result + ")";
              break;

            case ResultDefinition::magnitudeFormat:
              if ( definition.db() )
                {
                  result = "DB(" + result + ")";
                }
              else
                {
                  result = "MAG(" + result + ")";
                }
              break;

            case ResultDefinition::angleFormat:
              result = "ANG(" + result + ")";
              break;

            default:
              ASSERT( "Unhandled switch statement!" == 0 );
            }
        }
      break;

    case ResultDefinition::linvillStabilityFactor:
      result = "C";
      break;

    case ResultDefinition::sternStabilityFactor:
      result = "K";
      break;

    default:
      ASSERT( "Unhandled switch statement!" == 0 );
    }
  result = definition.source() + " " + result;
  return result;
}

//-----------------------------------------------------------------
ResultDefinition* ResultDefinition::findResultDefinitionById( long int id )
{
  ResultDefinition* item = 0;
  for ( item=resultDefinitions_->first(); item != 0; item=resultDefinitions_->next() )
    {
      if ( item->id() == id )
        {
          break;
        }
    }
  return item;
}

//-----------------------------------------------------------------
void ResultDefinition::writeToStream( QTextStream& stream )
{
  stream << "<OUTPUT TYPE=\"" << (uint) measurementType_ << "\" ";
  stream << "MEASUREMENT=\"" << (uint) measurement_ << "\" ";
  stream << "FORMAT=\"" << (uint) format_ << "\" ";
  stream << "DATASOURCE=\"" << dataSource_ << "\" ";
  stream << "FROM=\"" << (uint) fromPort_ << "\" ";
  stream << "TO=\"" << (uint) toPort_ << "\" ";
  stream << "DB=\"" << (uint) dbResults_ << "\" />" << endl;
}

//-----------------------------------------------------------------
bool ResultDefinition::readFromDOM( QDomElement& element )
{
  QString measurementStr = element.attribute( "MEASUREMENT" );
  QString datasourceStr = element.attribute( "DATASOURCE" );
  QString formatStr = element.attribute( "FORMAT" );
  QString fromStr = element.attribute( "FROM" );
  QString toStr = element.attribute( "TO" );
  QString typeStr = element.attribute( "TYPE" );
  QString dbStr = element.attribute( "DB" );

  measurementType_ = (ResultDefinition::MeasurementType) typeStr.toUInt();
  measurement_ = (ResultDefinition::Measurement) measurementStr.toUInt();
  format_ = (ResultDefinition::MeasurementFormat) formatStr.toUInt();
  dataSource_ = datasourceStr;
  fromPort_ = fromStr.toUInt();
  toPort_ = toStr.toUInt();
  dbResults_ = (bool) dbStr.toUInt();
  return TRUE;
}
