/****************************************************************************
 * Copyright (c) 2024 MAK Technologies, Inc.
 * All rights reserved.
 ****************************************************************************/

/*********************************************************************/
/**
 *t  diguyGraphicsTexture
 **
 *b    Link against: libdiguy_graphics_api
 */

#ifndef __diguyGraphicsTexture_H
#define __diguyGraphicsTexture_H

#ifdef SWIG
%module diguyGraphicsTexture
#else
#define CPLUSPLUS_ONLY
#endif

#ifdef CPLUSPLUS_ONLY
#include <declspec_diguy.h>
#include <diguy_constants.h>

class bdiGeometryTextureFile;
class diguyGraphicsTexture;


#endif

/****************************************************************************/
/*l
 *b  Description:
 **
 **    This enumeration lists the types of compression that texture map data
 **    may have.
 **
 */
enum diguyGraphicsTextureCompressionType
{
   DIGUY_GRAPHICS_TEXTURE_COMPRESSION_TYPE_NONE = 0,
   DIGUY_GRAPHICS_TEXTURE_COMPRESSION_TYPE_DXT1,
   DIGUY_GRAPHICS_TEXTURE_COMPRESSION_TYPE_DXT2,
   DIGUY_GRAPHICS_TEXTURE_COMPRESSION_TYPE_DXT3,
   DIGUY_GRAPHICS_TEXTURE_COMPRESSION_TYPE_DXT4,
   DIGUY_GRAPHICS_TEXTURE_COMPRESSION_TYPE_DXT5,
   DIGUY_GRAPHICS_TEXTURE_COMPRESSION_TYPE_DXT5_NM
};


/****************************************************************************/
/*l
 *b  Description:
 **
 **    This enumeration lists the type of texture map a given image file is
 **    being used as.
 **
 */
enum diguyTextureMapType
{
   DIGUY_TEXTURE_MAP_TYPE_UNKNOWN = -1,
   DIGUY_TEXTURE_MAP_TYPE_DIFFUSE = 0,
   DIGUY_TEXTURE_MAP_TYPE_SHADOW,
   DIGUY_TEXTURE_MAP_TYPE_SPECULAR,
   DIGUY_TEXTURE_MAP_TYPE_BUMP,
   DIGUY_TEXTURE_MAP_TYPE_COMPONENTS,
   DIGUY_TEXTURE_MAP_TYPE_COMPONENT_RAMP,
   DIGUY_TEXTURE_MAP_TYPE_MISC_1,
   DIGUY_TEXTURE_MAP_TYPE_MISC_2,
   DIGUY_TEXTURE_MAP_TYPE_ANIMATION,
   DIGUY_TEXTURE_MAP_TYPE_DECAL,
   DIGUY_TEXTURE_MAP_TYPE_DECAL_SPECULAR,
   DIGUY_TEXTURE_MAP_TYPE_DECAL_BUMP,
   DIGUY_TEXTURE_MAP_TYPE_COUNT
} ;


/****************************************************************************/
/*l
 *b  Description:
 **
 **    This enumeration lists how the state stores the available textures in
 **    the textures_available bitfield.  Also used by the shader programs.
 **
 */
enum diguyTextureMapMasks
{
   DIGUY_TEXTURE_MAP_MASK_DIFFUSE    = 0x00000001,
   DIGUY_TEXTURE_MAP_MASK_SHADOW     = 0x00000002,
   DIGUY_TEXTURE_MAP_MASK_SPECULAR   = 0x00000004,
   DIGUY_TEXTURE_MAP_MASK_BUMP       = 0x00000008,
   DIGUY_TEXTURE_MAP_MASK_COMPONENTS = 0x00000010,
   DIGUY_TEXTURE_MAP_MASK_MISC_1     = 0x00000020,
   DIGUY_TEXTURE_MAP_MASK_MISC_2     = 0x00000040,
   DIGUY_TEXTURES_MAP_MASK_ALL       = 0xffffffff
} ;

