/* -----------------------------------------------------------------------------
*
*  nptexmap.c
*
*  ANTz - realtime 3D data visualization tools for the real-world, based on NPE.
*
*  ANTz is hosted at http://openantz.com and NPE at http://neuralphysics.org
*
*  Written in 2010-2019 by Shane Saxon - saxon@openantz.com
*
*  Please see main.c for a complete list of additional code contributors.
*
*  To the extent possible under law, the author(s) have dedicated all copyright 
*  and related and neighboring rights to this software to the public domain
*  worldwide. This software is distributed without any warranty.
*
*  Released under the CC0 license, which is GPL compatible.
*
*  You should have received a copy of the CC0 Public Domain Dedication along
*  with this software (license file named LICENSE.txt). If not, see
*  http://creativecommons.org/publicdomain/zero/1.0/
*
* --------------------------------------------------------------------------- */

#include "nptexmap.h"

#include "../../npdata.h"
#include "../../os/npos.h"
#include "../npgl.h"
#include "../npfile.h"				//zz models

#ifdef NP_ADDON_FREEIMAGE
	#include "../file/npfreeimage.h"	// needs to be after other includes
#endif
#ifdef NP_ADDON_SOIL
	#include "SOIL.h"
#endif


void npLoadTexturesLegacy(void* dataRef);
void npLoadTextures( void* dataRef);

//Textures, fonts, display lists, etc... can all be shared provided that:
//All rendering contexts of a shared display list must use an identical pixel format.
//http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=79299&page=1
//wglShareLists() supports texture sharing across GL contexts


/// @todo support sRGBA using GL_EXT_texture_sRGB
//------------------------------------------------------------------------------
/// Load texture maps from default folders into the GPU
void npInitTexMap (void* dataRef)
{
	pData data = (pData) dataRef;

//zz debug move init to npdata.c
	pNPtexmap texmap = NULL;
	int i = 0;
	data->io.gl.texmapCount = 0;

	for(i = 0; i < kNPtexListMax; i++)
	{
		texmap = &data->io.gl.texmap[i];
		texmap->loaded = 0;
		texmap->path[0] = '\0';
		texmap->filename[0] = '\0';
		texmap->channels = 0;
		texmap->height = 0;
		texmap->width = 0;
		texmap->image = NULL;
		texmap->extTexId = 0;
		texmap->intTexId = 0;
		texmap->reserved = 0;
	}

	npLoadTextures(dataRef);

	return;
}

/// @ todo update legacy support to use texture table to match map*.jpg to id
//------------------------------------------------------------------------------
/// Each texture needs to be referenced by the extMapMe 
void npLoadTextures( void* dataRef)
{
	int i = 0;
	int result = 0;
	int fileType = 0;
	int textureSize = 0;
	int fileNumber = 1;
	int fileCat = 0;

	pNPfileRef fRef = NULL;

	char* filename = (char*)malloc(4096);
	char fName[256] = {'\0'};

//zz-f	unsigned int textureID;		//zz debug, allow loading textures at runtime
									//detect changes to data->io.file.mapPath
	pData data = (pData) dataRef;


	glGetIntegerv( GL_MAX_TEXTURE_SIZE, &textureSize);
	data->io.gl.maxTextureSize = textureSize;

	printf("\nTexture Max: %dx%d\n", textureSize, textureSize);

	/// legacy using map00*.jpg ID sequence, before we had the image table
	npLoadTexturesLegacy( data );

//zz-f commented out below, comment back in and FIX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

/*	/// Now we load all other textures
	fRef = nposNewFileRef(data);
	result = nposFindFirstFile( fRef, kNPpathGlobalImages, "*.*", data);
	if( result != 1 )
		return;		// err or empty folder

	do
    {
		npGetFileTypeCat( &fileCat, fRef->name, data );

		// legacy support by skipping the ones we just loaded
		if( strncmp( fRef->name, "map", 3) == 0
			&& npGetFileTypeCat( &fileCat, fRef->name, data) == kNPfileJPG )
			continue;

		i++;

		// print first couple filenames and progress dots
		if( i < 5 )
			printf( "%.70s\n", fRef->name );
		else if( i % 10 == 0 )
			printf( "." );

//		printf("fRef->name : %s\n", fRef->name);
		sprintf( filename, "%s%s%s", data->io.file.appPath, kNPpathGlobalImages, fRef->name);
		printf("TEST npLoadTextures path: %s\n", filename);

		// if Folder (not a file) then recursively call to create dir tree
		if( fRef->isDir )
		{
		//	npLoadTextures( sPath, data );			// recursion
		}
		else
		{
//			if( (strcmp(fRef->name, ".DS_Store") == 0) || (strcmp(fRef->name, "README") == 0) || ( strcmp(fRef->name, "images-notes.txt") == 0) )
//				continue;
			
			//npFileNameFromPath(filename, fName, dataRef);
			//filename[strlen(filename) - strlen(fName)] = '\0';
			//npAddTexMap(0, fName, filename, dataRef);
			if( fileCat == kNPfileCatImage )
				textureID = npLoadTexture2( filename, 0, data ); // lv mac port // npLoadTexture2
		}
	}
	while( nposFindNextFile( fRef ) );	// next file within limits

    nposFindClose( fRef, data );		// always clean up!
*/
	if( data->io.gl.textureCount )
		printf( "\nTexture count: %d\n\n", data->io.gl.textureCount );
	else
		printf( "\nNo Textures Found!\n\n" );
}


