//-*-C++-*-
/*
**************************************************************************
                                 description
                             --------------------
    copyright            : (C) 2000-2001 by Andreas Zehender
    email                : zehender@kde.org
**************************************************************************

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


#ifndef PMLIGHT_H
#define PMLIGHT_H

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "pmnamedobject.h"
#include "pmvector.h"
#include "pmcolor.h"

class PMViewStructure;

/**
 * Class for povray light sources.
 */ 

class PMLight : public PMNamedObject
{
   typedef PMNamedObject Base;
public:
   enum PMLightType { PointLight=0, SpotLight=1, CylinderLight=2, ShadowlessLight=3 }; 
   /** Creates an empty PMLight */
   PMLight( );
   /** deletes the PMLight */
   virtual ~PMLight( );

   /** */
   virtual PMObject* newObject( ) const { return new PMLight( ); }
   /** */
   virtual QString className( ) const { return QString( "light" ); }
   /** */
   virtual QString description( ) const;
   /** */
   virtual PMObjectType type( ) const { return PMTLight; }
   /** */
   virtual bool isA( PMObjectType t ) const;

   /** */
   virtual bool canInsert( PMObjectType t, const PMObject* after,
                           const PMObjectList* objectsBetween = 0 ) const;
   /** */
   virtual int canInsert( const PMObjectList& list,
                          const PMObject* after ) const;
   /** */
   virtual int canInsert( const QValueList<PMObjectType>& list,
                          const PMObject* after ) const;
   /** */
   virtual void serialize( PMOutputDevice& dev ) const;
   /** */
   virtual void serialize( QDomElement& e, QDomDocument& doc ) const;
   /** */
   virtual void readAttributes( const PMXMLHelper& h );
   
   /** Returns a new @ref PMLightEdit */
   virtual PMDialogEditBase* editWidget( QWidget* parent ) const;
   /** Returns the name of the pixmap that is displayed in the tree view
    * and dialog view */
   virtual QString pixmap( ) const { return QString( "pmlight" ); }

   /** Returns the type */
   PMLightType lightType( ) const { return m_type; }
   /** Sets the type */
   void setLightType( PMLightType t );
   
   /** Returns the location */
   PMVector location( ) const { return m_location; }
   /** Sets the location */
   void setLocation( const PMVector& p );
   
   /** Returns the color */
   PMColor color( ) const { return m_color; }
   /** Sets the color */
   void setColor( const PMColor& c );

   /** Returns the radius for cylinder and spot lights */
   double radius( ) const { return m_radius; }
   /** Sets the radius for cylinder and spot lights */
   void setRadius( double r );
   
   /** Returns the falloff for cylinder and spot lights */
   double falloff( ) const { return m_falloff; }
   /** Sets the falloff for cylinder and spot lights */
   void setFalloff( double f );

   /** Returns the tightness for cylinder and spot lights */
   double tightness( ) const { return m_tightness; }
   /** Sets the tightness for cylinder and spot lights */
   void setTightness( double r );

   /** Returns the pointAt point for cylinder and spot lights */
   PMVector pointAt( ) const { return m_pointAt; }
   /** Sets the pointAt for cylinder and spot lights */
   void setPointAt( const PMVector& p );

   /** Returns true if the light is a area light */
   bool isAreaLight( ) const { return m_bAreaLight; }
   /** Sets the area light flag */
   void setAreaLight( bool yes );

   /** Returns the axis1 for area lights */
   PMVector axis1( ) const { return m_areaAxis1; }
   /** Sets the axis1 for area lights */
   void setAxis1( const PMVector& v );

   /** Returns the axis2 for area lights */
   PMVector axis2( ) const { return m_areaAxis2; }
   /** Sets the axis2 for area lights */
   void setAxis2( const PMVector& v );

   /** Returns the size1 for area lights */
   int size1( ) const { return m_areaSize1; }
   /** Sets the size1 for area lights */
   void setSize1( int s );

