/*
**************************************************************************
                                 description
                             --------------------
    copyright            : (C) 2002 by Luis Passos 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 "pmbumpmapedit.h"
#include "pmbumpmap.h"
#include "pmpalettevalue.h"
#include "pmpalettevaluememento.h"

#include "pmoutputdevice.h"
#include "pmxmlhelper.h"
#include "pmcompositeobject.h"
#include "pmmemento.h"

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

#include <klocale.h>

const PMBumpMap::PMBitmapType bitmapTypeDefault = PMBumpMap::BitmapSys;
const char *const bitmapFileDefault = 0;
const bool enableFilterAllDefault = false;
const bool enableTransmitAllDefault = false;
const double filterAllDefault = 0.0;
const double transmitAllDefault = 0.0;
const bool onceDefault = false;
const PMBumpMap::PMMapType mapTypeDefault = PMBumpMap::MapPlanar;
const PMBumpMap::PMInterpolateType interpolateTypeDefault = PMBumpMap::InterpolateNone;
const bool useIndexDefault = false;
const double bumpSizeDefault = 0.0;

PMBumpMap::PMBumpMap( )
      : Base( )
{
   m_bitmapType = bitmapTypeDefault;
   m_bitmapFile = bitmapFileDefault;
   m_once = onceDefault;
   m_mapType = mapTypeDefault;
   m_interpolateType = interpolateTypeDefault;
   m_useIndex = useIndexDefault;
   m_bumpSize = bumpSizeDefault;
}


PMBumpMap::~PMBumpMap( )
{
}

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

   dev.objectBegin( "bump_map" );

   switch( m_bitmapType )
   {
      case PMBumpMap::BitmapGif:
         dev.writeLine( "gif" );
         break;
      case PMBumpMap::BitmapTga:
         dev.writeLine( "tga" );
         break;
      case PMBumpMap::BitmapIff:
         dev.writeLine( "iff" );
         break;
      case PMBumpMap::BitmapPpm:
         dev.writeLine( "ppm" );
         break;
      case PMBumpMap::BitmapPgm:
         dev.writeLine( "pgm" );
         break;
      case PMBumpMap::BitmapPng:
         dev.writeLine( "png" );
         break;
      case PMBumpMap::BitmapJpeg:
         dev.writeLine( "jpeg" );
         break;
      case PMBumpMap::BitmapTiff:
         dev.writeLine( "tiff" );
         break;
      case PMBumpMap::BitmapSys:
         dev.writeLine( "sys" );
         break;
   }

   dev.writeLine( "\"" + m_bitmapFile + "\"" );

   if( m_once )
      dev.writeLine( "once" );

   switch( m_mapType )
   {
      case PMBumpMap::MapPlanar:
         dev.writeLine( "map_type 0" );
         break;
      case PMBumpMap::MapSpherical:
         dev.writeLine( "map_type 1" );
         break;
      case PMBumpMap::MapCylindrical:
         dev.writeLine( "map_type 2" );
         break;
      case PMBumpMap::MapToroidal:
         dev.writeLine( "map_type 5" );
         break;
   }
   switch( m_interpolateType )
   { 
      case PMBumpMap::InterpolateBilinear:
         dev.writeLine( "interpolate 2" );
	 break;
      case PMBumpMap::InterpolateNormalized:
         dev.writeLine( "interpolate 4" );
	 break;
      default:
         break;
   }

   if( m_useIndex )
      dev.writeLine( "use_index" );

   if( m_bumpSize )
   {
      str1.setNum( m_bumpSize );
      dev.writeLine( "bump_size " + str1 );
   }

   dev.objectEnd( );
}

void PMBumpMap::serialize( QDomElement& e, QDomDocument& doc ) const
{
   switch( m_bitmapType )
   {
      case BitmapGif:
         e.setAttribute( "bitmap_type", "gif" );
         break;
      case BitmapTga:
         e.setAttribute( "bitmap_type", "tga" );
         break;
      case BitmapIff:
         e.setAttribute( "bitmap_type", "iff" );
         break;
      case BitmapPpm:
         e.setAttribute( "bitmap_type", "ppm" );
         break;
      case BitmapPgm:
         e.setAttribute( "bitmap_type", "pgm" );
         break;
      case BitmapPng:
         e.setAttribute( "bitmap_type", "png" );
         break;
      case BitmapJpeg:
         e.setAttribute( "bitmap_type", "jpeg" );
         break;
      case BitmapTiff:
         e.setAttribute( "bitmap_type", "tiff" );
         break;
      case BitmapSys:
         e.setAttribute( "bitmap_type", "sys" );
         break;
   }
   e.setAttribute( "file_name", m_bitmapFile );
   e.setAttribute( "once", m_once );
   switch( m_mapType )
   {
      case MapPlanar:
         e.setAttribute( "map_type", "planar" );
         break;
      case MapSpherical:
         e.setAttribute( "map_type", "spherical" );
         break;
      case MapCylindrical:
         e.setAttribute( "map_type", "cylindrical" );
         break;
      case MapToroidal:
         e.setAttribute( "map_type", "toroidal" );
         break;
   }
   switch( m_interpolateType )
   {
      case InterpolateNone:
         e.setAttribute( "interpolate", "none" );
         break;
      case InterpolateBilinear:
         e.setAttribute( "interpolate", "bilinear" );
         break;
      case InterpolateNormalized:
         e.setAttribute( "interpolate", "normalized" );
         break;
   }
   e.setAttribute( "use_index", m_useIndex );
   e.setAttribute( "bump_size", m_bumpSize );

   Base::serialize( e, doc );
}

void PMBumpMap::readAttributes( const PMXMLHelper& h )
{
   QString str;

   str = h.stringAttribute( "bitmap_type", "sys" );
   if( str == "gif" )
      m_bitmapType = BitmapGif;
   else if( str == "tga" )
      m_bitmapType = BitmapTga;
   else if( str == "iff" )
      m_bitmapType = BitmapIff;
   else if( str == "ppm" )
      m_bitmapType = BitmapPpm;
   else if( str == "pgm" )
      m_bitmapType = BitmapPgm;
   else if( str == "png" )
      m_bitmapType = BitmapPng;
   else if( str == "jpeg" )
      m_bitmapType = BitmapJpeg;
   else if( str == "tiff" )
      m_bitmapType = BitmapTiff;
   else if( str == "sys" )
      m_bitmapType = BitmapSys;

   m_bitmapFile = h.stringAttribute( "file_name", bitmapFileDefault );
   m_once = h.boolAttribute( "once", onceDefault );

   str = h.stringAttribute( "map_type", "planar" );
   if( str == "planar" )
      m_mapType = MapPlanar;
   else if( str == "spherical" )
      m_mapType = MapSpherical;
   else if( str == "cylindrical" )
      m_mapType = MapCylindrical;
   else if( str == "toroidal" )
      m_mapType = MapToroidal;

   str = h.stringAttribute( "interpolate", "none" );
   if( str == "none" )
      m_interpolateType = InterpolateNone;
   else if( str == "bilinear" )
      m_interpolateType = InterpolateBilinear;
   else if( str == "normalized" )
      m_interpolateType = InterpolateNormalized;

   m_useIndex = h.boolAttribute( "use_index", useIndexDefault );
   m_bumpSize = h.doubleAttribute( "bump_size", bumpSizeDefault );

   Base::readAttributes( h );
}

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

QString PMBumpMap::description( ) const
{
   return i18n( "bump map" );
}

void PMBumpMap::setBitmapType( PMBitmapType c )
{
   if( c != m_bitmapType )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTBumpMap, PMBitmapTypeID, m_bitmapType );
      m_bitmapType = c;
   } 
}

void PMBumpMap::setBitmapFileName( const QString& c )
{
   if( c != m_bitmapFile )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTBumpMap, PMBitmapFileID, m_bitmapFile );
      m_bitmapFile = c;
   } 
}

void PMBumpMap::enableUseIndex( bool c )
{
   if( c != m_useIndex )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTBumpMap, PMUseIndexID, m_useIndex );
      m_useIndex = c;
   } 
}

void PMBumpMap::setMapType( PMMapType c )
{
   if( c != m_mapType )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTBumpMap, PMMapTypeID, m_mapType );
      m_mapType = c;
   }
}

void PMBumpMap::setInterpolateType( PMInterpolateType c )
{
   if( c != m_interpolateType )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTBumpMap, PMInterpolateID, m_interpolateType );
      m_interpolateType = c;
   }
}

void PMBumpMap::enableOnce( bool c )
{
   if( c != m_once )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTBumpMap, PMOnceID, m_once );
      m_once = c;
   } 
}

void PMBumpMap::setBumpSize( double c )
{
   if( c != m_bumpSize )
   {
      if( m_pMemento )
         m_pMemento->addData( PMTBumpMap, PMBumpSizeID, m_bumpSize );
      m_bumpSize = c;
   } 
}

PMDialogEditBase* PMBumpMap::editWidget( QWidget* parent ) const
{
   return new PMBumpMapEdit( parent );
}

void PMBumpMap::restoreMemento( PMMemento* s )
{
   PMMementoDataIterator it( s );
   PMMementoData* data;

   for( ; it.current( ); ++it )
   {
      data = it.current( );
      if( data->objectType( ) == PMTBumpMap )
      {
         switch( data->valueID( ) )
         {
            case PMBitmapTypeID:
               setBitmapType( ( PMBitmapType )data->intData( ) );
               break;
            case PMBitmapFileID:
               setBitmapFileName( data->stringData( ) );
               break;
            case PMOnceID:
               enableOnce( data->boolData( ) );
               break;
            case PMMapTypeID:
               setMapType( ( PMMapType )data->intData( ) );
               break;
            case PMInterpolateID:
               setInterpolateType( ( PMInterpolateType )data->intData( ) );
               break;
            case PMUseIndexID:
               enableUseIndex( data->boolData( ) );
               break;
            case PMBumpSizeID:
               setBumpSize( data->doubleData( ) );
               break;
            default:
               kdError( PMArea ) << "Wrong ID in PMBumpMap::restoreMemento\n";
               break;
         }
      }
   }
   Base::restoreMemento( s );
}
