/****************************************************************************************

		IShTextureMap.h

		Copyright: (c) 2001 Eovia Corp. All rights reserved.
	
		Author:	Emil
		Date:	12/11/98

		Revision History

		when		who			what & why
		==========	==========	======================================================
		10/01/99	David		Add GetRasterLayer
*****************************************************************************************/
#ifndef __IShTextureMap__
#define __IShTextureMap__

#if CP_PRAGMA_ONCE
#pragma once
#endif

#include "ComTypes.h"
#include "APITypes.h"
#include "MCColorRGBA.h"
#include "Vector2.h"
#include "Real.h"
#include "MCHash.h"

struct IShRasterLayer; 
struct IShChannel;
struct IMCFile;
struct TSequencedMovieInfos;
struct IShMovie;
struct IShLayerList;
struct I3DShInstance;
class TMCPixelBucket;
class TMCRect;
struct InvalidTextureRectCallback;

/****** Globally Unique Ids **************************************************/
MCDEFINE_GUID_H(IID_IShTextureMap);
MCDEFINE_GUID_H(IID_IShTextureMapFile);
MCDEFINE_GUID_H(CLSID_TextureMap);
MCDEFINE_GUID_H(IID_IExTextureMapIDUser);


struct IShTextureMapFile;


/// Filtering methods for TextureMappingInfo::fFiltering
enum ETMapFilter
{
	kFast		= 0,
	kSummedArea = 1,	///< Use summed area tables
	kGaussian	= 2		///< ( used for area shading only )
};

/// structure to get/set options on a texture (IShTextureMap)
///
class TextureMappingInfo : public TMCObject
{
public:
	TextureMappingInfo()
	{
		fTiling				= false;
		fSeamless			= false;
		fRepeatCount[0]		= 1;
		fRepeatCount[1]		= 1;
		fFlip[0]			= false;
		fFlip[1]			= true;				// The texture map is UpSideDown in the shaders by default	
		fNinetyDegreeCount  = 0;
		fInterpolate		= false;
		fInvertColor		= false;
		fBrightness			= kRealOne;
		fFiltering			= kFast;			// by default fast filtering
		fIsInternal			= false;			// by default texture is External
		
	}
	boolean operator== (const TextureMappingInfo& other) const
	{
		return 
			fTiling				== other.fTiling &&
			fSeamless			== other.fSeamless &&
			fRepeatCount[0]		== other.fRepeatCount[0] &&
			fRepeatCount[1]		== other.fRepeatCount[1] &&
			fFlip[0]			== other.fFlip[0] &&
			fFlip[1]			== other.fFlip[1] &&
			fNinetyDegreeCount  == other.fNinetyDegreeCount &&
			fInterpolate		== other.fInterpolate &&
			fInvertColor		== other.fInvertColor &&
			fBrightness			== other.fBrightness &&
			fFiltering			== other.fFiltering &&
			fIsInternal			== other.fIsInternal;
	}
	TextureMappingInfo(const TextureMappingInfo& other):TMCObject(other)
	{
		fTiling				= other.fTiling;
		fSeamless			= other.fSeamless;
		fRepeatCount[0]		= other.fRepeatCount[0];
		fRepeatCount[1]		= other.fRepeatCount[1];
		fFlip[0]			= other.fFlip[0];
		fFlip[1]			= other.fFlip[1];
		fNinetyDegreeCount  = other.fNinetyDegreeCount;
		fInterpolate		= other.fInterpolate;
		fInvertColor		= other.fInvertColor;
		fBrightness			= other.fBrightness;
		fFiltering			= other.fFiltering;
		fIsInternal			= other.fIsInternal;
	}
	boolean			fTiling;				///< Should the texture be repeated on the object
	boolean			fSeamless;				///< Should the texture be mirrored when it is repeated
	int16			fRepeatCount[2];		///< The number of repetitions along the X (width) and Y (height) axes.
	boolean			fFlip[2];				///< Should the texture be mirrored in X or Y
	int16			fNinetyDegreeCount;		///< Number of 90 degrees turn to apply to the texture
	boolean			fInterpolate;			///< Should the texture be interpolated
	boolean			fInvertColor;			///< Should the texture's colors be inverted
	real			fBrightness;			///< Value between zero and one, which multiplies values in GetValue and GetColor
	ETMapFilter		fFiltering;				///< The filter method to use
	boolean			fIsInternal;			///< True if the texture is saved inside the Carrara file
};