//zz-t
void npLoadTexturesLegacy( void* dataRef) 
{
	int i = 0;
	int result = 0;
	int textureID;

	pNPfileRef fRef = NULL;

	char filename[kNPnameMax];

	pData data = (pData) dataRef;


	printf( "Loading: ../%s\n", kNPpathLegacyImages );

	fRef = nposNewFileRef( data );

	/// Legacy support where we first load map*.jpg files then all others
	result = nposFindFirstFile( fRef, kNPpathLegacyImages, "map*.jpg", data);
	if( result != 1 )
		return;		// err or empty folder

	do
    {
		i++;

		// print a few of the filenames then dots for every 100 files
		if( i < 5 )
			printf( "%.70s\n", fRef->name );
		else if( i < 10 || i % 5 == 0)
			printf( "." );

		sprintf(filename, "%s%s", kNPpathLegacyImages, fRef->name);

		// if Folder (not a file) then recursively call to create dir tree
		if( fRef->isDir == 0 )
			textureID = npLoadTexture2( filename, 0, data ); // lv mac port // npLoadTexture2
    }
	while( nposFindNextFile( fRef ) );	// next file within limits

	/// Now we load all other textures
	result = nposFindFirstFile(fRef, kNPpathLegacyImages, "*.*", data);
	if( result != 1 )
		return;		// err or empty folder

	do
    {
		// handle legacy support by skipping the ones we just loaded
		if( strncmp( fRef->name, "map", 3) == 0
			&& npGetFileTypeCat( NULL, fRef->name, data) == kNPfileJPG )
			continue;

		i++;

		// print first few filenames then dots
		if( i < 5 )
			printf( "%.70s\n", fRef->name );
		else if( i < 10 || i % 5 == 0)
			printf( "." );

		sprintf(filename, "%s%s", kNPpathLegacyImages, fRef->name);

		//skip any sub-directories in the legacy usr/images/ folder
		if( fRef->isDir == 0 )
			textureID = npLoadTexture2( filename, 0, data ); // lv mac port // npLoadTexture2
    }
	while( nposFindNextFile( fRef ) );	// next file within limits

    nposFindClose( fRef, data );		// always clean up!

	printf ("...\n");
}

