/*
								+----------------------------------+
								|                                  |
								| ***   Texture loader class  ***  |
								|                                  |
								|   Copyright © -tHE SWINe- 2007   |
								|                                  |
								|          TextureUtil.h           |
								|                                  |
								+----------------------------------+
*/

#pragma once
#ifndef __TEXTURE_UTIL_INCLUDED
#define __TEXTURE_UTIL_INCLUDED

/**
 *	@file gl2/TextureUtil.h
 *	@date 2007
 *	@author -tHE SWINe-
 *	@brief texture loader class
 *
 *	@date 2007-07-14
 *
 *	removed GL_TEXTURE_2D target from CGLTexture_2D constructor calls
 *
 *	@date 2007-12-24
 *
 *	improved linux compatibility by using posix integer types
 *
 *	@date 2008-03-04
 *
 *	added CTextureLoader::p_LoadTexture which can decide fileformat by itself
 *
 *	@date 2008-05-07
 *
 *	fixed stupid error in CTextureLoader::p_LoadTexture which couldn't decide
 *	fileformat correctly
 *
 *	@date 2008-10-09
 *
 *	renamed CTextureLoader to CGLTextureLoader (but there's typedef on the end of the file
 *	so the code is backwards-compatible. however, new name should be always used.)
 *
 *	added CGLTextureLoader::p_LoadTexture_3D()
 *
 *	cleaned-up image format decission and loading a little bit
 *
 *	exposed internal texture format override in all texture loading functions
 *
 *	moved function bodies to TextureUtil.cpp
 *
 *	@date 2009-05-04
 *
 *	fixed mixed windows / linux line endings
 *
 *	@date 2009-10-20
 *
 *	fixed some warnings when compiling under VC 2005, implemented "Security
 *	Enhancements in the CRT" for VC 2008. compare against MyProjects_2009-10-19_
 *
 *	@date 2012-06-19
 *
 *	Moved multiple inclusion guard before file documentation comment.
 *
 */

#include "../Tga.h"
#include "../Jpeg.h"
#include <stdio.h>

/*
 *	class CGLTextureLoader
 *		- simple class with a few useful functions for loading textures directly from file
 */
class CGLTextureLoader {
public:
	/*
	 *	CGLTextureLoader::<__unnamed_0>
	 *		- image format names
	 */
	enum {
		format_Unknown = -1,
		format_Targa,
		format_Jpeg
	};

	/*
	 *	static int CGLTextureLoader::n_IdentifyFormat(const char *p_s_filename)
	 *		- identifies format of image file p_s_filename
	 *		  by it's extension (doesn't look at file data)
	 *		- returns one of format_Unknown, format_Targa, format_Jpeg
	 */
	static int n_IdentifyFormat(const char *p_s_filename);

	/*
	 *	static TBmp *CGLTextureLoader::p_LoadTargaImage(const char *p_s_filename)
	 *		- returns targa image, loaded from file p_s_filename
	 *		  or 0 on failure
	 */
	static TBmp *p_LoadTargaImage(const char *p_s_filename);

	/*
	 *	static TBmp *CGLTextureLoader::p_LoadJpegImage(const char *p_s_filename)
	 *		- returns jpeg image, loaded from file p_s_filename
	 *		  or 0 on failure
	 */
	static TBmp *p_LoadJpegImage(const char *p_s_filename);

	/*
	 *	static TBmp *CGLTextureLoader::p_LoadImage(const char *p_s_filename,
	 *		int n_force_format = format_Unknown)
	 *		- returns image, loaded from file p_s_filename or 0 on failure
	 *		- in case n_force_format is different than format_Unknown,
	 *		  it is used as guide to which codec to use. otherwise format
	 *		  is determied using n_IdentifyFormat() by file extension
	 *		- in case n_force_format is format_Unknown and file has no
	 *		  extension, it tries to load image using targa codec or
	 *		  using jpeg codec (only if jpeg error handling is compiled)
	 */
	static TBmp *p_LoadImage(const char *p_s_filename, int n_force_format = format_Unknown);

