/* -----------------------------------------------------------------------------
*
*  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-2016 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" // lv mac port
#include "../../../../sdk/libs/soil/src/SOIL.h" // lv mac port
#endif

//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 update legacy support to use texture table to match map*.jpg to id
//------------------------------------------------------------------------------
/// Each texture needs to be referenced by the extMapMe
 // lv mac port models start
void npLoadTextures(void* dataRef)
{
    //lv mac port models start
    int i = 0;
    int result = 0;
    int fileType = 0;
    int textureSize = 0;
    int fileNumber = 1;
    int fileCat = 0;
#ifdef NP_MSW_
    pNPfileRef fRef = NULL;
#endif
    char* filename = (char*)malloc(4096);
    char fName[256] = {'\0'};
    
    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 ("\nMax Texture Size: %dx%d\n", textureSize, textureSize);
    printf ("Loading Textures...\n");
    printf ("App Path : %s", data->io.file.appPath);
    //    printf ("Larger textures down converted\n", textureSize);

#ifdef __APPLE__
    npLoadTexturesOSX(dataRef);
#endif
    
#ifdef NP_MSW_
    fRef = nposNewFileRef( data );
    
    //------------------------------------------------------------------
    /// Now we load all other textures
    result = nposFindFirstFile( fRef, "usr/global/images/", "*.*", data );
    if( result != 1 )
        return;        // err or empty folder
    
    do
    {
        // legacy support by skipping the ones we just laoded
        if( strncmp(fRef->name, "map", 3) == 0
           && npGetFileTypeCat(&fileCat, fRef->name, data) == kNPfileJPG )
            continue;
        
        npGetFileTypeCat(&fileCat, fRef->name, data);
        
        i++;
        
        
        // print a few of the filenames then dots for every 100 files
        if( i <= 5 )
            printf( "%.70s\n", fRef->name );
        else if(  i < 100 || i % 100 == 0 )
            printf( "." );
        
        //        printf("fRef->name : %s\n", fRef->name);
        sprintf(filename, "%s%s%s", data->io.file.appPath ,"usr\\global\\images\\", fRef->name );
        //        printf("2 filename :F %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;
            
            //npGetFileNameFromPath(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
                if(textureId)
                    strcpy(data->io.gl.texmap[index].filename, fRef->name);
        }
    }
    while( nposFindNextFile( fRef ) );    // next file within limits
    
    nposFindClose( fRef, data );        // always clean up!
#endif
    if( data->io.gl.textureCount )
        printf ("\nDone Loading Textures\n\n");
    else
        printf ("No Textures Found!!!\n\n");
    // lv mac port models stop
}
// lv mac port models stop

void npLoadTexturesLegacy(void* dataRef);
void npLoadTexturesLegacy(void* dataRef)
{
#ifdef __APPLE__
    npLoadTexturesOSX(dataRef);
#endif
    // lv mac port models start
#ifdef NP_MSW_
    int i = 0;
    int result = 0;
    int fileType = 0;
    int textureSize = 0;
    int fileNumber = 1;
    
    pNPfileRef fRef = NULL;
    
    char* filename = (char*)malloc(4096);
    
    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 ("\nMax Texture Size: %dx%d\n", textureSize, textureSize);
    printf ("Loading Textures...\n");
    //    printf ("Larger textures down converted\n", textureSize);
    
    fRef = nposNewFileRef( data );
    
    /// Legacy support where we first load map*.jpg files then all others
    result = nposFindFirstFile( fRef, "usr/images/", "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 < 100 || i % 100 == 0 )
            printf( "." );
        
        sprintf(filename, "%s/%s", "usr/images/", fRef->name );
        
        // if Folder (not a file) then recursively call to create dir tree
        if( fRef->isDir )
        {
            //    npLoadTextures( sPath, data );            // recursion
        }
        else
            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, "usr/images/", "*.*", data );
    if( result != 1 )
        return;        // err or empty folder
    
    do
    {
        // handle legacy support by skipping the ones we just laoded
        if( strncmp(fRef->name, "map", 3) == 0
           && npGetFileTypeCat(NULL, fRef->name, data) == kNPfileJPG )
            continue;
        
        i++;
        
        // append current file/dir item to the basePath (parent dir)
        //       sprintf(sPath, "%s/%s", basePath, fRef->fdFile.cFileName);
        
        // print a few of the filenames then dots for every 100 files
        if( i <= 5 )
            printf( "%.70s\n", fRef->name );
        else if(  i < 100 || i % 100 == 0 )
            printf( "." );
        
        sprintf(filename, "%s/%s", "usr/images/", fRef->name );
        
        // if Folder (not a file) then recursively call to create dir tree
        if( fRef->isDir )
        {
            //    npLoadTextures( sPath, data );            // recursion
        }
        else
            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 ("\nDone Loading Textures\n\n");
    else
        printf ("No Textures Found!!!\n\n");
     */
    // lv mac port models stop