   /** Returns the size2 for area lights */
   int size2( ) const { return m_areaSize2; }
   /** Sets the size2 for area lights */
   void setSize2( int s );

   /** Returns the adaptive parameter for area lights */
   int adaptive( ) const { return m_adaptive; }
   /** Sets the adaptive parameter for area lights */
   void setAdaptive( int s );

   /** Returns the jitter parameter for area lights */
   bool jitter( ) const { return m_jitter; }
   /** Sets the jitter parameter for area lights */
   void setJitter( bool j );

   /** Returns true if light fading is enabled */
   bool fading( ) const { return m_bFading; }
   /** Enables/Disables light fading */
   void setFading( bool yes );

   /** Returns the fading distance */
   double fadeDistance( ) const { return m_fadeDistance; }
   /** Sets the fading distance */
   void setFadeDistance( double d );

   /** Returns the fading power */
   int fadePower( ) const { return m_fadePower; }
   /** Sets the fading power */
   void setFadePower( int p );

   /** Returns the media interaction flag */
   bool mediaInteraction( ) const { return m_bMediaInteraction; }
   /** Sets the media interaction flag */
   void setMediaInteraction( bool yes );

   /** Returns the media attenuation flag */
   bool mediaAttenuation( ) const { return m_bMediaAttenuation; }
   /** Sets the media attenuation flag */
   void setMediaAttenuation( bool yes );

   /** */
   virtual void restoreMemento( PMMemento* s );
   /** */
   virtual void controlPoints( PMControlPointList& list );
   /** */
   virtual void controlPointsChanged( PMControlPointList& list );
   /** */
   virtual void cleanUp( ) const;
   
protected:
   /** */
   virtual bool isDefault( ) { return false; }
   /** */
   virtual void createViewStructure( );
   /** */
   virtual PMViewStructure* defaultViewStructure( ) const { return 0; }
   
private:
   /** Creates and returns the default view structure for point lights */
   PMViewStructure* defaultPointStructure( ) const;
   /** Creates and returns the default view structure for spot lights */
   PMViewStructure* defaultSpotStructure( ) const;
   /** Creates and returns the default view structure for cylindrical lights */
   PMViewStructure* defaultCylindricalStructure( ) const;
   bool containsLooksLike( ) const;
   
   /** IDs for @ref PMMementoData */
   enum PMLightMementoID
   { PMLocationID, PMColorID, PMRadiusID, PMFalloffID, PMTightnessID,
     PMPointAtID, PMAreaLightID, PMAreaAxis1ID, PMAreaAxis2ID,
     PMAreaSize1ID, PMAreaSize2ID, PMAdaptiveID, PMJitterID, PMTypeID,
     PMFadingID, PMFadeDistanceID, PMFadePowerID, PMInteractionID,
     PMAttenuationID };

   PMLightType m_type;
   PMVector m_location;
   PMColor m_color;
   double m_radius;
   double m_falloff;
   double m_tightness;
   PMVector m_pointAt;
   bool m_bAreaLight;
   PMVector m_areaAxis1, m_areaAxis2;
   int m_areaSize1, m_areaSize2;
   int m_adaptive;
   bool m_jitter;
   bool m_bFading;
   double m_fadeDistance;
   int m_fadePower;
   bool m_bMediaInteraction;
   bool m_bMediaAttenuation;
   
   /** The default view structure for point lights */
   static PMViewStructure* s_pDefaultPointStructure;
   /** The default view structure for spot lights */
   static PMViewStructure* s_pDefaultSpotStructure;
   /** The default view structure for cylindrical lights */
   static PMViewStructure* s_pDefaultCylindricalStructure;
   
   /** The size of the point light for 3d views */
   static double s_pointLightSize;
   /** Number of lines around the cylinder */
   static int s_nCylinderLines;
   /** Number of lines around the spot */
   static int s_nSpotLines;
   /** Length of the spot and cylinder */
   static double s_length;
};

#endif