	/*
	 *	static GLenum CGLTextureLoader::n_Optimal_InternalFormat(const TBmp *p_bitmap,
	 *		bool b_force_alpha = false)
	 *		- returns optimal texture internal format for image p_bitmap
	 *		  (based on image being greyscale and on alpha channel presence)
	 */
	static GLenum n_Optimal_InternalFormat(const TBmp *p_bitmap, bool b_force_alpha = false);

	/*
	 *	static CGLTexture_2D *CGLTextureLoader::p_LoadTexture(CGLState *p_state,
	 *		const char *p_s_filename, bool b_mipmaps = true, bool b_clamp_to_edge = false,
	 *		GLenum n_force_internal_format = 0, int n_force_format = format_Unknown)
	 *		- returns new 2D texture
	 *		- p_state is OpenGL state guard, p_s_filename is image file name
	 *		- b_mipmaps controls wheter texture is created with mipmaps
	 *		- b_clamp_to_edge sets texture wrap mode to GL_CLAMP_TO_EDGE
	 *		- passing nonzero n_force_internal_format sets texture internal format
	 *		  to n_force_internal_format (otherwise RGB8 / RGBA8 is used)
	 *		- if n_force_format is not format_Unknown, image is loaded using
	 *		  corresponding codec (otherwise format is determined using filename
	 *		  extension)
	 */
	static CGLTexture_2D *p_LoadTexture(CGLState *p_state, const char *p_s_filename,
		bool b_mipmaps = true, bool b_clamp_to_edge = false,
		GLenum n_force_internal_format = 0, int n_force_format = format_Unknown);

	/*
	 *	static CGLTexture_2D *CGLTextureLoader::p_LoadTexture_TGA(CGLState *p_state,
	 *		const char *p_s_filename, bool b_mipmaps = true, bool b_clamp_to_edge = false,
	 *		GLenum n_force_internal_format = 0)
	 *		- returns new 2D texture
	 *		- p_state is OpenGL state guard, p_s_filename is targa image file name
	 *		- b_mipmaps controls wheter texture is created with mipmaps
	 *		- b_clamp_to_edge sets texture wrap mode to GL_CLAMP_TO_EDGE
	 *		- passing nonzero n_force_internal_format sets texture internal format
	 *		  to n_force_internal_format (otherwise RGB8 / RGBA8 is used)
	 */
	static CGLTexture_2D *p_LoadTexture_TGA(CGLState *p_state, const char *p_s_filename,
		bool b_mipmaps = true, bool b_clamp_to_edge = false, GLenum n_force_internal_format = 0);

	/*
	 *	static CGLTexture_2D *CGLTextureLoader::p_LoadTexture_Jpeg(CGLState *p_state,
	 *		const char *p_s_filename, bool b_mipmaps = true, bool b_clamp_to_edge = false,
	 *		GLenum n_force_internal_format = 0)
	 *		- returns new 2D texture
	 *		- p_state is OpenGL state guard, p_s_filename is jpeg image file name
	 *		- b_mipmaps controls wheter texture is created with mipmaps
	 *		- b_clamp_to_edge sets texture wrap mode to GL_CLAMP_TO_EDGE
	 *		- passing nonzero n_force_internal_format sets texture internal format
	 *		  to n_force_internal_format (otherwise RGB8 / RGBA8 is used)
	 */
	static CGLTexture_2D *p_LoadTexture_Jpeg(CGLState *p_state, const char *p_s_filename,
		bool b_mipmaps = true, bool b_clamp_to_edge = false, GLenum n_force_internal_format = 0);

