/* -----------------------------------------------------------------------------
*
*  npmodels.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 "npmodels.h"

#include "npassimp.h"
#include "../gl/npgeometry.h"
#include "../gl/nptexmap.h"
#include "../npfile.h"
#include "../../data/npmapfile.h"

#include "../../npdata.h"


int npGeolistFindObjectName(char* objectName, void* dataRef);

/** Inits the Geolist 
	@param dataRef is a global map reference instance.
*/
void npInitModels (void* dataRef)
{
	pNPnode tmp = NULL;

	//npLoadGeos(dataRef); //  lv mac port models
    npLoadGeosOSX(dataRef); // lv mac port models
	//tmp->geometry = 1002;
	return;
}

/** Unloads all the models
	@param dataRef is a global map reference instance.	
*/
void npCloseModels (void* dataRef)
{
	/// @todo npCloseModels
	return;
}

/** Sets the Geolist's length
	@param length to set geolist
	@param dataRef is a global map reference instance.
*/
void npGeolistSetLen(int length, void* dataRef)
{	
	pData data = (pData) dataRef;
	data->io.gl.geoLen = length;
}

int npGeoLessId(int geometryId, void* dataRef)
{
	pData data = (pData) dataRef;
	int x = 0;

    while ( (x = npSearchGeosId(geometryId, dataRef)) == 0 && (geometryId > 20) )
		geometryId--;
	
	printf("x : %d\n", x);


	return geometryId;
}


int npGeoMoreId(int geometryId, void* dataRef)
{
	pData data = (pData) dataRef;
	int x = 0;

	if(geometryId == 20)
	{
		geometryId = 1000;
	}

	if(geometryId < 20)
	{
		return geometryId;
	}

	if( (x = npSearchGeosId(geometryId, dataRef)) != 0 && (geometryId > 20) && (geometryId < kNPgeoMax) )
	{
		return geometryId;
	}
	else if(x == 0)
	{
		while ( (x = npSearchGeosId(geometryId, dataRef)) == 0 && (geometryId > 20) && (geometryId < kNPgeoMax) )
			geometryId++;
	}

/*
    while ( (x = npSearchGeosId(geometryId, dataRef)) == 0 && (geometryId > 20) && (geometryId < 2000) )
		geometryId++;
*/

	if(geometryId == kNPgeoMax)
		return 0;

	printf("x : %d\n", x);


	return geometryId;
}

/*
int npGeoLessId(int geometryId, void* dataRef)
{
	pData data = (pData) dataRef;
	int x = 0;

    while ( (x = npSearchGeosId(geometryId, dataRef)) == 0 && (geometryId > 20) )
		geometryId--;
	
	printf("x : %d\n", x);


	return geometryId;
}
*/

// node->texture = npGeoTexId( node->geometry, dataRef );
int npGeoTexId( int geometryId, void* dataRef )
{
	pData data = (pData) dataRef;
	pNPgeolist geolist = &data->io.gl.geolist[0];
	int i = kNPgeoListMax;
	int geoId = geometryId;
	
	//npSearchGeosId(geometryId, dataRef)
	for(; i > 0; i--)
	{
		geolist = &data->io.gl.geolist[i];
		if(geolist->geometryId == geoId)
		{
			return geolist->textureId;
		//	return npExtTexToIntTexId(geolist->textureId, dataRef);	
		}

			//return geolist->textureId;
	}

	return 0;
}

pNPgeolist npSearchGeolistExtTexId(int extTexId, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPgeolist geo = NULL;
	int i = 0;

	if(extTexId == 0)
		return geo;

	for(i = 1; i < kNPgeoListMax; i++)
	{
		geo = &data->io.gl.geolist[i];
		if(geo->textureId == extTexId)
		{
			return geo;
		}
	}

	geo = NULL;
	return geo; 
}

pNPgeolist npSearchGeolistModelFilePath(char* file, char* path, void* dataRef);
pNPgeolist npSearchGeolistModelFilePath(char* file, char* path, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPgeolist geo = NULL;
	int i = 0;

	for(i = 0; i < kNPgeoListMax; i++)
	{
		geo = &data->io.gl.geolist[i];
		if( (strcmp(geo->modelFile, file) == 0) 
			&& (strcmp(geo->modelPath, path) == 0) )
		{
			return geo;
		}
	}

	return NULL;
}

pNPgeolist npGetUnusedGeo(void* dataRef)
{
	pData data = (pData) dataRef;
	pNPgeolist geolist = NULL;
	pNPgeolist geodef = &data->io.gl.geolist[0];
	int i = 1;

	for(i = 1; i < kNPgeoListMax; i++)
	{
		geolist = &data->io.gl.geolist[i];
		if( 0 == memcmp(geodef, geolist, sizeof(NPgeolist)) )
			return geolist;
	}

	return NULL;
}



