/***************************************************************/
//
//
//		DirectX	[ texturegl.cpp ]
//
//											Author	kazuki tanaka
//											Date	2017 4/25
/*---------------------------------------------------------------
■Update : 2017/4/25
			texturegl.cppの作成

/*---------------------------------------------------------------
	Include File
---------------------------------------------------------------*/


//#include <Windows.h>
//#include <stdio.h>
//#include <d3dx9.h>

#include "texturegl.h"

#include <stdio.h>
#include <Windows.h>
#include <gl\GL.h>
#include <gl\GLU.h>

#ifdef _DEBUG
#pragma comment( lib, "library/dlibpng16.lib" )
#pragma comment( lib, "library/dzlib.lib" )
#else
#pragma comment( lib, "library/libpng16.lib" )
#pragma comment( lib, "library/zlib.lib" )
#endif // _DEBUG

#include "png.h"

//#pragma comment (lib,"d3d9.lib")
//#pragma comment (lib,"d3dx9.lib")
//#pragma comment (lib,"dxguid.lib")


/*---------------------------------------------------------------
	Macro Difinition
---------------------------------------------------------------*/

#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }


/*---------------------------------------------------------------
	Const Number Difinition
---------------------------------------------------------------*/

#define NUM_VERTEX  ( 4 )						
#define NUM_POLYGON ( 2 )						

/*----------------------------------------------------------------
	static member variable Initialize 
----------------------------------------------------------------*/





// CTextureGL Constructor
CTextureGL::CTextureGL( )
{

	// Menber Clear Process

}

// CTextureGL Destructor
CTextureGL::~CTextureGL( )
{

	// Do Nothing!!

}

// CTextureGL Create Instance 
CTextureGL* CTextureGL::Create( void )
{

	// Create Class Instance
	CTextureGL* pObject;
	pObject = new CTextureGL;

	return pObject;

}

// CTextureGL Initialize
void CTextureGL::Init( void )
{

	// Initialize Process


}

// CTextureGL Uninitialize
void CTextureGL::Uninit( void )
{

	// Uninitialize Process


}

// CTextureGL Update
void CTextureGL::Update( void )
{

	// Update Process


}

// CTextureGL Draw
void CTextureGL::Draw( void )
{

	// Draw Process


}

// CTecxtureGL Load Texture
unsigned int CTextureGL::GLTextureLoadFromTga( const std::string& fileName )
{

	// Texture Load Process
	const char* TEXTURE_FORMAT[ ] = {
		"tga",
	};

	

	// file Load
	FILE* fp = fopen( fileName.data( ), "rb" );

	if( fp == NULL ){

		#ifdef _DEBUG
		MessageBox( NULL, "FILE_LOAD_ERROR", "ERROR!!", 0 );
		#endif // _DEBUG
		return 0;
	}

	// get header file
	unsigned char header[18];
	bool byteformat = false;
	bool vertical = false,horizonal = false;

	fread( header, sizeof(header), 1, fp );

	// pixel Stencil Value
	if( header[16] == 32 ){
		byteformat = true;
	}

	// check [ Header File ]
	if( (header[17] && 0x10) ){
		horizonal = true;
	}

	if( (header[17] && 0x20) ){
		vertical = true;
	}

	unsigned short width, height;

	// get Pixel Size
	width = *((unsigned short*)&header[12]);
	//width = header[13] * 256 + header[12];
	height = *((unsigned short*)&header[14]);

	BYTE byte = *(&header[16]);

	unsigned char* pImage
		= new unsigned char[ width * height * 4 ];

	
	if( horizonal && vertical ){
		for( unsigned short y = 0; y < height; y++ ){
			for( unsigned short x = 0; x < width; x++ ){

				pImage[ (y * width + ( width-1 - x ) ) *4 + 2 ] = fgetc(fp);
				pImage[ (y * width + ( width-1 - x ) ) *4 + 1 ] = fgetc(fp);
				pImage[ (y * width + ( width-1 - x ) ) *4 + 0 ] = fgetc(fp);
				pImage[ (y * width + ( width-1 - x ) ) *4 + 3 ] = fgetc(fp);

			}
		}
	}
	else if( vertical ){

		for( unsigned short y = 0; y < height; y++ ){
			for( unsigned short x = 0; x < width; x++ ){

				pImage[ (y * width + x ) *4 + 2 ] = fgetc(fp);
				pImage[ (y * width + x ) *4 + 1 ] = fgetc(fp);
				pImage[ (y * width + x ) *4 + 0 ] = fgetc(fp);
				pImage[ (y * width + x ) *4 + 3 ] = fgetc(fp);

			}
		}
	}
	else if( horizonal ){

		for( unsigned short y = 0; y < height; y++ ){
			for( unsigned short x = 0; x < width; x++ ){

				pImage[ ( (height-1 - y) * width + ( width-1 - x ) ) *4 + 2 ] = fgetc(fp);
				pImage[ ( (height-1 - y) * width + ( width-1 - x ) ) *4 + 1 ] = fgetc(fp);
				pImage[ ( (height-1 - y) * width + ( width-1 - x ) ) *4 + 0 ] = fgetc(fp);
				pImage[ ( (height-1 - y) * width + ( width-1 - x ) ) *4 + 3 ] = fgetc(fp);

			}
		}
	}
	else{
		for( unsigned short y = 0; y < height; y++ ){
			for( unsigned short x = 0; x < width; x++ ){

				pImage[ ( (height-1 - y) * width + x ) *4 + 2 ] = fgetc(fp);
				pImage[ ( (height-1 - y) * width + x ) *4 + 1 ] = fgetc(fp);
				pImage[ ( (height-1 - y) * width + x ) *4 + 0 ] = fgetc(fp);
				pImage[ ( (height-1 - y) * width + x ) *4 + 3 ] = fgetc(fp);

			}
		}
	}
	
	

	

	fclose(fp);

	unsigned int texture;
	glGenTextures( 1, &texture );

	glBindTexture( GL_TEXTURE_2D, texture );

	glPixelStorei( GL_PACK_ALIGNMENT, 1 );

	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );

	gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pImage );

	glBindTexture( GL_TEXTURE_2D, 0 );

	delete[] pImage;
	pImage = nullptr;

	return texture;

}