/*l
 *b  Description:
 **
 **    This function converts the passed texture type enumeration into
 **    a NULL-terminated C-style string.
 **
 *b  Returns:
 **
 **    C-style string identifying texture map type
 */

BDI_DECLSPEC_bdiutil const char* diguy_texture_type_to_string(diguyTextureMapType texture_type);

/*l
 *b  Description:
 **
 **    This function converts the passed C-style string into an
 **    enumerated value.
 **
 *b  Returns:
 **
 **    enumeration value of string
 */

BDI_DECLSPEC_bdiutil diguyTextureMapType diguy_texture_type_from_string(const char* string);

/****************************************************************************/
/*!
** \brief A class that represents a shared texture.
**
**  Can be subclassed by filling out the diguy_graphics_set_texture_create_func().
**
** \ingroup diguyGraphicsAPI
*/
class BDI_DECLSPEC_diguy diguyGraphicsTexture
{

public:

/*****************************************************************************/
/**
 *2  Accessor Functions
 **
 **    The functions in this section provide access to data in this object.
 **    They are designed to be called by DI-Guy programmers.
 **
 **   Unless noted all functions in this section are callable from:
 **
 *-    - C++
 *-    - Script
 */

   /*l
    *b  Description:
    **
    **    Returns the name of the texture.  This pointer will
    **    never be NULL.
    **
    *b  Returns:
    **
    **    name of the texture
    */
   const char* get_name();

   /*l
    *b  Description:
    **
    **    This function returns the filename of the texture.  This pointer
    **    may be NULL if the texture does not have an associated filename.
    **
    *b  Returns:
    **
    **    filename of the texture
    */
   const char* get_filename();

   //! Returns: Where diguy found the file name... will be null if source data isn't available
   const char* get_full_filename();

   //! Returns: The file after transformation and stored in compressed_texture_cache
   const char* get_cached_dds_filename();

   /*l
    *b  Returns:
    **
    **    the width of the texture, in pixels; -1 on failure
    */
   int get_width();

   /*l
    *b  Returns:
    **
    **    the height of the texture, in pixels; -1 on failure
    */
   int get_height();

   /*l
    *b  Description:
    **
    **    This function returns how many components the texture has.  The
    **    number of components will be an integer between 1 and 4.
    **
    **    Most textures have three components, red (R), green (G), and
    **    blue (B), or RGB.  These textures commonly have filenames with
    **    the extension .rgb.
    **
    **    Four component textures add an alpha (A) channel, resulting in
    **    RGBA.  These textures commonly have filenames with the extension
    **    .rgba.
    **
    **    One component textures have only an intensity (I).  These textures
    **    commonly have filenames with the extension .int.
    **
    **    Two component textures have only an intensity (I), and an alpha
    **    channel.  These textures commonly have filenames with the
    **    extension .inta.
    **
    *b  Returns:
    **
    **    number of components in texture; -1 on failure
    */
   int get_num_components();

   /*l
    *b  Description:
    **
    **    This function returns whether the texture contains an alpha
    **    component.  Textures that have an alpha component can make
    **    objects semi-transparent, which can affect when said objects
    **    should be drawn.
    **
    *b  Returns:
    **
    **    1 if texture contains an alpha component, 0 if not; -1 on failure
    */
   int get_contains_alpha_component();

   /**
    **   Returns if this texture should be rendered with alpha to coverage,
    **   Clip maps have 4 channels but return false for get_contains_alpha_component
    **   Useful for screen door transparency, and out of order transparency
    */
   int get_is_clip_map();

#ifdef CPLUSPLUS_ONLY