struct ITextureMapListener
{
	virtual void		MCCOMAPI TextureModified() = 0;
};
struct IShTextureMapHardwareResult : public IMCUnknown
{
	// ****************************************************************************
	//								ReleaseContent
	// 
	/// Release the contents.
	/// Further request for content would require recomputing the content
	virtual void MCCOMAPI ReleaseContent() = 0;
	// ****************************************************************************
	//								CalculateHardwareResult
	// 
	/// Calculate the hardware representation result
	/// \param[out] canReleasePixelBucket true iff the pixel bucket can be release without causing problems to the hardware result
	virtual boolean MCCOMAPI CalculateHardwareResult(const TMCPixelBucket& origTexture, boolean& canReleasePixelBucket) = 0;
		// ****************************************************************************
		//								UpdateHardwareResult
		// 
		/// Update the hardware representation result
		/// \param[out] canReleasePixelBucket true iff the pixel bucket can be release without causing problems to the hardware result
    virtual boolean MCCOMAPI UpdateHardwareResult(const TMCPixelBucket& origTexture, boolean& canReleasePixelBucket, const TMCRect& updateRect) = 0;
	virtual boolean MCCOMAPI HasValidData() = 0;
};
struct IShTextureMapResultCache : public IMCUnknown
{
    // A callback function defined to be used when the content has been released.
    typedef void (*ReleaseNotificationFunction)(IShTextureMapResultCache* privData);
	// ****************************************************************************
	//								HasAlphaChannel
	// 
	/// Check if the texture has an alpha channel.
	virtual boolean MCCOMAPI HasAlphaChannel() const = 0;
	// ****************************************************************************
	//								GetCommonPixelBucket
	// 
	/// Get the common pixel bucket in the specified size.
	/// This pixel bucket ignores the specific mapping.
	virtual TMCPixelBucket* MCCOMAPI GetCommonPixelBucket() const = 0;
	// ****************************************************************************
	//								GetHardwareResult
	// 
	/// Get the hardware result
	virtual IShTextureMapHardwareResult* MCCOMAPI GetHardwareResult() const = 0;
	// ****************************************************************************
	//								ReleaseContent
	// 
	/// release the contents of this texture bucket to preserve memory
	/// Further request for content would require recomputing the content
	virtual void MCCOMAPI ReleaseContent() = 0;
     // ****************************************************************************
	//								SetReleaseNotificationFunction
	// 
	/// Set the function pointer to a notifier in case the content was released.
	virtual void MCCOMAPI SetReleaseNotificationFunction(ReleaseNotificationFunction ptr) = 0; 
};
//AlternativeTextureAvailableProc is the same as TextureAvailableProc
typedef void (*AlternativeTextureAvailableProc)(void * privData);
struct IShTextureMapBucketCache : public IMCUnknown
{

	// ****************************************************************************
	//								CalcCommonPixelBucketInSize
	// 
	/// Get the common pixel bucket in the specified size.
	/// This pixel bucket ignores the specific mapping.
	/// \param[in] proc procedure to update the scene one the bucket has been calculated
	virtual void MCCOMAPI CalcCommonPixelBucketInSize(uint32 width, uint32 height, 
		AlternativeTextureAvailableProc proc, I3DShInstance* relevantInstance, IShTextureMapHardwareResult* hardwareResultHandler) = 0;
	// ****************************************************************************
	//								GetReslt
	// 
	/// Get result object common to all textures using the same texture map
	/// This pixel bucket ignores the specific mapping.
	virtual void MCCOMAPI GetResult(IShTextureMapResultCache** result) const = 0;
	// ****************************************************************************
	//								FlipAlongAxis
	// 
	/// Should the texture be flipped along the specified axis
	/// \param[in] axisNum the queried axis
	virtual boolean MCCOMAPI FlipAlongAxis(int16 axisNum) const = 0;
    // ****************************************************************************
	//								GetTextureMultiplyColor
    //
	//  Get the texture multiply color
    virtual TMCColorRGB MCCOMAPI GetTextureMultiplyColor() const = 0;
    // ****************************************************************************
	//								SetTextureMultiplyColor
    //
	//  Set the texture multiply color
    virtual void MCCOMAPI SetTextureMultiplyColor(TMCColorRGB color) = 0;    
    // ****************************************************************************
	//								GetBumpAmplitude
    //
	//  Get the bump amplitude
    virtual real MCCOMAPI GetBumpAmplitude() const = 0;
    // ****************************************************************************
	//								SetBumpAmplitude
    //
	//  Set the bump amplitude
    virtual void MCCOMAPI SetBumpAmplitude(real newValue) = 0;
    // ****************************************************************************
	//								GetUniqueCommonTexturePtr
    //
	//  Get pointer that uniquely identifies all the IShTextureMapBucketCache representing the same texture map file.
    virtual IMCUnknown*  MCCOMAPI GetUniqueCommonTexturePtr() const = 0;    
};
struct IShTextureMapFile : public IMCUnknown
{
	// ****************************************************************************
	//								GetLayerList
	// 
	/// Returns the layer list associated with this texture map.
	/// 
	virtual IShLayerList*	MCCOMAPI GetLayerList() = 0;