// CTecxtureGL Load Texture
unsigned int CTextureGL::GLTextureLoadFromPng( const std::string& fileName )
{

	
	// Signature Load Process
	FILE* fp = fopen( fileName.data( ), "rb" );

	if( fp == NULL ){

		#ifdef _DEBUG
		MessageBox( NULL, "FILE_LOAD_ERROR", "ERROR!!", 0 );
		#endif // _DEBUG
		return 0;
	}

	unsigned char header[8];

	// get Header Info
	fread( header, 1, 8, fp);
	
	if ( png_sig_cmp( header, 0, 8 ) )
		return (0);

		
	// png_struct 構造体の初期化
	png_structp png_ptr = png_create_read_struct (
					   PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr );
	if (!png_ptr) return (ERROR);

	// png_info 構造体の初期化（画像データの前にあるチャンク用）
	png_infop info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr) {
		png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
		return (ERROR);
	}

	// png_info 構造体の初期化（画像データの後にあるチャンク用）
	png_infop end_info = png_create_info_struct(png_ptr);
	if (!end_info) {
		png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
		return (ERROR);
	}

	// setjmp/longjmp
	if (setjmp(png_jmpbuf(png_ptr))) {
		png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
		fclose(fp);
		return (ERROR);
	}

	// ファイル・ポインタのセット
	png_init_io( png_ptr, fp );

	// 事前にシグネチャを読込確認済なら、ファイル先頭から読み飛ばしているバイト数を知らせる
	png_set_sig_bytes( png_ptr, 8 );  

	// 高水準読込インタフェース
	png_read_png(
		png_ptr,
		info_ptr,
		0,//PNG_TRANSFORM_PACKING
		//| PNG_TRANSFORM_INVERT_ALPHA,
		NULL );

	unsigned int width  = png_get_image_width( png_ptr, info_ptr );
	unsigned int height = png_get_image_height( png_ptr, info_ptr );
	// Custom Load
	unsigned int depth = png_get_bit_depth( png_ptr, info_ptr );

	// 各行のピクセル・データのポインタ配列
	png_bytep* row_pointers;

	// Pixelフォーマット書き出し
	unsigned char* pImage
		= new unsigned char[ width * height * 4 ];

	row_pointers = png_get_rows( png_ptr, info_ptr );

	for( unsigned short y = 0; y < height; y++ ){
		for( unsigned int x = 0; x < width; x++ ){

			pImage[ (y * width + x) *4 + 0 ] = row_pointers[y][ x * 4 + 0 ];
			pImage[ (y * width + x) *4 + 1 ] = row_pointers[y][ x * 4 + 1 ];
			pImage[ (y * width + x) *4 + 2 ] = row_pointers[y][ x * 4 + 2 ];
			pImage[ (y * width + x) *4 + 3 ] = row_pointers[y][ x * 4 + 3 ];
		}
	}

	png_destroy_read_struct(
		&png_ptr,
		&info_ptr,
		&end_info );

	fclose(fp);
	
	
	unsigned int texture;
	glGenTextures( 1, &texture );

	glBindTexture( GL_TEXTURE_2D, texture );

	glPixelStorei( GL_PACK_ALIGNMENT, 1 );

	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );

	gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pImage );

	glBindTexture( GL_TEXTURE_2D, 0 );

	delete[] pImage;
	pImage = nullptr;

	return texture;

}




