/*
**************************************************************************
                                 description
                             --------------------
    copyright            : (C) 2001 by Luis Carvalho
    email                : lpassos@mail.telepac.pt
**************************************************************************

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


#include "pmmedia.h"
#include "pmoutputdevice.h"
#include "pmxmlhelper.h"
#include "pmmemento.h"
#include "pmmediaedit.h"
#include "pmcolor.h"

#include <kdebug.h>
#include "pmglobals.h"
#include <klocale.h>

bool PMMedia::s_linkPossibilitiesCreated = false;
QValueList<PMDeclare::PMDeclareType> PMMedia::s_linkPossibilities;

const int intervalsDefault = 10;
const int samplesMinDefault = 1;
const int samplesMaxDefault = 1;
const double confidenceDefault = 0.9;
const double varianceDefault = 0.0078125;
const double ratioDefault = 0.9;
const PMColor absorptionDefault = PMColor( 0.0, 0.0, 0.0 );
const PMColor emissionDefault = PMColor( 0.0, 0.0, 0.0 );
const int scatteringTypeDefault = 0;
const PMColor scatteringColorDefault = PMColor( 0.0, 0.0, 0.0 );
const double scatteringEccentricityDefault = 0;
const double scatteringExtinctionDefault = 1.0;

PMMedia::PMMedia( )
      : Base( )
{
   m_intervals = intervalsDefault;
   m_samplesMin = samplesMinDefault;
   m_samplesMax = samplesMaxDefault;
   m_confidence = confidenceDefault;
   m_variance = varianceDefault;
   m_ratio = ratioDefault;
   m_absorption = absorptionDefault;
   m_emission = emissionDefault;
   m_scatteringType = scatteringTypeDefault;
   m_scatteringColor = scatteringColorDefault;
   m_scatteringEccentricity = scatteringEccentricityDefault;
   m_scatteringExtinction = scatteringExtinctionDefault;
   m_enableIntervals = false;
   m_enableSamples = false;
   m_enableConfidence = false;
   m_enableVariance = false;
   m_enableRatio = false;
   m_enableAbsorption = false;
   m_enableEmission = false;
   m_enableScattering = false;
}

PMMedia::~PMMedia( )
{
}

bool PMMedia::isA( PMObjectType t ) const
{
   if( t == PMTMedia )
      return true;
   return Base::isA( t );
}

QString PMMedia::description( ) const
{
   return i18n( "media" );
}

bool PMMedia::canInsert( PMObjectType t, const PMObject*,
                         const PMObjectList* ) const
{
   return ( t == PMTComment || t == PMTDensity || t == PMTRaw );
}
   

void PMMedia::serialize( PMOutputDevice& dev ) const
{
   QString str1;
   QString str2;

   dev.objectBegin( "media" );
   Base::serialize( dev );
   if( m_enableIntervals )
   {
      str1.setNum( m_intervals );
      dev.writeLine( "intervals " + str1 );
   }
   if( m_enableSamples )
   {
      str1.setNum( m_samplesMin );
      str2.setNum( m_samplesMax );
      dev.writeLine( "samples " + str1 + "," + str2 );
   }
   if( m_enableConfidence )
   {
      str1.setNum( m_confidence );
      dev.writeLine( "confidence " + str1 );
   }
   if( m_enableVariance )
   {
      str1.setNum( m_variance );
      dev.writeLine( "variance " + str1 );
   }
   if( m_enableRatio )
   {
      str1.setNum( m_ratio );
      dev.writeLine( "ratio " + str1 );
   }
   if( m_enableAbsorption )
   {
      dev.writeLine( "absorption " + m_absorption.serialize( ) );
   }
   if( m_enableEmission )
   {
      dev.writeLine( "emission " + m_emission.serialize( ) );
   }
   if( m_enableScattering )
   {
      dev.objectBegin( "scattering" );
      str1.setNum( m_scatteringType );
      dev.writeLine( str1 + ", " + m_scatteringColor.serialize( ) );
      if( m_scatteringType == 5 && m_scatteringEccentricity != scatteringEccentricityDefault )
      {
         str1.setNum( m_scatteringEccentricity );
         dev.writeLine( "eccentricity " + str1 );
      }
      if( m_scatteringExtinction != scatteringExtinctionDefault )
      {
         str1.setNum( m_scatteringExtinction );
         dev.writeLine( "extinction " + str1 );
      }
      dev.objectEnd( );
   }
   dev.objectEnd( );
}

void PMMedia::serialize( QDomElement& e, QDomDocument& doc ) const
{
   Base::serialize( e, doc );
   e.setAttribute( "enable_intervals", m_enableIntervals );
   e.setAttribute( "enable_samples", m_enableSamples );
   e.setAttribute( "enable_confidence", m_enableConfidence );
   e.setAttribute( "enable_variance", m_enableVariance );
   e.setAttribute( "enable_ratio", m_enableRatio );
   e.setAttribute( "enable_absorption", m_enableAbsorption );
   e.setAttribute( "enable_emission", m_enableEmission );
   e.setAttribute( "enable_scattering", m_enableScattering );
   e.setAttribute( "intervals", m_intervals );
   e.setAttribute( "samples_min", m_samplesMin );
   e.setAttribute( "samples_max", m_samplesMax );
   e.setAttribute( "confidence", m_confidence );
   e.setAttribute( "variance", m_variance );
   e.setAttribute( "ratio", m_ratio );
   e.setAttribute( "absorption", m_absorption.serializeXML( ) );
   e.setAttribute( "emission", m_emission.serializeXML( ) );
   e.setAttribute( "scattering_type", m_scatteringType );
   e.setAttribute( "scattering_color", m_scatteringColor.serializeXML( ) );
   e.setAttribute( "scattering_eccentricity", m_scatteringEccentricity );
   e.setAttribute( "scattering_extinction", m_scatteringExtinction );
}
 
void PMMedia::readAttributes( const PMXMLHelper& h )
{
   Base::readAttributes( h );
   m_enableIntervals = h.boolAttribute( "enable_intervals", false );
   m_enableSamples = h.boolAttribute( "enable_samples", false );
   m_enableConfidence = h.boolAttribute( "enable_confidence", false );
   m_enableVariance = h.boolAttribute( "enable_variance", false );
   m_enableRatio = h.boolAttribute( "enable_ratio", false );
   m_enableAbsorption = h.boolAttribute( "enable_absorption", false );
   m_enableEmission = h.boolAttribute( "enable_emission", false );
   m_enableScattering = h.boolAttribute( "enable_scattering", false );
   m_intervals = h.intAttribute( "intervals", intervalsDefault );
   m_samplesMin = h.intAttribute( "samples_min", samplesMinDefault );
   m_samplesMax = h.intAttribute( "samples_max", samplesMaxDefault );
   m_confidence = h.doubleAttribute( "confidence", confidenceDefault );
   m_variance = h.doubleAttribute( "variance", varianceDefault );
   m_ratio = h.doubleAttribute( "ratio", ratioDefault );
   m_absorption = h.colorAttribute( "absorption", absorptionDefault );
   m_emission = h.colorAttribute( "emission", emissionDefault );
   m_scatteringType = h.intAttribute( "scattering_type", scatteringTypeDefault );
   m_scatteringColor = h.colorAttribute( "scattering_color", scatteringColorDefault );
   m_scatteringEccentricity = h.doubleAttribute( "scattering_eccentricity", 
                                                       scatteringEccentricityDefault );
   m_scatteringExtinction = h.doubleAttribute( "scattering_extinction", 
                                                       scatteringExtinctionDefault );
}

QValueList<PMDeclare::PMDeclareType> PMMedia::linkPossibilities( ) const
{
   if( !s_linkPossibilitiesCreated )
   {
      s_linkPossibilities.append( PMDeclare::MediaDeclare );
      s_linkPossibilitiesCreated = true;
   }
   return s_linkPossibilities;
}

void PMMedia::setIntervals( int c )
{
   if( c != m_intervals )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMIntervalsID, m_intervals );
      m_intervals = c;
   }
}
 
void PMMedia::setSamplesMin( int c )
{
   if( c != m_samplesMin )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMSamplesMinID, m_samplesMin );
      m_samplesMin = c;
   }
}
 
void PMMedia::setSamplesMax( int c )
{
   if( c != m_samplesMax )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMSamplesMaxID, m_samplesMax );
      m_samplesMax = c;
   }
}
 
void PMMedia::setConfidence( double c )
{
   if( c != m_confidence )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMConfidenceID, m_confidence );
      m_confidence = c;
   }
}
 
void PMMedia::setVariance( double c )
{
   if( c != m_variance )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMVarianceID, m_variance );
      m_variance = c;
   }
}
 
void PMMedia::setRatio( double c )
{
   if( c != m_ratio )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMRatioID, m_ratio );
      m_ratio = c;
   }
}
 
void PMMedia::setAbsorption( const PMColor& c )
{
   if( c != m_absorption )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMAbsorptionID, m_absorption );
      m_absorption = c;
   }
}
 
void PMMedia::setEmission( const PMColor& c )
{
   if( c != m_emission )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMEmissionID, m_emission );
      m_emission = c;
   }
}
 
void PMMedia::setScatteringType( int c )
{
   if( c != m_scatteringType )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMScatteringTypeID, m_scatteringType );
      m_scatteringType = c;
   }
}
 
void PMMedia::setScatteringColor( const PMColor& c )
{
   if( c != m_scatteringColor )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMScatteringColorID, m_scatteringColor );
      m_scatteringColor = c;
   }
}
 
void PMMedia::setScatteringEccentricity( double c )
{
   if( c != m_scatteringEccentricity )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMScatteringEccentricityID, m_scatteringEccentricity );
      m_scatteringEccentricity = c;
   }
}
 
void PMMedia::setScatteringExtinction( double c )
{
   if( c != m_scatteringExtinction )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMScatteringExtinctionID, m_scatteringExtinction );
      m_scatteringExtinction = c;
   }
}
 
void PMMedia::enableIntervals( bool c )
{
   if( c != m_enableIntervals )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMEnableIntervalsID, m_enableIntervals );
      m_enableIntervals = c;
   }
}
 
void PMMedia::enableSamples( bool c )
{
   if( c != m_enableSamples )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMEnableSamplesID, m_enableSamples );
      m_enableSamples = c;
   }
}
 
void PMMedia::enableConfidence( bool c )
{
   if( c != m_enableConfidence )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMEnableConfidenceID, m_enableConfidence );
      m_enableConfidence = c;
   }
}

void PMMedia::enableVariance( bool c )
{
   if( c != m_enableVariance )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMEnableVarianceID, m_enableVariance );
      m_enableVariance = c;
   }
}

void PMMedia::enableRatio( bool c )
{
   if( c != m_enableRatio )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMEnableRatioID, m_enableRatio );
      m_enableRatio = c;
   }
}

void PMMedia::enableAbsorption( bool c )
{
   if( c != m_enableAbsorption )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMEnableAbsorptionID, m_enableAbsorption );
      m_enableAbsorption = c;
   }
}

void PMMedia::enableEmission( bool c )
{
   if( c != m_enableEmission )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMEnableEmissionID, m_enableEmission );
      m_enableEmission = c;
   }
}

void PMMedia::enableScattering( bool c )
{
   if( c != m_enableScattering )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTMedia, PMEnableScatteringID, m_enableScattering );
      m_enableScattering = c;
   }
}

PMDialogEditBase* PMMedia::editWidget( QWidget* parent ) const
{
   return new PMMediaEdit( parent );
}

void PMMedia::restoreMemento( PMMemento* s )
{
   PMMementoDataIterator it( s );
   PMMementoData* data;
 
   for( ; it.current( ); ++it )
   {
      data = it.current( );
      if( data->objectType( ) == PMTMedia )
      {
         switch( data->valueID( ) )
         {
            case PMEnableIntervalsID:
               enableIntervals( data->boolData( ) );
               break;
            case PMEnableSamplesID:
               enableSamples( data->boolData( ) );
               break;
            case PMEnableConfidenceID:
               enableConfidence( data->boolData( ) );
               break;
            case PMEnableVarianceID:
               enableVariance( data->boolData( ) );
               break;
            case PMEnableRatioID:
               enableRatio( data->boolData( ) );
               break;
            case PMEnableAbsorptionID:
               enableAbsorption( data->boolData( ) );
               break;
            case PMEnableEmissionID:
               enableEmission( data->boolData( ) );
               break;
            case PMEnableScatteringID:
               enableScattering( data->boolData( ) );
               break;
            case PMIntervalsID:
               setIntervals( data->intData( ) );
               break;
            case PMSamplesMinID:
               setSamplesMin( data->intData( ) );
               break;
            case PMSamplesMaxID:
               setSamplesMax( data->intData( ) );
               break;
            case PMConfidenceID:
               setConfidence( data->doubleData( ) );
               break;
            case PMVarianceID:
               setVariance( data->doubleData( ) );
               break;
            case PMRatioID:
               setRatio( data->doubleData( ) );
               break;
            case PMAbsorptionID:
               setAbsorption( data->colorData( ) );
               break;
            case PMEmissionID:
               setEmission( data->colorData( ) );
               break;
            case PMScatteringTypeID:
               setScatteringType( data->intData( ) );
               break;
            case PMScatteringColorID:
               setScatteringColor( data->colorData( ) );
               break;
            case PMScatteringEccentricityID:
               setScatteringEccentricity( data->doubleData( ) );
               break;
            case PMScatteringExtinctionID:
               setScatteringExtinction( data->doubleData( ) );
               break;
            default:
               kdError( PMArea ) << "Wrong ID in PMMedia::restoreMemento\n";
               break;
         }
      }
   }
   Base::restoreMemento( s );
}