   /*l
    *b  Description:
    **
    **    This function returns a memory buffer with the actual texture
    **    data.
    **
    **    The size of buffer can be obtained by calling
    **    get_texture_map_data_size().
    **
    **    The texture information is packed into the buffer row by row,
    **    in the following order:
    **
    *-      - I    (intensity) for one component textures
    *-      - IA   (intensity and alpha) for two component textures
    *-      - RGB  (red, blue, green) for three component textures
    *-      - RGBA (red, blue, green, alpha) for four component textures
    **
    **    There is one byte per component.
    **
    **    This function should not be called after free_loader_memory()
    **    has been called.
    **
    **    Note that some renderers expect to take ownership of the texture
    **    data that is passed to them.  In this case, a copy of this texture
    **    data must be made to avoid a double deletion of the memory.  This
    **    texture data will be deleted by the call to free_loader_memory(),
    **    or when this object is deleted.
    **
    *b  Returns:
    **
    **    pointer to texture map data
    **
    **    NOTE: The returned pointer may be NULL, if there was some problem
    **    loading the texture file.
    **
    *b  Callable From:
    **
    *-    - C++
    */
   unsigned char* get_texture_map_data();

#endif

   /*l
    *b  Description:
    **
    **    This function returns how many bytes are used by the texture
    **    map data buffer.
    **
    *b  Returns:
    **
    **    buffer size of texture map data, in bytes; may be 0 in the
    **    case of a NULL texture
    */
   int get_texture_map_data_size();

   /*l
    *b  Description:
    **
    **    This function returns which compression method, if any, is
    **    applied to the data returned bu get_texture_map_data().
    **
    **    Most often compressed textures come from .dds (DirectDraw Surface)
    **    files.
    **
    *b  Returns:
    **
    **    compression type enumeration
    */
   diguyGraphicsTextureCompressionType get_texture_compression_type();

   /*l
    *b  Description:
    **
    **    This function returns how many mipmaps are already included in
    **    the texture map data.
    **
    **    Typically only .dds (DirectDraw Surface) textures have precomputed
    **    mipmaps in them.
    **
    **    Note that values 0 and 1 are somewhat the same: there is only
    **    one image in the texture map data: the base, unscaled image.
    **
    *b  Returns:
    **
    **    num of included mipmaps
    */
   int get_num_included_mipmaps();

   /*l
    *b  Description:
    **
    **    This function returns the size of the data, in bytes, of the
    **    specified mipmap.
    **
    **    "mipmap" 0 is the base, unscaled image, mipmap 1 is the first
    **    scaled image, etc.
    **
    *b  Returns:
    **
    **    data size, in bytes, of mipmap; -1 on error
    */
   int get_mipmap_data_size(int mipmap);

   /*l
    *b  Description:
    **
    **    This function returns the data offset of the specified mipmap
    **    into the data pointer returned by get_texture_map_data().
    **
    **    "mipmap" 0 is the base, unscaled image, mipmap 1 is the first
    **    scaled image, etc.
    **
    *b  Returns:
    **
    **    data offset, in bytes, of mipmap; -1 on error
    */
   int get_mipmap_data_offset(int mipmap);

   /*l
    *b  Description:
    **
    **    This function returns the OpenGL pixel format enumeration of this
    **    texture.
    **
    **    This enumeration will be one of the following:
    **
    *-    - GL_LUMINANCE
    *-    - GL_LUMINANCE_ALPHA
    *-    - GL_RGB
    *-    - GL_RGBA
    *-    - GL_COMPRESSED_RGB_S3TC_DXT1_EXT
    *-    - GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
    *-    - GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
   .*     - GL_COMPRESSED_RGB_ALPHA_S3TC_DXT1_EXT
   .*     - GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
    **
    *b  Returns:
    **
    **    OpenGL pixel format enum; -1 on error
    **
    **    In OpenGL and OSG environments, the returned value should be cast
    **    into a GLenum.
    */
   int get_gl_format();

   /*l
    *b  Description:
    **
    **    This function returns the OpenGL pixel format string of this
    **    texture.  There are a large number of potential results depending
    **    if compressed textures and/or sRGB textures are enabled.
    **
    **    Example of possible results:
    **
    *-    - GL_RGB GL_RGBA
    *-    - sRGB: GL_SRGB GL_SRGB_ALPHA
    *-    - Compressed: GL_COMPRESSED_RGB_S3TC_DXT1 GL_COMPRESSED_RGBA_S3TC_DXT5
    *-    - sRGB + Compressed: GL_COMPRESSED_RGB_ALPHA_S3TC_DXT1 GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5
    */
   const char* get_gl_format_as_string();