	// ****************************************************************************
	//								SetLayerList
	// 
	/// Sets the layer list associated with this texture map.
	/// 
	virtual void			MCCOMAPI SetLayerList(IShLayerList* layerList) = 0;

	// ****************************************************************************
	//								Reload
	// 
	/// Reload the texture map for the associated file is it has one.
	/// 
	virtual void		MCCOMAPI Reload() = 0;

	// ****************************************************************************
	//								LoadAsLayerList
	// 
	/// Load the texture map as a layer list. If the format is not fully supported
	/// the function returns false and will not load it as a layer list. Except if
	/// forceNotSupported is true, in that case the image will be loaded as a layer
	/// list but the resulting image might not be excatly as the original one.
	/// 
	virtual boolean		MCCOMAPI LoadAsLayerList(boolean forceNotSupported, boolean reload=false) = 0;

	// ****************************************************************************
	//								LoadAsExtLayerList
	// 
	/// Load the texture as a layer without modifiying the internal texture mpa file.
	/// 
	virtual boolean		MCCOMAPI LoadAsExtLayerList(IShLayerList** layerList) = 0;

	// ****************************************************************************
	//								Save
	// 
	/// Saves the texture map to the associated file if it is supported.
	/// 
	virtual void		MCCOMAPI Save() = 0;
};


//***********************************************************************************

// IShTextureMap reresents the shell texture map object
// 2 modes exist to tell it where to get the bitmap data from : internal and external
// - internal mode : use SetChannel, giving the actual data to be used in 32 bit format
// - external mode : use SetFile, giving an image file to load and use
//
// in both modes GetChannel can be used to get the bitmap data
// while GetFile only returns valid data in external mode
//
// note : movie files can be passed into SetFile as well
//		  but movies can only exist in external mode

struct IShTextureMap: public IMCUnknown
{
	virtual boolean  MCCOMAPI IsInternalMode() const																= 0;
	virtual MCCOMErr MCCOMAPI SetInternalMode( const boolean &internal )											= 0;
	virtual MCCOMErr MCCOMAPI SaveExternally( IMCFile * file , const IDType &format, boolean displayOptions = true)	= 0;

	// ****************************************************************************
	//								SetFile
	// 
	// -Description:
	//
	// Sets the image/movie file corresponding to a texture map
	//
	// -Parameters:
	//
	// file			: a pointer to the file
	// format		: either 'imag' or 'movi' or kAnyFile ('****')
	//
	virtual MCCOMErr MCCOMAPI SetFile(IMCFile * file, IDType format, const TSequencedMovieInfos* infos= NULL)		= 0;
	virtual MCCOMErr MCCOMAPI GetFile(IMCFile ** file, IDType & format)	const										= 0;

	virtual MCCOMErr MCCOMAPI SetChannel(IShChannel * channel)														= 0;
	virtual MCCOMErr MCCOMAPI GetChannel(IShChannel ** channel)	const												= 0;
	virtual MCCOMErr MCCOMAPI GetRasterLayer(IShRasterLayer** rasterLayer) const									= 0;

	virtual MCCOMErr MCCOMAPI SetTextureMappingInfo(const TextureMappingInfo & info)								= 0;
	virtual MCCOMErr MCCOMAPI GetTextureMappingInfo(TextureMappingInfo & info) const								= 0;

	virtual MCCOMErr MCCOMAPI GetColor(TMCColorRGBA &result, const TVector2 &position)								= 0;
	virtual MCCOMErr MCCOMAPI GetColor(TMCColorRGBA &result, const TVector2 area[])									= 0;

	virtual MCCOMErr MCCOMAPI GetVector(TVector3 &result, const TVector2 &position)									= 0;

	virtual MCCOMErr MCCOMAPI Clone(IShTextureMap ** clone, ECloneMode mode)										= 0;

	virtual boolean  MCCOMAPI IsMovie		() const																= 0;
	virtual void	 MCCOMAPI SetIsMovie	(boolean isMovie)														= 0;

	virtual boolean  MCCOMAPI IsEqualTo( const IShTextureMap *t2 ) const											= 0; // return true if thid & t2 have the SameImage + Same TextureMappingInfo.
	virtual boolean  MCCOMAPI IsImageEqualTo( const IShTextureMap *t2 ) const										= 0; // return true if this & t2 have the SameImage 

	virtual IShMovie* MCCOMAPI GetMovie		() = 0;

	// ****************************************************************************
	//								RegisterListener
	// 
	/// Register a listener which is notified when the texture map is modified.
	/// 
	virtual void	 MCCOMAPI RegisterListener(ITextureMapListener* listener) = 0;