// lv mac port models start
int npLoadTexture2( char* filePath, int fileType, void* dataRef )
{
	int i = 0;
	int extId = 0;
	int fileCat = 0;
	int textureID = 0;

	char* abs = NULL;
	char path[kNPmaxPath] = {'\0'};
	char filename[kNPmaxPath] = {'\0'};

	pData data = (pData)dataRef;
	pNPtexmap tex = NULL;


	if (filePath[0] == '\0')
		return 0;
//zz-f		printf("TEST npLoadTexture2 filePath: %s\n", filePath);

	if( npPathIsRel( filePath, dataRef ) )
	{
		abs = npFilePathRelToAbs( filePath, dataRef );
//zz-f			printf("absolute path is %s\n", abs);
		filePath[0] = '\0';
		strcpy( filePath, abs );
		free(abs);
	}

	npFileNameFromPath( filePath, &filename[0], dataRef );

	if( filePath[0] == '\0' )
	{
		printf( "err 4302 - missing fileName: %s\n", filename );
		return 0;
	}

//zz-f		printf("TEST TEST filename: %s\n", filename);

	strcpy( path, filePath );
	path[( strlen(filePath) - strlen(filename) )] = '\0';
	tex = npTexlistSearchFile( filename, path, dataRef );

	if(tex != NULL && tex->intTexId > 0)
	{
		/// tex search found
		printf("----235 found texture 235----\n");
		//system("pause");
		return tex->intTexId;
	}

	/// if fileType not defined, determine by the extension.
	if( !fileType )
		fileType = npGetFileTypeCat( &fileCat, filePath, dataRef );

//zz-f	printf("fileType: %d   fileCat: %d\n", fileType, fileCat);

	/// skip if its known not to be an image
	if( fileCat != kNPfileCatImage && fileCat != kNPfileCatNull )
		return 0;

	/// Use SOIL for efficient direct memory DDS file loading.
#ifdef NP_ADDON_SOIL
	if( fileType == kNPfileDDS )
	{
		textureID = SOIL_load_OGL_texture ( filePath,
			SOIL_LOAD_AUTO,
			SOIL_CREATE_NEW_ID,
			SOIL_FLAG_INVERT_Y |
			SOIL_FLAG_MIPMAPS * kNPglMipmaps );	// multiply to turn ON/OFF
			// | SOIL_FLAG_NTSC_SAFE_RGB	// we want the entire RGB spectrum
	}
	else
#endif
	{	/// Use FreeImage (addon) for all other (non-DDS) images.
#ifdef NP_ADDON_FREEIMAGE
		textureID = npfiLoadTexture( filePath, data );
#else
 #ifdef NP_ADDON_SOIL
		textureID = SOIL_load_OGL_texture ( filePath,
			SOIL_LOAD_AUTO,
			SOIL_CREATE_NEW_ID,
			SOIL_FLAG_INVERT_Y |
			SOIL_FLAG_MIPMAPS * kNPglMipmaps );
 #endif
#endif
	}

	// If success then increment the texture count.
	if( textureID )
	{
		data->io.gl.textureCount++; // lv mac port
		tex = &data->io.gl.texmap[data->io.gl.textureCount];
		tex->loaded = 1;
		strcpy(tex->filename, filename);
		tex->intTexId = textureID;
		//data->io.gl.extMapMe[data->io.gl.textureCount] = tex;
		for (i = 1; i < kNPgeoListMax; i++)
		{
			if( data->io.gl.extMap[i] == 0 )
			{
				
			}
		}
//zz-f		printf("textureCount:%d\n", data->io.gl.textureCount);
	}
	else
		printf("warn 4301 - could not load image: %s\n", filePath);


	return textureID;
} 
// lv mac port models stop

 
//------------------------------------------------------------------------------
/// Close open (video) files, release GPU texture memory and stop threads
void npCloseTexMap (void* dataRef)		//clean-up
{
	return;
}

//------------------------------------------------------------------------------
/*! Load texture maps from specified folder to the GPU.
	@param dirPath Directory path to search for file(s).
	@param fileFilter Only load files with specified filter, ie: 'map*.jpg'
	@param dataRef Global scene graph pointer.

	@todo Thread texture map loading.
*/
void npAddDirPath( int* dirID, char** dirList, const char* dirPath, void* dataRef)
{
		/// Skip files that have already been loaded
	return;
}

int npAddFile( int* fileID, int dirID, char* fileName, void* dataRef)
{
		/// Skip files that have already been loaded
		return 1;
}

//------------------------------------------------------------------------------
/*! Load texture maps from specified folder to the GPU.
	@param dirPath Directory path to search for file(s).
	@param fileFilter Only load files with specified filter, ie: 'map*.jpg'
	@param dataRef Global scene graph pointer.

	@todo Thread texture map loading.
*/
void npLoadTexDir( const char* dirPath, char* fileFilter, void* dataRef)
{
	/* // lv mac port
	int i = 0;
	int result = 0;
	int fileCat = 0;
	int fileID = 0;
	int dirID = 0;
	int texID = 0;
	pNPfileRef fRef = NULL;

	char filePath[kNPmaxPath];

	pData data = (pData) dataRef;
//	pNPtex tex = &data->io.gl.tex; // lv mac port, commented out


	if( !dirPath )
	{
		npPostMsg( "err 4330 - npLoadTexDir null dirPath", kNPmsgErr, data);
		return;
	}

	/// Add the directory path to the list, okay if already present
	npAddDirPath( &dirID, tex->dirPaths, dirPath, data);

	fRef = nposNewFileRef( data );

	/// Find the first file in the directory
	result = nposFindFirstFile( fRef, dirPath, fileFilter, data );
	if( !result )
	{
		printf( "warn 4331 - err or empty folder: %s\n", dirPath);
		return;
	}

	/// Loop through directory contents and process each file
	do
    {	//zz debug legacy workaround until npFileAdd is implemented
		if( !fileFilter && !strncmp(fRef->name, "map0", 4) )
				continue;
		
		sprintf( filePath, "%s/%s", dirPath, fRef->name );

		/// If Folder (not a file) then recursively call to create dir tree
		if( fRef->isDir )
		{
			npLoadTexDir( filePath, fileFilter, data );	/// recursion
		}
		else
		{
			npGetFileTypeCat( &fileCat, fRef->name, data);
			if( fileCat == kNPfileCatImage )
			{
			//	result = npAddFile( tex->files, dirID, fRef->name, data); //zz debug
				if( !result )
					continue;	/// skip files already loaded

				if( i++ < 5 )	// print the first few file names then dots
					printf( " %.70s\n", fRef->name );
				else if( i % 10 == 0 )
					printf( "." );
			
				texID = npLoadTexture( filePath, data );
			}
		}
    }
	while( nposFindNextFile( fRef ) );	// next file within limits

    nposFindClose( fRef, data );		// always clean up!

	if( i > 5 )
		printf( "\n" );
	*/
}


