/**
 * This file describes the modeling object for IGImage geometry in 2-D graphics.
 * Class described here is IImage.
 *
 *   IBM Open Class Library
 *   (C) Copyright International Business Machines Corporation,  1997
 *   Licensed Material - Program-Property of IBM - All Rights Reserved.
 *
 */

// Revision: 96 1.39.1.8 source/albert/graph2d/iimage.hpp, 2d, ioc.v400, 980918 

#ifndef _IIMAGE_
#define _IIMAGE_

#include <i2dghand.hpp>                  // IPointerHandle, IBitmapHandle
#include <igraph2d.hpp>
#include <igimage.hpp>

#if __IBMCPP__ >= 400
#pragma namemangling(compat)
#endif

class IGPoint2D;
class IGPolygon2D;
class IGrafBundle;
class IGrafDevice;
class IGRect2D;
class IGrafMatrix;
class IGrafPort;
class IBaseRootGrafPort;

class IString;

#pragma pack(push,4)
#pragma enum(4)

/**
 * IImage is a wrapper for the IGImage geometry class.
 * IImage is a wrapper for the IGImage geometry class. IImages have an IGImage,
 * and a matrix. You can draw and transform images, as you can for all
 * IMGraphics. You can also get and set the bundle.
 * There are three spaces associated with the image:
 * 	Modeling Space:
 *		the space outside the IImage. Most operations are in modeling space.
 * 	Image Space or World Space:
 *		the space outside the IGImage. To go from Modeling Space
 *		to World Space, call matrix, and transform the modeling space point into a world
 *		space point. To go from World Space to Modeling Space call matrix, and untransform
 *		the world space point into a modeling space point.
 *	Pixel Space:
 *		the space outside the IGImage where incrementing by 1 moves to the next
 *		pixel. To go from World Space to Pixel Space call TransformPointsIntoPixelCoords.
 *		To go from Pixel Space to World Space call UnTransformPointsFromPixelCoords.
 *	To transform from Modeling Space to Pixel Space, call:
 *		worldPoint = image.matrix()->transformPoint(modelingPoint);
 *		worldPointArray[0] = worldPoint;
 *		image.TransformPointsIntoPixelCoords(worldPointArray, pixelPointArray);
 */

class IImage: public IMGraphic
{
	StreamableDeclarationsMacro(IImage);
  protected :
	virtual void writeToStream(IDataStream& toWhere) const;
	virtual void readFromStream(IDataStream& toWhere);

  public:
    /**
     */
    IImage ();

	/**
	 */
	IImage(const IImage&);

	/**
   * Note: On OS/2 platform, please specifically use long values for the first two parameters.
   * (e.g. IImage(64L, 64L, IGImage::kTrueColor24Bit). Otherwise, a compilation error might occur if
   * the first two parameters are used literally as IImage(64, 64, IGImage::kTrueColor24Bit).
	 */
	IImage(long width, long height, IGImage::EImageType imageType,
		ICoordinateSystem::EOrientation orientation=
			ICoordinateSystem::applicationOrientation(),
		IColorMap* colmap = &(IColorMap::defaultColorMap()));

#if (IC_OBSOLETE <= IC_OBSOLETE_3)

	IImage(IPresSpaceHandle psh, int nWidth, int nHeight);

#endif // (IC_OBSOLETE <= IC_OBSOLETE_3)

	/**
	 */
	IImage(const IBitmapHandle& bitmapHandle);

	/**
	 */
	IImage(const IImage& bitmap, const IGRect2D& rectangle);

	/**
	 */
	IImage(const IGImage& );

	virtual ~IImage();

	/**
	 * Returns the image geometry for which this class is a wrapper. The returned image geometry is uneditable.
	 */
	const IGImage* image() const;

	/**
	 * Calculates and returns the image's bounding rectangle, not including any area determined by the attribute bundle.
	 */
	virtual IGRect2D geometricBounds() const;

	/**
	 * Calculates and returns the bounding rectangle of the source image for the image object (in pixel space).
	 */
	IGRect2D sourceBounds()const;

	/**
	 * Returns the IGrafPort used to render this image.
	 * IImage does not ensure multitask safety, so you can only obtain one grafport.
	 * Use the grafport to render into the image.
	 */
	IGrafPort* grafPort();

	/**
	 * Draws the graphic to the specified IGrafPort.
	 */
	virtual void draw(IGrafPort& port) const;

	/**
	 * Draws the portion of the image that lies within the specified rectangle to the specified IGrafPort.
	 */
	void drawPartial(IGrafPort& port, const IGRect2D& areaOfInterestInSource) const;

  	/**
  	 * Adopts the specified attribute bundle to determine the graphic's attributes.
  	 */
	virtual void adoptAttributeState(IAttributeState* adoptedAttributeState);

	/**
  	 * Relinquishes knowledge of, and responsibility for, the IImage's attribute bundle, returning it to the caller.
  	 */
	virtual IAttributeState* orphanAttributeState();