int npSearchGeosId(int geoId, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPgeolist geolist = NULL; 
	int i = 1;	

//	if(geoId == 0)
//		geoId++;

	for(; i < kNPgeoListMax; i++)
	{
		geolist = &data->io.gl.geolist[i];	
		if(geolist->geometryId == geoId)
			return geoId;
	}

	return 0;
}

/// return a new GeoId
int npNewGeoId(void* dataRef)
{
	static int geoId = 999;

	geoId++;
	printf("623982901 geo id %d\n", geoId);
	
	return geoId;
}

/// returns the geoCount
/*
int npNewGeoId(int* geoId, void* dataRef);
int npNewGeoId(int* geoId, void* dataRef)
{
	static int geoCount = 0;
	int x = 0;
	if( (*geoId) < 1000)
		(*geoId) = 1000;

	while( (x = npSearchGeosId((*geoId), dataRef) ) != 0 )
		(*geoId)++;

	geoCount++;
	printf("623982901 geo count %d\n", geoCount);
	return geoCount;
}
*/

pNPgeolist npSearchGeolistFile(char* fn, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPgeolist g = NULL;
	int i = 1;

	printf("81 npSearchGeolistFile : %s\n", fn);

	for(i = 1; i < kNPgeoListMax; i++)
	{
		g = &data->io.gl.geolist[i];
		if( strcmp(g->modelFile, fn) == 0 )
		{

			return g;
		}
	}

	return NULL;
}

pNPgeolist npNewGeo(int* geoId, int* extTexId, char* geoname, pNPfloatXYZ center, pNPfloatXYZ rotate, pNPfloatXYZ scale ,char* filename, char* path, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPgeolist geo = NULL;
	pNPgeolist geoA = NULL;
	char fileP[256] = {'\0'};
	int i = 1;

	//npNewGeoId(geoId, dataRef);
	if( (*geoId) == 0)
		(*geoId) = npNewGeoId(dataRef);

	geo = npGetUnusedGeo(dataRef);

	geo->geometryId = (*geoId);

	if((*extTexId) == 0)
	{
		geoA = npSearchGeolistFile(filename, dataRef);

		if(geoA && geoA->textureId > 0)
		{
			printf("33 FOUND IT.....\n");
			geo->textureId = geoA->textureId;
		}
		else
		{
		//	geo->textureId = npGetUnusedExtTexId(dataRef);
		//	geo->textureId = 0;
			/*
			sprintf(fileP, "%s%s", path, filename);
			geo->textureId = npLoadTexture(fileP, 0, dataRef);
			printf("32 npNewGeo textureId : %d", geo->textureId);
			*/
		}
	}
	else
	{
		for( i = 1; i < kNPgeoMax; i++)
		{
			if( data->io.gl.texmap[i].extTexId == 0 )
				break;
		}

		data->io.gl.texmap[i].extTexId = (*extTexId);

		geo->textureId = (*extTexId); // todo check if extTexId already used
	}

	strcpy(geo->modelFile, filename);
	strcpy(geo->modelPath, path);

	if(geoname != NULL)
		strcpy(geo->name, geoname);
	else
		strcpy(geo->name, "");

	geo->loaded = 0;
	geo->modelId = 0;
	geo->modelTextureFile[0] = '\0';
	geo->modelTexturePath[0] = '\0';

	if(center && rotate && scale)
	{
		geo->center.x = center->x;
		geo->center.y = center->y;
		geo->center.z = center->z;

		geo->rotate.x = rotate->x;
		geo->rotate.y = rotate->y;
		geo->rotate.z = rotate->z;
	
		geo->scale.x = scale->x;
		geo->scale.y = scale->y;
		geo->scale.z = scale->z;
	}

	return geo;
}

// geometryId
int npGeoUsedId(int geoId, void* dataRef);
int npGeoUsedId(int geoId, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPgeolist geolist = NULL;
	int i = 1;

	for(i = 1; i < kNPgeoListMax; i++)
	{
		geolist = &data->io.gl.geolist[i];
		if(geolist->geometryId == geoId)
			return i;
	}

	return 0;
}


pNPgeolist npGeoFind(int geoId, int extTexId, int type, char* objName, char* file, char* path, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPgeolist g = &data->io.gl.geolist[0];
	int i = 1;
	
	for( i = 1; i < kNPgeoListMax; i++)
	{
		if( (g[i].geometryId == geoId) && (g[i].textureId == extTexId) && (strcmp(g[i].modelFile, file) == 0) && ( strcmp(g[i].modelPath, path) == 0))
			return &g[i];
	}

	return NULL;
}

