//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.

// -*-c++-*-

#ifndef OSG_IMAGE
#define OSG_IMAGE 1

#include <osg/Object>

#include <string>

namespace osg {

/** Image class for encapsulating the storage texture image data.*/
class SG_EXPORT Image : public Object
{

    public :

        Image();
        
        /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
        Image(const Image& image,const CopyOp& copyop=CopyOp::SHALLOW_COPY);

        virtual Object* cloneType() const { return new Image(); }
        virtual Object* clone(const CopyOp& copyop) const { return new Image(*this,copyop); }
        virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Image*>(obj)!=0; }
        virtual const char* className() const { return "Image"; }


        inline const std::string& getFileName() const { return _fileName; }
        void setFileName(const std::string& fileName);
        
        /** set the image data and format.
          * note, when the packing value is negative (the default is -1) this method assumes
          * a _packing width of 1 if the width is not a multiple of 4,
          * otherwise automatically sets to _packing to 4. If a positive
          * value of packing is supplied than _packing is simply set to that value.
          */
        void setImage(const int s,const int t,const int r,
            const int internalFormat,
            const unsigned int pixelFormat,
            const unsigned int dataType,
            unsigned char *data,
            const int packing=-1);

        /** Width of image.*/
        inline const int s() const { return _s; }
        /** Height of image.*/
        inline const int t() const { return _t; }
        /** Depth of image.*/
        inline const int r() const { return _r; }
        
        inline const int internalFormat() const { return _internalFormat; }
        inline const unsigned int pixelFormat() const { return _pixelFormat; }
        inline const unsigned int dataType() const { return _dataType; }
        inline const unsigned int packing() const { return _packing; }
        
        /** raw image data.*/
        inline unsigned char *data() { return _data; }
        
        /** raw const image data.*/
        inline const unsigned char *data() const { return _data; }

        /** Scale image to specified size. */
        void scaleImage(const int s,const int t,const int r);

        /** Ensure image dimensions are a power of two.
          * Mip Mapped texture require the image dimensions to be
          * power of two.
          */
        void ensureDimensionsArePowerOfTwo();
      
        /** Dirty the image, which increments the modified flag, to force osg::Texture to reload the image.*/
        inline void dirty() { ++_modifiedTag; }      
      
        /** Set the modified tag value, only used by osg::Texture when using texture subloading. */
        inline void setModifiedTag(const unsigned int value) { _modifiedTag=value; }

        /** Get modified tag value, only used by osg::Texture when using texture subloading. */
        inline const unsigned int getModifiedTag() const { return _modifiedTag; }

    protected :

        virtual ~Image();

        Image& operator = (const Image&) { return *this; }

        std::string _fileName;
        int _s, _t, _r;
        int _internalFormat;
        unsigned int _pixelFormat;
        unsigned int _dataType;
        unsigned int _packing;
        unsigned char *_data;

        unsigned int _modifiedTag;
};

class Geode;

/** Convenience function to be used by images loaders to generate a valid geode
 * to return for readNode().  
 * Use the images s and t values scale the dimensions of the image.
 */
SG_EXPORT extern Geode* createGeodeForImage(Image* image);
/** Convenience function to be used by images loaders to generate a valid geode
 * to return for readNode().  
 * Use the specified s and t values scale the dimensions of the image.
 */
SG_EXPORT extern Geode* createGeodeForImage(Image* image,const float s,const float t);

}

#endif                                            // __SG_IMAGE_H