   //! returns if texture should use sRGB style format hints, useful in DX11 where gl_format is less useful.
   int get_is_srgb_texture();

   /*l
    *b  Description:
    **
    **    This function returns the "block size" of the dds compression
    **    types.  This value can be useful in generating mipmap data offsets.
    **
    **    Alternatively, the function get_mipmap_data_offset() can be called
    **    to get the precomputed mipmap data offsets.
    **
    **    Currently this value will be either 8 (for DXT1 compression) or 16
    **    (for DXT3 and DXT5 compression).
    **
    *b  Returns:
    **
    **    block size, in bytes
    */
   int get_dds_block_size();

   /*l
    *b  Description:
    **
    **    For texture indices less than zero and greater than one, a decision
    **    must be made as to whether the texture is repeated or whether the
    **    edge pixels are replicated to fill the space.
    **
    **    This function returns whether the texture should be repeated
    **    horizontally (don't clamp) or whether the edge column of pixels
    **    should be used (do clamp).
    **
    **    Note that in MultiGen Creator attribute (.attr) files, this
    **    corresponds to the "Wrap Method u" attribute.
    **
    *b  Returns:
    **
    **    0 is texture should be tiled, 1 if not; -1 on failure
    */
   int get_clamp_s();

   /*l
    *b  Description:
    **
    **    For texture indices less than zero and greater than one, a
    **    decision must be made as to whether the texture is repeated
    **    or whether the edge pixels are replicated to fill the space.
    **
    **    This function returns whether the texture should be repeated
    **    vertically (don't clamp) or whether the edge row of pixels
    **    should be used (do clamp).
    **
    **    Note that in MultiGen Creator attribute (.attr) files, this
    **    corresponds to the "Wrap Method v" attribute.
    **
    *b  Returns:
    **
    **    0 is texture should be repeated, 1 if not; -1 on failure
    */
   int get_clamp_t();

   //! Is this texture currently being loaded by the asynchronous texture loader.
   //! if so you can render an approximation of the color via get_approximate_color()
   int get_is_in_async_load_queue();

   //! Returns an approximation of the overall color based on mip-mapping that was generated
   //! when bdg files were built.
   void get_approximate_color(float *r, float *g, float *b);

   /*l
    *b  Description:
    **
    **    This function frees most memory allocated by the DI-Guy geometry
    **    loader for this object.
    **
    **    This function should only be called during or after the object's
    **    build() function has been called.  After it has been called, calls
    **    to many accessor functions will fail.
    */
   void free_loader_memory();


/*****************************************************************************/
/**
 *2  Virtual Functions
 **
 **    The functions in this section are all virtual functions that will
 **    be called by DI-Guy at various times during DI-Guy execution.
 **
 **    Because the functions are all virtual, DI-Guy programmers can create
 **    a subclass of this class and override them.  Unless otherwise stated,
 **    the base class functions do not need to be called.
 */

#ifdef CPLUSPLUS_ONLY

   /*l
   *b  Description:
   **
   **    This function will be called by DI-Guy after the texture is loaded but before build.
   **    When asynchronous texture loading is active this provides an opportunity to copy data from
   **    DI-Guy structures to end user structures in the background loading thread.
   **
   *i  Immediate Mode:
   **
   **    Immediate mode renderers may override this function.
   **
   *i  Scene Graph:
   **
   **    Scene graph renderers may override this function, if they are using the async texture loader.
   **    may need to be coupled with calls to diguyScenario::run_background_load_update()
   **
   *b  Callable From:
   **
   *-    - N/A (automatically called by DI-Guy Graphics API during
   *-      the Build Stage)
   */
   virtual void asynchronous_post_load();