int npPathIsRel(char* path, void* dataRef)
{
	char t[256] = {'\0'};
	strcpy(t, path);
	t[0] = tolower(t[0]);
	if(t[0] >= 'a' && t[0] <= 'z' && t[1] == ':' && t[2] == '\\')
		return 0;

	return 1;
}




int npExtTexToIntTexId(int extTexId, void* dataRef)
{
	pData data = (pData) dataRef;
//	pNPgeolist geolist = &data->io.gl.geolist[0];
	pNPtexmap texmap = &data->io.gl.texmap[0];
	int i = 0;

	if(extTexId == 0)
	{
		printf("no ext tex\n");
		return 0;
	}
	
	/// kNPtexListMax 2000
	for(i = 1; i < kNPtexMax; i++)
	{
		texmap = &data->io.gl.texmap[i];
		if(texmap->extTexId == extTexId)
		{
			printf("---int %d to ext %d---\n", texmap->intTexId, extTexId);
			printf("---%s%s---\n", texmap->path, texmap->filename);
			return texmap->intTexId;
		}
	}

	return 0;
}


int npIntTexToExtTexId(int intTexId, void* dataRef)
{
	pData data = (pData) dataRef;
//	pNPgeolist geolist = &data->io.gl.geolist[0];
	pNPtexmap texmap = &data->io.gl.texmap[0];
	int i = 0;

//	printf("npIntTexToExtTexId\n");
	/// kNPtexListMax 2000
	for(i = 1; i < kNPtexMax; i++)
	{
		texmap = &data->io.gl.texmap[i];
		if(texmap->intTexId == intTexId)
		{
//			printf("---int %d to ext %d---\n", intTexId, texmap->extTexId);
//			printf("---%s %s---\n", texmap->path, texmap->filename);
			return texmap->extTexId;
		}
	}

	return 0;
}

int npNewModelId(int* geoId, void* dataRef);
int npNewModelId(int* geoId, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPgeolist geolist = &data->io.gl.geolist[0];
	int i = 0;
	int x = 0;
	
	while( (x = npSearchGeosId((*geoId), dataRef)) != (*geoId) )
		(*geoId)++;

	if( x >= 1000 )
		return (*geoId)-999;

	return 0;
}

int npLoadModel(pNPgeolist geo, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPassimp assimp = (pNPassimp)data->io.assimp;
	pNPgeolist geolist = &data->io.gl.geolist[0];
	pNPgeolist geoMatch = NULL;
	pNPtexmap tex = NULL;
	char filePath[256] = {'\0'};
	char fileName[256] = {'\0'};
	char path[256] = {'\0'};
	char* absModelPath = NULL;
	char texfp[256] = {'\0'};
	int modelId = 0;
	int i = 0;
	int geolistIndexMatch = 0;
	int fLen = 0;
	
	filePath[0] = '\0';

//	absModelPath = npFilePathRelToAbs(geo->modelPath, dataRef);

	if( npPathIsRel(geo->modelPath, dataRef) )
	{
		absModelPath = npFilePathRelToAbs(geo->modelPath, dataRef);
		geo->modelPath[0] = '\0';
		strcpy(geo->modelPath, absModelPath);
		free(absModelPath);
	}
    
	filePath[0] = '\0';
	sprintf(filePath, "%s%s", geo->modelPath, geo->modelFile);
	modelId = npNewModelId(&geo->geometryId, dataRef);
	assimp->scene[modelId] = npModelImport(filePath, dataRef);
	if(assimp->scene[modelId] == NULL)
	{
		geo->geometryId = 0;
		geo->loaded = 0;
		return 0;
	}

//	assimp->path = npAssimpGetTexturePath(modelId, dataRef); // lv mac port models
	npGetFileNameFromPath(&assimp->path.data[0], fileName, dataRef);
	strcpy(path, filePath);
	path[strlen(filePath) - strlen(geo->modelFile)] = '\0';
//	printf("---------path : %s-------\n", path);
	geo->modelTextureFile[0] = '\0';
	geo->modelTexturePath[0] = '\0';
	strcpy(geo->modelTextureFile, fileName);
	strcpy(geo->modelTexturePath, path);
	tex = npTexlistSearchFile(geo->modelTextureFile, geo->modelTexturePath, dataRef);
	if(tex)
	{
		printf("-=-=-=-=-=-=- geo test npTexlistSearchFile -=-=-=-=-=\n");
		sprintf(texfp, "%s%s", geo->modelTexturePath, geo->modelTextureFile);
		//return modelId;
	}


	fLen = strlen(fileName);

	for(i = 0; i < fLen; i++)
	{
		fileName[i] = tolower(fileName[i]);
	}

	if(tex == NULL)
	{
		path[0] = '\0';
		assimp->path.data[0] = '\0';
	}
	else
	{
        if(tex->intTexId == 0){
		//	geo->textureId = npLoadTexture2(texfp, 0, dataRef); // lv mac port, npLoadTexture2
        }
		else
			geo->textureId = tex->intTexId;

	}
	
	return modelId;
}