	// ****************************************************************************
	//								UnregisterListener
	// 
	/// Unregister a listener.
	/// 
	virtual void	 MCCOMAPI UnregisterListener(ITextureMapListener* listener) = 0;

	// ****************************************************************************
	//								HasAlphaChannel
	// 
	/// Returns true if the texture map as an alpha channel different from 1 in any
	/// pixel.
	/// 
	virtual boolean MCCOMAPI HasAlphaChannel()=0;

	// ****************************************************************************
	//								Reload
	// 
	/// Reload the texture map for the associated file is it has one.
	/// 
	virtual void		MCCOMAPI Reload() = 0;

	// ****************************************************************************
	//								LoadAsLayerList
	// 
	/// Load the texture map as a layer list. If the format is not fully supported
	/// the function returns false and will not load it as a layer list. Except if
	/// forceNotSupported is true, in that case the image will be loaded as a layer
	/// list but the resulting image might not be excatly as the original one.
	/// 
	virtual boolean		MCCOMAPI LoadAsLayerList(boolean forceNotSupported) = 0;

	// ****************************************************************************
	//								IsWritable
	// 
	/// Returns true if the texture map is writable.
	/// 
	virtual boolean		MCCOMAPI IsWritable() = 0;

	// ****************************************************************************
	//								SetWritable
	// 
	/// Changes the texture map to writable. It returns false is this texture map
	/// does not support writing.
	/// 
	virtual boolean		MCCOMAPI SetWritable() = 0;

	// ****************************************************************************
	//								MarkModified
	// 
	/// Marks the texture map as modified.
	/// 
	virtual void		MCCOMAPI MarkModified() = 0;

	// ****************************************************************************
	//								MarkUnmodified
	// 
	/// Marks the texture map as unmodified.
	/// 
	virtual void		MCCOMAPI MarkUnmodified() = 0;

	// ****************************************************************************
	//								IsModified
	// 
	/// Returns true if the texture mpa is modified in memory.
	/// 
	virtual boolean		MCCOMAPI IsModified() = 0;

	// ****************************************************************************
	//								Save
	// 
	/// Saves the texture map to the associated file if it is supported.
	/// 
	virtual void		MCCOMAPI Save() = 0;

	// ****************************************************************************
	//								GetUniqueTextureMapID
	// 
	/// Changes the channel of the texture map. Note that it will modify the texture
	/// map and overwrite the old channel.
	/// 
	virtual uint32		MCCOMAPI GetUniqueTextureMapID() = 0;

	// ****************************************************************************
	//								GetTextureMode
	// 
	/// Returns the mode of the texture map (alpha support, RGB mode...)
	/// 
	virtual void		MCCOMAPI GetTextureMode(boolean& alpha) = 0;
	
	// ****************************************************************************
	//								GetTextureMode
	// 
	/// Sets the mode of the texture map (alpha support, RGB mode...)
	/// 
	virtual void		MCCOMAPI SetTextureMode(boolean alpha) = 0;

	// ****************************************************************************
	//								GetLayerList
	// 
	/// Returns the layer list associated with this texture map.
	/// 
	virtual IShLayerList*	MCCOMAPI GetLayerList() = 0;

	// ****************************************************************************
	//								SetTextureMapFile
	// 
	/// Changes the texture map file.
	/// 
	virtual void				MCCOMAPI SetTextureMapFile(IShTextureMapFile* mapFile) = 0;

	// ****************************************************************************
	//								GetTextureMapFile
	// 
	/// Returns the texture map file.
	/// 
	virtual IShTextureMapFile*	MCCOMAPI GetTextureMapFile() = 0;

	// ****************************************************************************
	//								IsProtected
	// 
	/// Gets the protected state of this texture map.
	/// 
	virtual boolean				MCCOMAPI IsProtected() = 0;

	// ****************************************************************************
	//								SetProtected
	// 
	/// Sets the protected state of the texture map.
	/// 
	virtual void				MCCOMAPI SetProtected(boolean protect) = 0;
    // ****************************************************************************
    //                             GetTextureSize
    //
    /// Calculate the intrinsic appropriate texture size.
    virtual void  MCCOMAPI GetTextureSize(uint32& width, uint32& height) const = 0;
    // ****************************************************************************
	//                             GetRelevantTextureBucketCache
	//
	/// Get the texture bucket cache associated with the current texture (considering the mapping)
	virtual void MCCOMAPI GetRelevantTextureBucketCache(IShTextureMapBucketCache** outTextureMapFile) const = 0;
};


struct IExTextureMapIDUser : public IMCUnknown
{
	virtual void	MCCOMAPI RenamedTextureMapID(const TMCHashMap<uint32, uint32>& renamedTextureMapId) = 0;
};


#endif