	/*
	 *	static CGLTexture_2D *CGLTextureLoader::p_LoadTexture_Hybrid(CGLState *p_state,
	 *		const char *p_s_color_filename, const char *p_s_alpha_filename,
	 *		bool b_mipmaps = true, bool b_clamp_to_edge = false,
	 *		GLenum n_force_internal_format = 0)
	 *		- returns new 2D texture
	 *		- p_state is OpenGL state guard
	 *		- p_s_color_filename and p_s_alpha_filename are image filenames. rgb
	 *		  components of first image are merged with second image alpha channel
	 *		  (in case the second image doesn't have an alpha channel, it's red
	 *		  channel is used)
	 *		- b_mipmaps controls wheter texture is created with mipmaps
	 *		- b_clamp_to_edge sets texture wrap mode to GL_CLAMP_TO_EDGE
	 *		- passing nonzero n_force_internal_format sets texture internal format
	 *		  to n_force_internal_format (otherwise RGB8 / RGBA8 is used)
	 */
	static CGLTexture_2D *p_LoadTexture_Hybrid(CGLState *p_state,
		const char *p_s_color_filename, const char *p_s_alpha_filename,
		bool b_mipmaps = true, bool b_clamp_to_edge = false,
		GLenum n_force_internal_format = 0);

	/*
	 *	static CGLTexture_3D *CGLTextureLoader::p_LoadTexture_3D(CGLState *p_state,
	 *		const char *p_s_filename, bool b_mipmaps = true, bool b_clamp_to_edge = false,
	 *		GLenum n_force_internal_format = 0, int n_force_format = format_Unknown)
	 *		- returns new 3D texture
	 *		- p_state is OpenGL state guard, p_s_filename is image file name
	 *		  (file name contains formatting string for snprintf, such as
	 *		  "texture_%d.jpg" or "texture_%03d.jpg". first image index is 0,
	 *		  number of images is determined by trying to access image files
	 *		  in sequence)
	 *		- b_mipmaps controls wheter texture is created with mipmaps
	 *		- b_clamp_to_edge sets texture wrap mode to GL_CLAMP_TO_EDGE
	 *		- passing nonzero n_force_internal_format sets texture internal format
	 *		  to n_force_internal_format (otherwise RGB8 / RGBA8 is used)
	 *		- if n_force_format is not format_Unknown, image is loaded using
	 *		  corresponding codec (otherwise format is determined using filename
	 *		  extension)
	 */
	static CGLTexture_3D *p_LoadTexture_3D(CGLState *p_state, const char *p_s_filename,
		bool b_mipmaps = true, bool b_clamp_to_edge = false,
		GLenum n_force_internal_format = 0, int n_force_format = format_Unknown);

	/*
	 *	static CGLTexture_Cube *CGLTextureLoader::p_LoadTexture_Cube(CGLState *p_state,
	 *		const char *p_s_filename, bool b_mipmaps = true, bool b_clamp_to_edge = true,
	 *		GLenum n_force_internal_format = 0, int n_force_format = format_Unknown)
	 *		- returns new cube-map texture
	 *		- p_state is OpenGL state guard, p_s_filename is image file name
	 *		  (file name contains formatting string for snprintf, such as
	 *		  "texture_%s.jpg", %s is replaced by "pos-x", "neg-x", "pos-y", ...)
	 *		- b_mipmaps controls wheter texture is created with mipmaps
	 *		- b_clamp_to_edge sets texture wrap mode to GL_CLAMP_TO_EDGE
	 *		- passing nonzero n_force_internal_format sets texture internal format
	 *		  to n_force_internal_format (otherwise RGB8 / RGBA8 is used)
	 *		- if n_force_format is not format_Unknown, image is loaded using
	 *		  corresponding codec (otherwise format is determined using filename
	 *		  extension)
	 */
	static CGLTexture_Cube *p_LoadTexture_Cube(CGLState *p_state, const char *p_s_filename,
		bool b_mipmaps = true, bool b_clamp_to_edge = true,
		GLenum n_force_internal_format = 0, int n_force_format = format_Unknown);
};

typedef CGLTextureLoader CTextureLoader;

#endif // !__TEXTURE_UTIL_INCLUDED