  	/**
  	 * Gets the attribute bundle, keeping it available to the IImage.
  	 */
	virtual const IAttributeState* attributeState() const;

	/**
	 * Assigment operator.
	 */
	IImage& operator=(const IImage& source);

	/**
	 * Tests two IImage objects for equality.
	 */
	virtual bool operator==(const IMDrawable&) const;

	/**
	 * Transforms the image's shape and position by applying the specified transformation matrix.
	 */
	virtual void transformBy(const IGrafMatrix&);

	/**
	 * Reflects the image horizontally.
	 */
	IImage& reflectHorizontally();

	/**
	 * Reflects the image vertically.
	 */
	IImage& reflectVertically();

	/**
	 * Rotates the image by 180 degrees.
	 */
	IImage& rotateBy180();

	/**
	 * Rotates the image by 270 degrees.
	 */
	IImage& rotateBy270();

	/**
	 * Rotates the image by 90 degrees.
	 */
	IImage& rotateBy90();

	/**
	 * Transposes the image.
	 */
	IImage& transposeXForY();
			
	/**
	 * Checks if the IImage has a color transparent mask.
	 */
	bool  hasTransparentColor() const;
			
	/**
	 * Resets the transparent mask.
	 */
	IImage& resetTransparentColor();
			
	/**
	 * Sets the transparent mask and the flag after deleting the old one.
	 */
	IImage& setTransparentColor(const IBaseColor& aColor);

	/**
	 * Returns the transparent color.
	 */
	IBaseColor transparentColor() const;

#if (IC_OBSOLETE <= IC_OBSOLETE_3)

    /**
     * To be obsoleted. Use IGImagePixelAccessor::EImageFormat instead.
     */	
     enum EImageFormat {
  			kBitmap,
  			kGIF,
  			kPCX,
  			kTIFF,
  			kTarga,
  			kAmiga,
  			kXBM,
  			kPSEG,
		    kUnknownFormat = -1
  		};


  /**
   * To be obsoleted. Use IGImagePixelAccessor::EDitherType instead.
   */	
   enum EDitherType {
		kNoDither,
		kErrorDither,
		kHalftoneDither
	};

	/**
   * To be obsoleted. Use IGImagePixelAccessor class.
   */
	IImage(
		const IString& imageFilename,
		bool convertToScreen = false,
		EDitherType ditherStyle = IImage::kNoDither);

	/**
   * To be obsoleted. Use IGImagePixelAccessor class.
   */	
  IImage(
		const IString& imageFilename,
		EImageFormat imageFormat,
		bool convertToScreen = false,
		EDitherType ditherStyle = IImage::kNoDither);

  /**
   * To be obsoleted.
   * To be obsoleted. Use IGImagePixelAccessor::writeToFile() instead.
   * NOTE: The GIF file format is inherently an 8-bit format. Attempting to write a
   * GIF file using this function while specifying other than 8 bits per pixel will result
   * in a runtime error
   */
	IImage& writeToFile(const IString& imageFilename, EImageFormat imageFormat);

#endif //(IC_OBSOLETE <= IC_OBSOLETE_3)
	
  protected:

#if (IC_OBSOLETE <= IC_OBSOLETE_3)
	/**
   * To be obsoleted
   * To be obsoleted. Use IGImagePixelAccessor::loadFromFile() instead.
   */
	IImage& loadFromFile(
		const IString& imageFilename,
	   	EImageFormat imageFormat,
	   	bool covertToScreen,
	   	EDitherType ditherStyle);
#endif //(IC_OBSOLETE <= IC_OBSOLETE_3)

    /**
     * Adopts an IGImage. Deletes the old image and the old mask.
     */
	void adoptImage(IGImage* theImage);

    /**
     * Returns origin point (0., 0.).
     */
	IGPoint2D sourceOrigin()const;

private:
	// for internal assumption only
	/**
	 * Returns the transformation matrix of the image in world space.
	 */
	const IGrafMatrix* matrix() const;

friend class IProgressIndicatorData; // IProgressIndicatorData::layoutNativeSlider
friend class IAnimatedButtonData;
 // IAnimatedButtonData::drawForeground
 // IAnimatedButtonData::timerExpired
    /**
	 * Moves the image's position to the specified point.
	 */
    IImage& moveTo(const IGPoint2D&);

friend class IBitmapHandler;
friend class IToolBarButton;
	/**
	 * Scales the image into a specified size.
	 */
	IImage& sizeTo(const IGPoint2D& newSize);
			
  private:
	IGrafMatrix* fMatrix;
	IGRect2D* fBounds;
	IGImage* fImage;
	IAttributeState* fBundle;
	unsigned long fSeed;
	unsigned long fBoundsTimeStamp;
	IBaseColor	fTransparentColor;
};

#pragma enum(pop)
#pragma pack(pop)

#if __IBMCPP__ >= 400
#pragma namemangling()
#endif

#endif // _IIMAGE_