/// @todo pNPgeolist npGeolistGetGeo(int geometryId, void* dataRef)

int npGeoNull(void)
{
	return 0;
}

void npSetSelectedNodeGeoId(int* geoId, void* dataRef )
{
	npSetSelectedNodes( kNPgeometry, geoId, dataRef );
}

/** Increments the geolist length
	@param dataRef is a global map reference instance.
	@return the geolist length
*/
int npGeolistIncLen(void* dataRef)
{
	pData data = (pData) dataRef;	
	return (data->io.gl.geoLen++);	
}

/** Increments the geolist index 
	@param dataRef is a global map reference instance.
*/
void npGeolistIncX(void* dataRef)
{	
	pData data = (pData) dataRef;
	data->io.gl.geoX++;
}

/** Sets the geolist index 
	@param X is geolist index
	@param dataRef is a global map reference instance.
*/
void npGeolistSetX(int X, void* dataRef)
{	
	pData data = (pData) dataRef;
	data->io.gl.geoX = X;
}

/** Gets the geolist index
	@param dataRef is a global map reference instance.
	@return the geolist index
*/
int	npGeolistGetX(void* dataRef) 
{
	pData data = (pData) dataRef;
	return data->io.gl.geoX;
}

/** Gets the geolist lock status
	@param dataRef is a global map reference instance.
	@return geolock status as boolean (true/false)
*/
bool npGeolistLockStatus(void* dataRef)
{
	pData data = (pData) dataRef;
	return data->io.gl.geoLock;
}

pNPgeo npGeoInit(void* dataRef);
pNPgeo npGeoInit(void* dataRef)
{
	pNPgeo geo = NULL;
	geo = malloc(sizeof(NPgeo));
	return geo;
}

//curs = npTextureNewTypeB( curs, &type, extId, dataRef );
char* npTextureNewTypeB(char* idVal, int* type, int extId, void* dataRef);
char* npTextureNewTypeB(char* idVal, int* type, int extId, void* dataRef)
{
	pData data = (pData) dataRef;

	(*type) = npstrtoi(&idVal);
	return idVal;
}

char* npTextureNewType(char* idVal, int* type, int i, void* dataRef);
char* npTextureNewType(char* idVal, int* type, int i, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPtexmap tex = &data->io.gl.texmap[i];
	tex->type = (*type) = npstrtoi(&idVal);
//	pNPtexmap tex =
//	(*type) = npstrtoi(&idVal);
	

	return idVal; 
}

/// @todo lv new func
char* npTextureNewId(char* idVal, int* id, void* dataRef);
char* npTextureNewId(char* idVal, int* id, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPtexmap tex = NULL;
	static int i = 0;
	i++;

	(*id) = npstrtoi(&idVal);
	tex = &data->io.gl.texmap[i];
	tex->extTexId = (*id);
	printf("222 npTextureNewId : %d\n", tex->extTexId);
	//extMap[i] = (*id);
	data->io.gl.extMap[i] = (*id);
	
	printf("333 || extMap ind %d -> %d\n", i, (*id));

	tex->filename[0] = '\0';
	tex->path[0] = '\0';
//	(*id) = i;
	/// tex count++;

	return idVal;

}

char* npTextureNewExtId(char* idVal, int* extId, void* dataRef);
char* npTextureNewExtId(char* idVal, int* extId, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPtexmap tex = NULL;
	pNPgeolist geo = NULL;
	int i = 1;
	int oldId = 0;
	int tempId = 0;

	(*extId) = npstrtoi(&idVal);
	printf("Ext Id is %d\n", (*extId));
	return idVal;
}

char* npTextureNewFilenameB(char* stringVal, int maxSize, char* fileName, int extId, void* dataRef);
char* npTextureNewFilenameB(char* stringVal, int maxSize, char* fileName, int extId, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPtexmap tex = NULL;
	char* curs = stringVal;
	char** read = NULL;
	int strLength = 0;
	int match = 0;
	//int i = 0;
	char* ext = NULL;
//	strLength = maxSize - (curs - *read);
	strLength = maxSize;

	printf("npTextureNewFilenameB :: extId is %d\n", extId); 
	//system("pause");
	/*
	if (strLength >= kNPmodelFileName)
		strLength = kNPmodelFileName;
	*/
	if (strLength >= 200 )
		strLength = 200;
	
	fileName[0] = '\0';

	npCSVstrncpy(fileName, &curs, strLength);

	ext = strstr(fileName, ".");
	if( ext == NULL )
	{
		// texture file has no extension, cannot load
		printf("texture file has no extension, cannot load\n");
	}

	return curs;
}