//Textures, fonts, display lists, etc... can all be shared provided that:
//All rendering contexts of a shared display list must use an identical pixel format.
//http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=79299&page=1
//wglShareLists() supports texture sharing across GL contexts

/// Load a texture map from the specified file path of specified image type.
/// If fileType = 0 then image type determined by the file extension.
//------------------------------------------------------------------------------
int npLoadTexture( const char* filePath, void* dataRef)
{
	int texID = 0;					///< texture_id
	int fileCat = 0;				///< file category 
	pData data = (pData) dataRef;
	
	/// prefer FreeImage (addon) if available, otherwise SOIL or nothing
#ifdef NP_ADDON_FREEIMAGE
		texID = npfiLoadTexture( filePath, data );
#else
#ifdef NP_ADDON_SOIL
		texID = SOIL_load_OGL_texture ( filePath,
			SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID,
			SOIL_FLAG_INVERT_Y | SOIL_FLAG_MIPMAPS * kNPglMipmaps );
#endif
#endif

	/// report err if no texture_id and category is kNPfileCatImage
	if( !texID )
	{
		npGetFileTypeCat( &fileCat, filePath, data);
		if( fileCat == kNPfileCatImage )
		{
			printf("\n");
			npPostMsg( "err 4332 - failed to load image:", kNPmsgErr, data);
			npPostMsg( filePath, kNPmsgErr, data);
		}
	}
	else {
	//	data->io.gl.tex.count++;	// success
		data->io.gl.texmapCount++; // lv mac port
	}
	return texID;
}

/*!
* @param dataRef is the command line argument count.
*
* Save a screenshot, either full window or thumbnail.
*/
//------------------------------------------------------------------------------
void npScreenShot (void* dataRef)
{
	int err = 0;
	int temp = 0; //store console level
    int w = 0, tempW = 0;
    int h = 0, tempH = 0;

	char filePath[kNPmaxPath];
	char timeStamp[64];
	char msg[kNPmaxPath];
		
	pData data = (pData) npGetDataRef();
	
	data->io.gl.width = glutGet( GLUT_WINDOW_WIDTH );
	data->io.gl.height = glutGet( GLUT_WINDOW_HEIGHT );
	w = tempW = data->io.gl.width;
	h = tempH = data->io.gl.height;

#ifdef NP_ADDON_FREEIMAGE

	//resize to thumbnail and turn off HUD
	if( data->io.gl.screenGrab == kNPscreenshotThumb )
	{
		sprintf( filePath, "%s.tiff", data->io.gl.datasetName );

		w = kNPthumbWidth; // 320 // 160 // data->map.thumbSize.width
		h = kNPthumbHeight; // 180 // 90  // data->map.thumbSize.height
		temp = data->io.gl.hud.console.level;
		data->io.gl.hud.console.level = 0;
		npGLResizeScene( w, h );
		npGLDrawScene( data );
		
		//grab backbuffer and write to file
		err = npfiScreenshot( filePath, kNPfileTIFF, kNPthumbAlpha, data);
		if( !err )
			sprintf(msg, "Save: %s", filePath);

		//restore screen size and re-render
		data->io.gl.hud.console.level = temp;
		npGLResizeScene( tempW, tempH);
		npGLDrawScene( data);
	}
	else // kNPscreenshotFull
	{
		// construct the file path
		nposTimeStampName( timeStamp );
		sprintf( filePath, "%s%s.tiff", data->io.file.mapPath, timeStamp );

		npGLDrawScene (data);
		
		/// grab the window display buffer and save to file
		err = npfiScreenshot( filePath, kNPfileTIFF, kNPscreenshotAlpha, data);	

		sprintf(msg, "Save Screenshot: %s", filePath);
	}
#endif

	if( err )
		sprintf(msg, "err 4334 - screenshot failed: %s", filePath);

	npPostMsg( msg, kNPmsgFile, data );

	data->io.gl.screenGrab = kNPscreenshotOFF;	//reset screenGrab flag
}