   /*l
    *b  Description:
    **
    **    This function will be called by DI-Guy when it is time for a
    **    renderer-specific texture object to be created.  At that point
    **    the texture information has been read from the texture file,
    **    and is available via the Accessor Functions above.
    **
    *i  Immediate Mode:
    **
    **    Immediate mode renderers may override this function, to
    **    create an object that may be invoked by bind_now().
    **
    *i  Scene Graph:
    **
    **    Scene graph renderers usually do override this function, to
    **    create an object that gets associated with diguyGraphicsMesh
    **    objects.
    **
    *b  Callable From:
    **
    *-    - N/A (automatically called by DI-Guy Graphics API during
    *-      the Build Stage)
    */
   virtual void build();

   /*l
    *b  Description:
    **
    **    This function will be called by DI-Guy when it is time for a
    **    renderer-specific texture object to be destroyed.
    **
    *i  Immediate Mode:
    **
    **    Immediate mode renderers may override this function, to
    **    destroy any object that may have been created by build().
    **
    *i  Scene Graph:
    **
    **    Scene graph renderers usually do override this function, to
    **    destroy any object that may have been created by build().
    **
    *b  Callable From:
    **
    *-    - N/A (automatically called by DI-Guy Graphics API during
    *-      the Unbuild Stage)
    */
   virtual void unbuild();

   /*l
    *b  Description:
    **
    **    This function will be called by DI-Guy when the texture should
    **    be made active, or bound.
    **
    *i  Immediate Mode:
    **
    **    Immediate mode renderers usually do override this function, to
    **    invoke the object created by build(), or make calls to the
    **    renderer to set appropriate texture state.
    **
    *i  Scene Graph:
    **
    **    Scene graph renderers usually do not override this function.
    **
    *b  Callable From:
    **
    *-    - N/A (automatically called by DI-Guy Graphics API during
    *-      Draw Stage)
    */
   virtual void bind_now(diguyTextureMapType texture_type);

   /*l
    *b  Description:
    **  helper function to let diguy internals know what the object's texture ID is. not normally needed.
    **  (Used by character viewer in gapi mode.)
    **/
   virtual unsigned int get_gl_texture_id() const;

   /*l
    *b  Description:
    **
    **    This function returns the last bound texture used by DI-Guy.  This
    **    value can be used in diguyGraphicsTexture::bind() to check to see
    **    if a texture rebind is necessary; avoiding a texture rebind can
    **    avoid a significant performance hit in some rendering systems.
    **
    *b  Callable From:
    **
    *-    - C++
    */
   static diguyGraphicsTexture* get_last_bound_texture(int texture_unit = 0);

   /*l
    *b  Description:
    **
    **    This function clears out the last bound texture variable.
    **    diguyScenario::draw() automatically calls it, but it is also
    **    recommended that it be called before drawing individual
    **    diguyCharacters in case something outside of DI-Guy has changed
    **    the texture.
    **
    *b  Callable From:
    **
    *-    - C++
    */
   static void clear_last_bound_texture();


#endif

   void load_texture_data(int async_load);

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

/**
 *x  The functions and variables past this point are for internal use only.
 **   No external access to them is expected or necessary.
 */
#ifdef CPLUSPLUS_ONLY

   bdiGeometryTextureFile* get_scripted_object() {return m_scripted_object;}

protected:

   /*l
    **    A protected constructor.  Constructors are called automatically
    **    by DI-Guy.
    */
   diguyGraphicsTexture(void* internal_data);

   /*l
    **    A protected destructor.  Destructors are called automatically
    **    by DI-Guy.
    */
   virtual ~diguyGraphicsTexture();

private:

   /*l
    **    A pointer to internal data.
    */
   bdiGeometryTextureFile* m_scripted_object;

   friend class bdiGeometryTextureFile;
   friend class bdiGeometryFactory;

#endif

};


#endif /* __diguyGraphicsTexture_H */