char* npTextureNewFilePathB(char* stringVal, int maxSize, char* filePath, int extId, void* dataRef);
char* npTextureNewFilePathB(char* stringVal, int maxSize, char* filePath, int extId, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPtexmap tex = NULL;
	char path[256] = {'\0'};
	char* curs = stringVal;
	char** read = NULL;
	char* dslash = NULL;
	char* abs = NULL;
	int strLength = 0;
	int len = 0;
	int i = 0;
	int count = 0;
//	strLength = maxSize - (curs - *read);
	strLength = maxSize;
	/*
	if (strLength >= kNPmodelFilePath)
		strLength = kNPmodelFilePath;
	*/
	if (strLength >= 200 )
		strLength = 200;
	
	filePath[0] = '\0';

//	npCSVstrncpy(path, &curs, strLength);
	npCSVstrncpy(filePath, &curs, strLength);

	return curs;
}

void npTextureNew(char* tex_csvline, void* dataRef)
{	
	pData data = (pData) dataRef;
	pNPtexmap tex = NULL;
	pNPgeo geo = NULL;
	char* curs = tex_csvline;
	char* abs = NULL;
	char objectName[256] = {'\0'};
	char fileName[256] = {'\0'};
	char filePath[256] = {'\0'};
	int geometryId = 0;
	int textureId = 0;
//	int typeId = 0;
	int i = 0;
	int extId = 0;
	int type = 0;
	int index = 0;

	printf("99 npTextureNew\n");
	curs = npTextureNewExtId( curs, &extId, dataRef );
	printf("extId is %d\n", extId);
	//system("pause");
	curs = npTextureNewTypeB( curs, &type, extId, dataRef );
	curs = npTextureNewFilenameB( curs, 200, &fileName[0], extId, dataRef );
	strcpy(filePath, "usr/global/images/");
//	curs = npTextureNewFilePathB( curs, 200, &filePath[0], extId, dataRef ); // lv mac port
	printf("99 npTextureNew CLOSE\n");
	
	// Search the texlist for the filename and filepath pair (right now we'll ignore the path)

	for(i = 0; i < 2000; i++){
		tex = &data->io.gl.texmap[i];
		if( tex->filename[0] != '\0' && strcmp(tex->filename, fileName) == 0){
            printf("Found a match for index:%d with extId:%d\n", i, extId);
			data->io.gl.extMapMe[extId] = tex;
            printf("data->io.gl.extMapMe[%d]:%p\n", extId, tex);
          //  getchar();
			return;
		}
	}

	if( data->io.gl.extMapMe[extId] == NULL ){
		// if the external texture id is not already in the extMapMe
		data->io.gl.texmapCount++;
		printf("texmap count : %d\n", data->io.gl.texmapCount);
		tex = &data->io.gl.texmap[data->io.gl.texmapCount];
		data->io.gl.extMapMe[extId] = tex;
		tex->extTexId = extId;
		//tex->loaded = 0;
	} else {
		// if the external texture id is already in the extMapMe
	//	printf("777777777777777 The External Texture id is already in the extMapMe\n");
		//system("pause");
	}
	
	strcpy(data->io.gl.extMapMe[extId]->filename, fileName); // lv mac port
	strcpy(data->io.gl.extMapMe[extId]->path, filePath);	 // lv mac port

	return;
}

char* npModelNewCenter(char* curs, float* x, float* y, float* z, void* dataRef);
char* npModelNewCenter(char* curs, float* x, float* y, float* z, void* dataRef)
{
//	pNPgeolist geolist = npGetGeolist(dataRef);
	pNPgeolist geolist = NULL;

	//(*geoId) = npstrtoi(&idVal); // lv, if letter, returns 0
	(*x) = npstrtof(&curs);
	(*y) = npstrtof(&curs);
	(*z) = npstrtof(&curs);

	return curs;
}