/// Initiate a screenshot thumbnail by setting the flag mode to kNPscreenshotThumb
int npScreenGrabThumb( char* name, int type, int x, int y, int w, int h, void* dataRef )
{
	pData data = (pData) dataRef;

/*	char pathName[kNPmaxPath];

	pathName[0] = '\0';
	strncat( pathName, data->io.file.mapPath, kNPmaxPath );
	strncat( pathName, name, kNPmaxPath - strlen( pathName ) );
*/	
	data->io.gl.datasetName[0] = '\0';
	strncat( data->io.gl.datasetName, name, kNPmaxPath );
	data->io.gl.screenGrab = kNPscreenshotThumb;			

	return 0; //zz add error handling
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------



//zz models begin
void npLoadGeos(void* dataRef);
void npLoadGeos(void* dataRef)
{
	int i = 0;
	int result = 0;
	int fileType = 0;
	int textureSize = 0;
	int fileNumber = 1;
	static int extTexId = 0;
	int geoId = 0;

	pNPfileRef fRef = NULL;

	char* filename = (char*)malloc(4096);
	char path[256] = {'\0'};

//	unsigned int textureID;		//zz debug, allow loading textures at runtime
//									//detect changes to data->io.file.mapPath
	pData data = (pData) dataRef;
	NPfloatXYZ center, rotate, scale;
	
	center.x = 0; rotate.x = 0; scale.x = 0;
	center.y = 0; rotate.y = 0; scale.y = 0;
	center.z = 0; rotate.z = 0; scale.z = 0;


//	printf ("Loading Geos... : %s\n", data->io.file.appPath);
//	sprintf( path, "%s%s", data->io.file.appPath, kNPpathGlobalModels );

	fRef = nposNewFileRef( data );

	result = nposFindFirstFile( fRef, kNPpathGlobalModels, "*.*", data );
	if( result != 1 )
		return;		// err or empty folder

	do
    {
		i++;

		sprintf(filename, "%s%s", kNPpathGlobalModels, fRef->name );

		// if Folder (not a file) then recursively call to create dir tree
		if( fRef->isDir )
		{
			// add dir tree recursion
		}
		else
		{
			//zz-f replace this with fileCat method
			if( ( strcmp( fRef->name, "models-notes.txt" ) == 0) 
				|| (strcmp( fRef->name, ".DS_Store" ) == 0) 
				|| (strcmp( fRef->name, "README" ) == 0) 
				)
				continue;

			// print first few filenames then dots
			if( i <= 5 )
				printf( "%.70s\n", fRef->name );
			else if(  i < 10 || i % 5 == 0 )
				printf( "." );


			extTexId = 0;
			npFileOpenAuto_modelTest2( fRef->name, dataRef ); // lv model port
		}
    }
	while( nposFindNextFile( fRef ) );	// next file within limits

    nposFindClose( fRef, data );		// always clean up!

	
	if( data->io.gl.numModels )
		printf ("\nDone Loading Models\n\n");
	else
		printf ("No Models Found!!!\n\n");
}


#define kNPextId 1
#define kNPintId 2


pNPtexmap npTexlistSearchFile(char* filename, char* path, void* dataRef)
{
	pData data = (pData) dataRef;
	int count = data->io.gl.textureCount;
	pNPtexmap tex = NULL;
	int i = 0;

	for(i = 0; i < kNPtexListMax; i++)
	{
		tex = &data->io.gl.texmap[i];
//		if( ( strcmp(tex->filename, filename) == 0 ) && ( strcmp(tex->path, path) == 0 ) )
//			return tex;
		if( ( strcmp(tex->filename, filename) == 0 ) )
			return tex;
	}

	return NULL;
}

pNPtexmap npTexlistSearchId(int var, void* val, void* dataRef);
pNPtexmap npTexlistSearchId(int var, void* val, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPtexmap tex = NULL;
	int count = data->io.gl.textureCount;
	int i = 0;
	int* valInt = NULL;

	switch(var)
	{
		case kNPextId:
			valInt = (int*)val;
			for(; i < kNPtexListMax; i++)
			{
				tex = &data->io.gl.texmap[i];
				if( tex->extTexId == (*valInt) )
					return tex;
			}
			break;
		case kNPintId:
			valInt = (int*)val;
			for(; i < kNPtexListMax; i++)
			{
				tex = &data->io.gl.texmap[i];
				if( tex->intTexId == (*valInt) )
					return tex;
			}
			break;
	}

	return NULL;
}


int npGetUnusedExtTexId(void* dataRef)
{
	pData data = (pData) dataRef;
	pNPtexmap texmap = NULL;
	int i = 1;
	int extId = 1;

//	printf("NPgetUNUSEDextTEXid\n");
	for(i = 1; i < kNPtexListMax; i++)
	{
		texmap = &data->io.gl.texmap[i];
		if(texmap->extTexId == extId)
		{
			extId++;
			if(extId == kNPtexListMax)
				return 0;

			i = 1;
		}
	}

	for( i = 1; i < kNPtexListMax; i++)
	{
//		data->io.gl.texmap[i].extTexId = extId; // lv, temp
		if( data->io.gl.texmap[i].filename[0] == '\0' && data->io.gl.texmap[i].path[0] == '\0'
			&& data->io.gl.texmap[i].extTexId == 0 && data->io.gl.texmap[i].intTexId == 0 &&
			data->io.gl.texmap[i].loaded == 0)
			break;
		/*
		if( data->io.gl.texmap[i].extTexId == 0 )
			break;
		*/
	}

//	data->io.gl.texmap[i].extTexId = extId; // lv, temp
	printf("extMapMe assigning %d", extId);
	data->io.gl.extMapMe[extId] = &data->io.gl.texmap[i];
	data->io.gl.extMapMe[extId]->extTexId = extId;	

	printf("  New ext tex id : %d\n", extId);

	return extId;
}

pNPtexmap npGetUnusedTexMap(void* dataRef)
{
	pData data = (pData) dataRef;
	pNPtexmap texmap = NULL;
	pNPtexmap defTex = &data->io.gl.texmap[0];
	int i = 0;
	int res = 0;
	int texSize = sizeof(NPtexmap);


	/// texmap[0] is default

	for(i = 1; i < kNPtexListMax; i++)
	{
		texmap = &data->io.gl.texmap[i];
		res = memcmp(defTex,texmap,texSize);
		if(res == 0)
			return texmap;

	}

	return NULL;
}



/*
	npTexMapFind(0, fName, path, dataRef) 

	pNPtexmap npTexFind(int* extId, char* fName, char* path, void* dataRef);
	behavior:
	- first searches for fName/path pair
	- if found
	    return tex;
*/
pNPtexmap npTexFind(int* extId, char* fName, char* path, void* dataRef);
pNPtexmap npTexFind(int* extId, char* fName, char* path, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPtexmap t = &data->io.gl.texmap[0];
	int i = 1;

	/*
	if( (fName == NULL) && (path == NULL) )
	{
		for(i = 1; i < kNPtexMax; i++)
		{
			t = &data->io.gl.texmap[i];
			if(t->extTexId == (*extId))
				return t;
		}

		return NULL;
	}
	*/

	for(i = 1; i < kNPtexMax; i++)
	{
		t = &data->io.gl.texmap[i];

		if( (t->filename[0] !=  '\0') && (t->path[0] != '\0') )
		{
			if( (strcmp(t->filename, fName) == 0) && (strcmp(t->path, path) == 0) )	
			{
				//(*extId) = t->extTexId; // lv temp
				return t;
			}
		}	
	}

	for(i = 1; i < kNPtexMax; i++)
	{
		t = &data->io.gl.texmap[i];

		if( t->filename[0] !=  '\0' )
		{
			if( strcmp(t->filename, fName) == 0 )
			{
				//(*extId) = t->extTexId; // lv temp
				return t;
			}
		}	
	}

	return NULL;
}

// returns index into texlist :: if failure, then 0
int npUsedTex(int extId, void* dataRef);
int npUsedTex(int extId, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPtexmap t = NULL;
	int i = 1;

	for(i = 1; i < kNPtexMax; i++)
	{
		t = &data->io.gl.texmap[i];
		if(t->extTexId == extId)
			return i;
	}

	return 0;
}
/*
int npLoadTex(pNPtexmap tex, void* dataRef);
int npLoadTex(pNPtexmap tex, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPtexmap texA = NULL;
	pNPgeolist geo = NULL;
	char filepath[256] = {'\0'};

	texA = npTexlistSearchId(kNPextId, &tex->extTexId, dataRef);
	if(texA && (texA->intTexId > 0))
	{
		tex->intTexId = texA->intTexId;
		return tex->intTexId;
	}
	
	if(texA && (texA->intTexId == 0))
	{
		sprintf(filepath, "%s%s", tex->path, tex->filename);
	//	printf("filepath : %s\n", filepath);
		tex->intTexId = npLoadTexture(filepath, dataRef);
		if(tex->intTexId > 0)
		{
	//		printf("ext %d to int %d\n", tex->extTexId, tex->intTexId);
			tex->loaded = 1;
		}
		else if(tex->intTexId == 0)
		{
			geo = npSearchGeolistExtTexId(tex->extTexId, dataRef);
			if(geo)
			{
				filepath[0] = '\0';
				sprintf(filepath, "%s%s", geo->modelPath, tex->filename);
				tex->loaded = 0;
			}

		}
	}
	

	return tex->intTexId;
}
*/


/*
pNPtexmap npAddTexMap(int* extId, char* fName, char* path, void* dataRef);
pNPtexmap npAddTexMap(int* extId, char* fName, char* path, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPtexmap t = NULL;
	int i = 1;
	int oldId = (*extId);
	char* abs = NULL;
	char intPath[256] = {'\0'};

	printf("57261 npAddTexMap\n");

	if( npPathIsRel(path, dataRef) )
	{
		abs = npFilePathRelToAbs(path, dataRef);
		strcpy(intPath, abs);
	}
	else
		strcpy(intPath, path);

	// check if filename / path pair already exists in list
	// if npTexFind can't find pair then it looks for only an fName match
	t = npTexFind(extId, fName, intPath, dataRef);
	if(t)
	{
		printf("npTexFind Found\n");
		printf("fName %s || path %s\n", fName, intPath);
		return t;
	}

	printf("npTexFind Not Found\n");
	printf("fName %s || path %s\n", fName, intPath);


	t = npTexNew(extId, fName, intPath, dataRef);
	

	return t;
}
*/
/*
pNPtexmap npAddTexMap(int extTexId, char* filename, char* path, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPtexmap texmap = &data->io.gl.texmap[0];
	pNPtexmap newTex = NULL;
	pNPtexmap texA = NULL;
	pNPtexmap texB = NULL;
	pNPtexmap texC = NULL;
	int i = 0;
	char* foundPath = NULL;

	if(!filename)
		return NULL;

	printf("TEXC 77383929012019\n");
	texC = npTexlistSearchFile(filename, data->io.file.appPath, dataRef);
	if(texC)
	{
		printf("---texC---\n");
		
		return texC;
	}

	if(extTexId == 0)
		extTexId = npGetUnusedExtTexId(dataRef);
	else
		texA = npTexlistSearchId(kNPextId, &extTexId, dataRef);

	printf("7L npAddTexMap(%d,%s,%s,void* dataRef)\n", extTexId, filename, path, dataRef);

	
	if(texA)
	{
		printf("--235----- replace texmap : %d\n", extTexId);
		if(texA->filename[0] != '\0' && filename[0] != '\0')
			strcpy(texA->filename, filename);

		if(texA->path[0] != '\0' && path[0] != '\0')
			strcpy(texA->path, path);

		texA->loaded = 0;
		texA->intTexId = 0;
		return texA;
	}



	texB = npTexlistSearchFile(filename, path, dataRef);
	
	if(texB)
	{
		return texB;
	}

	newTex = npGetUnusedTexMap(dataRef);
	if(newTex)
	{
		newTex->extTexId = extTexId;
		strcpy(newTex->filename, filename);
		if(path[0] == '\0' && filename[0] != '\0')
		{

			foundPath = npSearchPathsForFile(filename, dataRef);
			foundPath[ (strlen(foundPath) - strlen(filename)) ] = '\0';

			if( (foundPath[strlen(foundPath)-1] == '\\') 
				&& (foundPath[strlen(foundPath)-2] == '\\') )
			{
				foundPath[strlen(foundPath)-1] = '\0';
				printf("modified found path : %s\n", foundPath);
			}

			strcpy(newTex->path, foundPath);
		}
		else
		{
			if(path[strlen(path)-1] == '\\' && path[strlen(path)-2] == '\\')
			{
				path[strlen(path)-1] = '\0';
			}

			strcpy(newTex->path, path);
		}

		newTex->intTexId = 0;
		newTex->loaded = 0;
	}

	return newTex;
}
*/

/*
pNPtexmap npTexReserve(int extId, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPtexmap t = NULL;
	
	t = npTexFind(&extId, NULL, NULL, dataRef);
	if(t)
		return NULL;

	t = npTexNew(&extId, NULL, NULL, dataRef);
	//t->reserved =
	t->reserved = 1;
}
*/

//------------------------------------------------------------------------------
void npUpdateTexMap (void* dataRef)							//add to ctrl loop, debug zz
{
	pData data = (pData) dataRef;
	pNPtexmap texmap = NULL;
	pNPnode tmpNode = NULL; // lv mac port
	char filepath[256] = {'\0'};
	char* foundPath = NULL;
	int i = 0;

//	printf("npUpdateTexMap\n");
	if( data->io.file.loading == true){
		//printf("file is loading\n");
		return;
	}

	for( i = 1; i < kNPtexMax; i++ )
	{
		texmap = &data->io.gl.texmap[i];
//		if(texmap->filename[0] != '\0'){
//			printf("texmap->filename:%s  :: texmap->path:%s :: texmap->intTexId:%d\n", texmap->filename, texmap->path, texmap->intTexId);
//		}

		if(texmap->intTexId == 0 && texmap->loaded == 0 &&
			texmap->filename[0] != '\0' && texmap->path[0] != '\0')
		{
			printf("Loading extTexId : %d -- intTexId : %d --\n", texmap->extTexId, texmap->intTexId);
			printf("%s\n", texmap->path);
			printf("%s\n", texmap->filename);
			//system("pause");
			
		//	printf("texmap->extTexId : %d\n", texmap->extTexId);
		//	printf("texmap->path : %s\n", texmap->path);
		//	printf("texmap->filename : %s\n", texmap->filename);
			
			sprintf(filepath, "%s%s", texmap->path, texmap->filename);
			printf("Texture filepath: %s\n", filepath);
			texmap->intTexId = npLoadTexture2(filepath, 0, dataRef); // lv mac port models npLoadTexture2

			if(texmap->intTexId > 0)
			{
				texmap->loaded = 1;
				data->io.gl.syncTexList = 1;
			}
			else if(texmap->intTexId == 0)
			{
				texmap->loaded = 0;
				foundPath = npSearchPathsForFile(texmap->filename, dataRef);
				if(foundPath != NULL)
				{
					foundPath[strlen(foundPath)-strlen(texmap->filename)] = '\0';
					texmap->path[0] = '\0';
					strcpy(texmap->path, foundPath);
					free(foundPath);
				}
			}
		}
	}

	if(data->io.gl.syncTexList == 1 && data->io.file.loading == false){
		printf("syncTexlist count: %d\n", data->io.gl.nodeTexSyncListLength);
		//system("pause");
		for(i = 1; i <= data->io.gl.nodeTexSyncListLength; i++)
		{
//zz tex			printf("(syncTexList) node id : %d\n", data->io.gl.nodeTexSyncList[i]);
			tmpNode = npGetNodeByID( data->io.gl.nodeTexSyncList[i], dataRef );
			//printf("tmpNode : %p :: extId: %d\n", tmpNode, tmpNode->extTextureId);
//zz tex			printf("nodeTexSyncList[%d] :: %d\n", i, data->io.gl.nodeTexSyncList[i]);

			if(!tmpNode)
			{
				printf("invalid node\n");
				continue;
			}

//zz tex			printf("tmpNode->extTextureId:%d\n", tmpNode->extTextureId);
//zz tex			printf("data->io.gl.extMapMe[tmpNode->extTextureId] : %p", data->io.gl.extMapMe[tmpNode->extTextureId]);
			if(tmpNode && data->io.gl.extMapMe[tmpNode->extTextureId] != NULL)
			{
//zz tex				printf("mapping exists\n");
				if(data->io.gl.extMapMe[tmpNode->extTextureId]->intTexId > 0)
				{
					tmpNode->textureID = data->io.gl.extMapMe[tmpNode->extTextureId]->intTexId;
//zz tex					printf("transform to textureId %d\n", data->io.gl.extMapMe[tmpNode->extTextureId]->intTexId);
					data->io.gl.extMapMe[tmpNode->extTextureId] = NULL;
					data->io.gl.nodeTexSyncList[i] = 0;
				}
				else
				{
//zz tex					printf("texture is not loaded\n");
					data->io.gl.syncTexList = 1;
					return;
				}
			}
		}
		data->io.gl.nodeTexSyncListLength = 0;

		data->io.gl.syncTexList = 0;
	}

	return;
}
/*
void npLoadExtTexMaps(void* dataRef)
{
	pData data = (pData) dataRef;
	char fp[256] = {'\0'};
	int i;

	
	for(i = 1; i < 100; i++)
	{
		if( data->io.gl.extMapMe[i] &&
			data->io.gl.extMapMe[i]->loaded == 0
			&&
			data->io.gl.extMapMe[i]->filename[0] != '\0'
			&&
			data->io.gl.extMapMe[i]->path[0] != '\0'
			&&
			data->io.gl.extMapMe[i]->intTexId == 0)
		{
			sprintf(fp, "%s%s", data->io.gl.extMapMe[i]->path,
				data->io.gl.extMapMe[i]->filename);
			data->io.gl.extMapMe[i]->intTexId = npLoadTexture(fp, dataRef);
			if(data->io.gl.extMapMe[i]->intTexId > 0)
				data->io.gl.extMapMe[i]->loaded = 1;
		}
	}

}
*/
//zz models end

//#define GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX 0x9048
//#define GL_GPU_MEM_INFO_CURRENT_AVAILABLE_MEM_NVX 0x9049
//	GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX
//	glGetIntegerv( GL_GPU_MEM_INFO_CURRENT_AVAILABLE_MEM_NVX,

//zz-f