#endif
}

// lv mac port models start
int npLoadTexture2( char* filePath, int fileType, int* index, void* dataRef ){
    pData data = (pData) dataRef;
    int textureID = 0;
    int i = 0;
    int x = 0;
    int extId = 0;
    pNPtexmap tex = NULL;
    char filename[256] = {'\0'};
    char path[256] = {'\0'};
    char* abs = NULL;
    
    if( filePath[0] != '\0' )
    {
        printf("npLoadTexture filePath : %s\n", filePath);
        i = strlen(filePath);
        while( i > 0 && filePath[i] != '/') {
            i--;
            x++;
        }
        strcpy(filename, &filePath[i+1]);
  //      printf("888888888888888 npLoadTexture2 filename:%s\n", filename);
        tex = npTexlistSearchFile(filename, filePath, dataRef);
        if(tex && tex->intTexId > 0){
    //        printf("9999999 found it\n");
            return tex->intTexId;
        }
      //  tex = npTexlistSearchFile
        /*
        if( npPathIsRel(filePath, dataRef) )
        {
            abs = npFilePathRelToAbs(filePath, dataRef);
            printf("absolute path is %s\n", abs);
            filePath[0] = '\0';
            strcpy(filePath, abs);
            free(abs);
        }
        
        npGetFileNameFromPath( filePath, &filename[0], dataRef);
        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;
        }
         */
    }
    
    /// Determine the format using the file extension.
    if( !fileType )
        fileType = npGetFileTypeCat( NULL, filePath, dataRef );
    
    /// Use SOIL for efficient direct memory DDS file loading.
    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
    {    /// Use FreeImage (addon) for all other (non-DDS) images.
#ifdef NP_ADDON_FREEIMAGE
        textureID = npfiLoadTexture( filePath, data );
#else
        textureID = SOIL_load_OGL_texture ( filePath,
                                           SOIL_LOAD_AUTO,
                                           SOIL_CREATE_NEW_ID,
                                           SOIL_FLAG_INVERT_Y |
                                           SOIL_FLAG_MIPMAPS * kNPglMipmaps );
#endif
    }
    printf("vvvvvv\n");
    // 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];
        (*index) = 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 < 100; i++){
            if(data->io.gl.extMap[i] == 0){
                
            }
        }
        printf("textureCount:%d\n", data->io.gl.textureCount);
        //system("pause");
    }
    else
        printf ("err 4301 - failed to load image: %s\n", filePath);
    
    printf("zzzzz\n");
    return textureID;
}
// lv mac port models stop


/*
/// @todo support sRGBA using GL_EXT_texture_sRGB
//------------------------------------------------------------------------------
/// Load texture maps from default folders into the GPU
void npInitTexMap (void* dataRef)							//zz tex
{
	int i = 0;
	char msg[128];

	pData data = (pData) dataRef;
	pNPtex tex = (pNPtex)&data->io.gl.tex;

#if (!defined(NP_ADDON_FREEIMAGE) && !defined(NP_ADDON_SOIL))
	npPostMsg( "Warn 4303 - No Texture Map Library!!!", kNPmsgFile, data );
	return;
#endif

	/// Tightly pack pixels, used by glReadPixels(), solves issue #232
	/// For discussion, see section 7. Watch Your Pixel Store Alignment' at
	/// https://www.opengl.org/archives/resources/features/KilgardTechniques/oglpitfall/
	glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
	glPixelStorei( GL_PACK_ALIGNMENT, 1);

	/// Get the maximum texture size dimensions supported by GL
	glGetIntegerv( GL_MAX_TEXTURE_SIZE, &tex->maxSize);
	sprintf( msg, "Max Texture Size: %dx%d", tex->maxSize, tex->maxSize);
	npPostMsg( msg, kNPmsgFile, data );
	printf("\n");

	/// Legacy support for loading textures named 'map00001.jpg' first
	npPostMsg( "texture search: usr/images/map*.jpg", kNPmsgFile, data);
	npLoadDir( kNPpathLegacyImages, "map*.jpg", kNPfileCatImage, dataRef );

	/// Load all images from the texture paths list
	for( i=0; i < tex->dirCount; i++)
	{
		sprintf( msg, "texture search: %s", tex->dirPaths[i] );
		npPostMsg( msg, kNPmsgFile, data);
		npLoadDirBranch( tex->dirPaths[i], NULL, kNPfileCatImage, data);
	}

	if( !tex->count )
		npPostMsg( "No textures loaded!!!", kNPmsgFile, data );
	else
	{
		sprintf( msg, "texture count: %d", tex->count ); 
		npPostMsg( msg, kNPmsgFile, data );
	}

	printf("\n");
}
*/