pNPgeo npModelNew(char* model_csvline, void* dataRef)
{	
	pData data = (pData) dataRef;
	pNPgeo geo = NULL;
//	char* curs = &model_csvline;
	char* curs = model_csvline;
	char* foundPath = NULL;
	char objectName[256] = {'\0'};
	char fileName[256] = {'\0'};
	char filePath[256] = {'\0'};
	int geometryId = 0;
	int textureId = 0;
	int intId = 0;
	int typeId = 0;
//	int cx,cy,cz = 0;
//	int rx,ry,rz = 0;
//	int sx,sy,sz = 0;
	int i = 0;
	int x = 0;
	NPfloatXYZ center;
	NPfloatXYZ rotate;
	NPfloatXYZ scale;

	printf("339 npModelNew\n");

	printf("npModelNewGeoId\n");
	curs = npModelNewGeoId( curs, &geometryId, &x, dataRef );
//	i = geometryId-999;

	printf("npModelNewTextureId :: geoId is %d\n", geometryId);
	//system("pause");
	curs = npModelNewTextureId( curs, &textureId, x, dataRef ); // lv, temp

	printf("npModelNewTypeId\n");
	curs = npModelNewTypeId( curs, &typeId, dataRef );
	
	curs = npModelNewCenter( curs, &center.x, &center.y, &center.z, dataRef);
	curs = npModelNewCenter( curs, &rotate.x, &rotate.y, &rotate.z, dataRef);
	curs = npModelNewCenter( curs, &scale.x,  &scale.y,  &scale.z,  dataRef);

	curs = npModelNewObjectName(curs, 200, &objectName[0], dataRef);
	curs =  npModelNewFileName(curs, 200, &fileName[0], x, dataRef);
	printf("fileName::%s\n", fileName);
	curs = npModelNewFilePath(curs, 200, &filePath[0], x, dataRef); 

	// Search the geolist for the filename and filepath pair (right now we'll ignore the path)
	for(i = 0; i < 2000; i++){
		geo = &data->io.gl.geolist[i];
		if( strcmp(geo->modelFile, fileName) == 0 ){
			printf("npModelNew :: found match\n");
			data->io.gl.extGeoMap[geometryId] = geo;
			//system("pause");
			return geo;
		}
	}


	
	if( data->io.gl.extGeoMap[geometryId] != NULL ) {
		///< @todo in the case that the external geometry id is already in use
		printf("the external geometry id is already in use\n");
		return data->io.gl.extGeoMap[geometryId];
		//return idVal;
	}
	else {
		// in the case that the external geometry id is not already in use
		data->io.gl.geoLen++; 
		printf("geoLen:%d\n", data->io.gl.geoLen);
		geo = &data->io.gl.geolist[data->io.gl.geoLen];
		printf("yyy :: %p\n", geo);
		data->io.gl.extGeoMap[geometryId] = geo; ///< @todo in the case that geoLen exceeds kNPgeolistMax
		printf("other ptr: %p\n", (data->io.gl.extGeoMap[geometryId]));
		//system("pause");
	//	geo->loaded = 0;
		geo->geometryId = npNewGeoId(dataRef);
		x = geometryId;
	}
	

	if( data->io.gl.extMapMe[textureId] != NULL){
		// the entry is there
		//geo->extTextureId = (*textureId);
		if(data->io.gl.extGeoMap[geometryId] != NULL){
			data->io.gl.extGeoMap[geometryId]->extTextureId = textureId;
			geo = data->io.gl.extGeoMap[geometryId];
		//	printf("geometryId:%d has external textureId of %d\n", geo->geometryId, geo->extTextureId);
			printf("extGeoMap geometryId:%d has external textureId of %d\n", geo->geometryId, geo->extTextureId);
			//system("pause");
		}
	}
		geo = data->io.gl.extGeoMap[geometryId];
		strcpy(geo->modelFile, fileName);

	/*
	void npModelNewCSR(int* cx, int* cy, int* cz, int* rx, int* ry, int* rz, int* sx, int* sy, int* sz, void* dataRef)
		npModelNewXYZ(kNPcenter, cx, cy, cz, dataRef);
		npModelNewXYZ(kNPscale, sx, sy, sz, dataRef);
		npModelNewXYZ(kNProtate, rx, ry, rz, dataRef);

	npModelNewXYZ(int type, int* x, int* y, int* z, void* dataRef);
	{
		switch(type)
		{
			case:kNPcenter
				npModelNewCenter(char* curs, int* x, int* y, int* z, void* dataRef);
				break;
			case:kNPscale
				npModelNewScale(char* curs, int* x, int* y, int* z, void* dataRef);
				break;
			case:kNProtate
				npModelNewRotate(char* curs, int* x, int* y, int* z, void* dataRef);
				break;
			npModelNewRotate(char* curs, int* x, int* y, int* z, void* dataRef);
		}
	}


	*/

	if(filePath[0] == '\0')
	{
		foundPath = npSearchPathsForFile(fileName, dataRef);
		if(foundPath[0] != '\0')
		{
			foundPath[strlen(foundPath)-strlen(fileName)] = '\0';
			strcpy(filePath, foundPath);
		}
	}
	
	return geo;
}




char* npModelNewFilePath(char* stringVal, int maxSize, char* filePath, int i, void* dataRef)
{
	pData data = (pData) dataRef;
//	pNPgeolist geo = &data->io.gl.geolist[i];
	char* curs = stringVal;
	char** read = NULL;
	char* abs = NULL;
	int strLength = 0;
	int len = 0;
//	int i = 0;
//	strLength = maxSize - (curs - *read);
	strLength = maxSize;
	/*
	if (strLength >= kNPmodelFilePath)
		strLength = kNPmodelFilePath;
	*/
	if (strLength >= 200 )
		strLength = 200;
	
	filePath[0] = '\0';

	npCSVstrncpy(filePath, &curs, strLength);
//	strcpy(geo->modelPath, filePath);

	i = len = strlen(filePath);
	
	if(filePath[strlen(filePath)-1] != '\\' && len > 0)
	{
		filePath[strlen(filePath)+1] = '\0';
		filePath[strlen(filePath)] = '\\';
	}
/*
	if(len == 0)
		return curs;
*/		
	//npFilePathIsRel(filePath, dataRef);
	if( npPathIsRel(filePath, dataRef))
	{
		abs = npFilePathRelToAbs(filePath, dataRef);
		filePath[0] = '\0';
		strcpy(filePath, abs);
		free(abs);
//		strcpy(filePath,
	}

	return curs;
}




char* npModelNewFileName(char* stringVal, int maxSize, char* fileName, int i, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPgeolist geo = &data->io.gl.geolist[i];
	char* curs = stringVal;
	char** read = NULL;
	int strLength = 0;
	int match = 0;
//	int i = 0;
	char* ext = NULL;
//	strLength = maxSize - (curs - *read);
	strLength = maxSize;
	/*
	if (strLength >= kNPmodelFileName)
		strLength = kNPmodelFileName;
	*/
	if (strLength >= 200 )
		strLength = 200;
	
	fileName[0] = '\0';

	npCSVstrncpy(fileName, &curs, strLength);
//	strcpy(geo->modelFile, fileName);

	ext = strstr(fileName, ".");
	if( ext == NULL )
	{
		// model file has no extension, cannot load
		printf("model file has no extension, cannot load\n");
/// @todo geolist[geoId].loadModel = false;	
	}
	
	return curs;
}

char* npModelNewObjectName(char* stringVal, int maxSize, char* objectName, void* dataRef)
{
//	char* objectName = NULL;
	char* curs = stringVal;
	char** read = NULL;
	int strLength = 0;
	int match = 0;
//	strLength = maxSize - (curs - *read);
	strLength = 200;

	if (strLength >= 200 )
		strLength = 200;
	
	objectName[0] = '\0';

	npCSVstrncpy(objectName, &curs, maxSize);

	if( objectName[0] == '\0' )
	{
		/// @todo: get objectName from model file
	}
	
	match = npGeolistFindObjectName(objectName, dataRef);

	return curs;
}

//curs = npModelNewTypeId(curs, &typeId, dataRef);
char* npModelNewTypeId(char* csv_typeId, int* typeId, void* dataRef)
{
	(*typeId) = npstrtoi(&csv_typeId);	
	return csv_typeId;
}

char* npModelNewTextureId(char* idVal, int* textureId, int i, void* dataRef)
{
	pData data = (pData) dataRef;
	//pNPgeolist geo = &data->io.gl.geolist[i]; // i ??
	pNPgeolist geo = NULL;
	pNPtexmap tex = NULL;
	int x = 1;

	printf("82934 npModelNewTextureId\n");

	(*textureId) = npstrtoi(&idVal);
	return idVal;
}

//	npGeolistFindObjectName(objectName, dataRef);
/// returns geoId
int npGeolistFindObjectName(char* objectName, void* dataRef)
{
	pData data = (pData) dataRef;
//	pNPgeolist geolist = npGetGeolist(dataRef);
	pNPgeolist geolist = NULL;
	pNPgeo geo = NULL;
	int i = 0;

	if( objectName[0] == '\0')
		return 0;

//	data->io.gl.nameMatch = 0;
	for(i = kNPgeoMax / 2; i < kNPgeoMax; i++)
	{
		geo = &geolist[i];	
		if( geo->name[0] != '\0' )
		{
			if( strcmp( objectName, geo->name ) == 0 )
			{	// Identical
			//	data->io.gl.nameMatch = i;
				return i; //return geo->geometryId
			}
			
		}
	}

	return 0;
}

char* npModelNewGeoId(char* idVal, int* geoId, int* x, void* dataRef)
{
	pData data = (pData) dataRef;
	pNPgeolist geo = NULL;
	int match = 0;
	int count = 0;

	(*geoId) = npstrtoi(&idVal);
	return idVal;
}