/// @todo support sRGBA using GL_EXT_texture_sRGB
//------------------------------------------------------------------------------
/// Load texture maps from default folders into the GPU
//#define kNPtexListMax 2000
void npInitTexMap (void* dataRef)
{
    pData data = (pData) dataRef;
    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;
    }
    
    npLoadTexturesLegacy(dataRef);
    npLoadTextures(dataRef);
    
    return;
}


//------------------------------------------------------------------------------
/// 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;


	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 // lv mac port commented out
    }
    
	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.jpg", data->io.file.mapPath, timeStamp );

		npGLDrawScene (data);
		
		/// grab the window display buffer and save to file
		err = npfiScreenshot( filePath, kNPfileJPG, 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
#ifdef NP_ADDON_ASSIMP

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);

	fRef = nposNewFileRef( data );

	result = nposFindFirstFile( fRef, "usr/global/models/", "*.*", 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 < 100 || i % 100 == 0 )
			printf( "." );

		//printf("fRef->name : %s\n", fRef->name);
		sprintf(filename, "%s/%s", "usr/global/models/", fRef->name );
		//printf("!!!!!!!-----filename : %s!!!!!!!!-------\n", filename);

		// if Folder (not a file) then recursively call to create dir tree
		if( fRef->isDir )
		{
		//	npLoadTextures( sPath, data );			// recursion
		}
		else
		{
			sprintf(path, "%s%s", data->io.file.appPath, "usr\\global\\models\\");
		//	printf("---------123 path : %s--------\n", path);
			if( ( strcmp(fRef->name, "models-notes.txt") == 0) 
				|| (strcmp(fRef->name, ".DS_Store") == 0) 
				|| (strcmp(fRef->name, "README") == 0)  )
				continue;

		//	printf("\nnpAddGeo(0,0,0, NULL, %s, %s, dataRef)\n", fRef->name, path);
		//	npAddGeo(0,0,0, NULL, fRef->name, path, dataRef);
		//	extTexId = npGetUnusedExtTexId(dataRef);
			
			extTexId = 0;
			npAddGeo(&geoId, &extTexId, 0, &center, &rotate, &scale, NULL, fRef->name, path, dataRef);
			
		}
    }
	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");
	*/
}
#endif

#define kNPextId 1
#define kNPintId 2

// lv mac port models start
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;
}
// lv mac port models stop


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 < 2000; 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)
		{
#ifdef NP_ADDON_ASSIMP
			geo = npSearchGeolistExtTexId(tex->extTexId, dataRef); // lv mac port
#endif
			if(geo)
			{
				filepath[0] = '\0';
				sprintf(filepath, "%s%s", geo->modelPath, tex->filename);
				tex->loaded = 0;
			}

		}
	}
	

	return tex->intTexId;
}

//------------------------------------------------------------------------------
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;
    int index = 0;
    
    //    printf("npUpdateTexMap\n");
    if( data->io.file.loading == true){
        printf("file is loading\n");
        return;
    }
    
    for( i = 1; i < 2000; 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, &index, 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.nodeTexSyncListLength > 0 ){
      //  printf("nodeTexSyncListLength:%d\n", data->io.gl.nodeTexSyncListLength);
    }
    if(data->io.gl.syncTexList == 1 && data->io.file.loading == false){
        printf("time to sync the texlist :: %d\n", data->io.gl.nodeTexSyncListLength);
        //system("pause");
     //   getchar();
        for(i = 1; i <= data->io.gl.nodeTexSyncListLength; i++){
            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);
            printf("nodeTexSyncList[%d] :: %d\n", i, data->io.gl.nodeTexSyncList[i]);
            
            if(!tmpNode){
                printf("invalid node\n");
                continue;
            }
            printf("tmpNode->extTextureId:%d\n", tmpNode->extTextureId);
            printf("data->io.gl.extMapMe[tmpNode->extTextureId] : %p", data->io.gl.extMapMe[tmpNode->extTextureId]);
            if(tmpNode && data->io.gl.extMapMe[tmpNode->extTextureId] != NULL) {
                printf("mapping exists\n");
                if(data->io.gl.extMapMe[tmpNode->extTextureId]->intTexId > 0){
                    tmpNode->textureID = data->io.gl.extMapMe[tmpNode->extTextureId]->intTexId;
                    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 {
                    printf("texture is not loaded\n");
                    data->io.gl.syncTexList = 1;
                    return;
                }
            }
        }
        data->io.gl.nodeTexSyncListLength = 0;
        
        data->io.gl.syncTexList = 0;
    }
    
    return;
}

//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,