// lv mac port start
void npUpdateGeoList( void* dataRef )
{
	pData data = (pData) dataRef;
	pNPassimp assimp = (pNPassimp)data->io.assimp;
	struct aiString aiPathStr;
	pNPgeolist geolist = NULL;
	pNPnode tmpNode = NULL; // lv mac port models start
	int i = 0;
	int x = 0;
	int modelId = 0;
	char* texFilename = NULL;
	char fullPath[1024] = {'\0'};

	for(; i < kNPgeoListMax; i++)
	{
		geolist = &data->io.gl.geolist[i];
		if( (geolist->geometryId != 0) && (geolist->loaded == 0) )
		{
			
			printf("\n");
			printf("geolist->geometryId : %d\n", geolist->geometryId);
			printf("geolist->modelFile : %s\n", geolist->modelFile);
			printf("geolist->modelPath : %s\n", geolist->modelPath);
			printf("i:%d\n", i);
			printf("\n");
			//system("pause");

			modelId = npLoadModel(geolist, dataRef);
			if(modelId)
			{
				npModelStoreDL(assimp->scene[modelId], geolist, dataRef);
				// lv mac port models start
				
					aiPathStr = npAssimpGetTexturePath2(assimp->scene[modelId], dataRef);
					printf("aiPathStr:%s\n", aiPathStr.data);
					//system("pause");
					x = strlen(aiPathStr.data);
					while(aiPathStr.data[x] != '/' && x >= 0){
						x--;
					}
					x++;
					texFilename = malloc(sizeof(char) * ( strlen(aiPathStr.data) - x ) );
					if(!texFilename){
						printf("Could not allocate space to store texFilename\n");
						system("pause");
						return;
					}
					memset(texFilename, '\0', sizeof(char) * (strlen(aiPathStr.data) - x) );
					strncpy(texFilename, &aiPathStr.data[x], (strlen(aiPathStr.data) - (x-1)));
					printf("texFilename:%s\n", texFilename);
					sprintf(fullPath, "usr/global/images/%s", texFilename); //images2
				//	geolist->textureId = npLoadTexture2(fullPath, 0, dataRef); // lv mac port, npLoadTexture2
					free(texFilename);
					x = 0;
				
				geolist->loaded = 1;
			//	data->io.gl.syncGeoList = 1;
				data->io.gl.numModels++;
				// lv mac port models stop
			}
			else
			{
				/// can't load
				geolist->loaded = 0;
				data->io.gl.numModels--;
			}
		}
	}

	// lv mac port models start
	if(data->io.gl.syncGeoList == 1 && data->io.file.loading == false){
		// time to sync the geolist
        //printf("time to sync the geolist\n");
	
		for(i = 1; i <= data->io.gl.nodeGeoSyncListLength; i++){
			printf("node id : %d\n", data->io.gl.nodeGeoSyncList[i]);
			tmpNode = npGetNodeByID( data->io.gl.nodeGeoSyncList[i], dataRef );
			
		//	printf("%p\n", data->io.gl.extGeoMap[tmpNode->extGeoId]);
			if(tmpNode && data->io.gl.extGeoMap[tmpNode->extGeoId] != NULL && data->io.gl.extGeoMap[tmpNode->extGeoId]->loaded == 1 ){
				tmpNode->geometry = data->io.gl.extGeoMap[tmpNode->extGeoId]->geometryId;
				if(tmpNode->geometry >= 1000 && tmpNode->geometry < 2000){
				//	tmpNode->textureID = data->io.gl.geolist[tmpNode->geometry - 999].textureId; // lv mac port models texture hotfix
					printf("transform to geometryId %d\n", data->io.gl.extGeoMap[tmpNode->extGeoId]->geometryId);
					data->io.gl.nodeGeoSyncList[i] = 0;
				}
				
			}
		}
	
		data->io.gl.nodeGeoSyncListLength = 0;
		data->io.gl.syncGeoList = 0;
		//data->io.gl.syncTexList = 1;
	}
	
	// lv mac port models stop

	return;
}
// lv mac port stop

/** Imports an assimp scene from a file
	@param filePath, full path to file
	@param dataRef is a global map reference instance.
*/
struct aiScene* npModelImport(char* filePath, void* dataRef)
{
	struct aiScene* scene = NULL;
	printf("npModelImport\n");
	scene = (struct aiScene*) aiImportFile( filePath, 0);
	printf("after aiImportFile\n");
	if( scene == NULL )
		printf("err 4088 - aiImportFile returned null :: %s\n", filePath);

	return scene;
}


