#include "cg_local.h"
#include "cg_vehicles_parser.h"

char *Parser_ParseModel(char *ptr, int *vehiclenum, int *modelnum) {
   int success = -1, i;
   int modelType = -1;
   char *new_ptr;

   new_ptr = ptr;

   //new_ptr = parser_strstr(new_ptr, "model {\n");
	/*
	Com_Printf("**\n");
		for(i = 0; i < MAX_QPATH; i++) {
		Com_Printf("%c", new_ptr[i]);
   }
   Com_Printf("\n**\n");
	*/

   new_ptr = parser_strstr(new_ptr, "model ");

   if(new_ptr) {
      char modelName[MAX_QPATH];

      parser_clear_string(modelName, MAX_QPATH);

		/*
		Com_Printf("*****\n");
		for(i = 0; i < MAX_QPATH; i++) {
			Com_Printf("%c", new_ptr[i]);
		}
		Com_Printf("\n*****\n");
		*/
      
		success = sscanf(new_ptr, "model %s {", modelName);

		if(success) {
         //byte modelType;
			char path[MAX_QPATH], shader[MAX_QPATH], skin[MAX_QPATH];
			int g2radius;
			float scale, offset[3], angles[3];

			// copy the modelType
			modelType = VehicleInfo_GetIndexForModelName(modelName);

			//Com_Printf("name: %s\ntype: %s\n", modelName, VehicleInfo_GetNameForModelType(modelType));

			cg_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].modelType =	VehicleInfo_GetIndexForModelName(modelName);
			
			// copy the model path and register the model
			parser_clear_string(path, MAX_QPATH);
			new_ptr = parser_strstr(new_ptr, "path ");
			success = sscanf(new_ptr, "path %s\n", path);
			if(success) {
				//Com_Printf("path: %s\n", path);
				if(strcmp(path, "none") == 0) {
					cg_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].model = -1;
				} else {
					cg_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].model = trap_R_RegisterModel(path);	
				}
			}

			// copy the skin and register it
			parser_clear_string(skin, MAX_QPATH);
			new_ptr = parser_strstr(new_ptr, "skin ");
			success = sscanf(new_ptr, "skin %s\n", skin);
			if(success) {
				//Com_Printf("skin: %s\n", skin);
				if(strcmp(skin, "none") == 0) {
					cg_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].skin = -1;
				} else {
					cg_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].skin = trap_R_RegisterSkin(skin);	
				}
			}
				
			// copy the shader and register it
			parser_clear_string(shader, MAX_QPATH);
			new_ptr = parser_strstr(new_ptr, "shader ");
			success = sscanf(new_ptr, "shader %s\n", shader);
			if(success) {
				//Com_Printf("shader: %s\n", shader);
				if(strcmp(shader, "none") == 0) {
					cg_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].shader = -1;
				} else {
					cg_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].shader = trap_R_RegisterShader(shader);	
				}
			}

			// read the g2 radius... once within this radius, use g2 for per poly collision
			new_ptr = parser_strstr(new_ptr, "g2radius ");
			success = sscanf(new_ptr, "g2radius %f\n", &g2radius);
			if(success) { 
				cg_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].radius = g2radius;
			}

			// copy the offset... this is used to offset the models origin from the entity's origin
			new_ptr = parser_strstr(new_ptr, "offset ");
			success = sscanf(new_ptr, "offset (%f,%f,%f)\n", &(offset[0]), &(offset[1]), &(offset[2]));
			if(success) { 
				cg_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].offset[0] = offset[0];
				cg_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].offset[1] = offset[1];
				cg_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].offset[2] = offset[2];
			}

			// copy the angles... this is used to rotate the models orientation from the entity's orientation
			new_ptr = parser_strstr(new_ptr, "angles ");
			success = sscanf(new_ptr, "angles (%f,%f,%f)\n", &(angles[0]), &(angles[1]), &(angles[2]));
			if(success) { 
				cg_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].angles[0] = angles[0];
				cg_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].angles[1] = angles[1];
				cg_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].angles[2] = angles[2];
			}

			// copy the scale... this is used to scale the axes, the g2radius, and the offset
			new_ptr = parser_strstr(new_ptr, "scale ");
			success = sscanf(new_ptr, "scale %f\n", &scale);
			if(success) { 
				cg_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].scale = scale;
			}

			//cg_vehicleTemplates[*vehiclenum].vehicleInfo.soundInfo.movesound1 = trap_S_RegisterSound(movesound1);
		}

      return new_ptr;
   }
   return ptr;
}

char *Parser_ParseModels(char *ptr, int *vehiclenum) {
	
	// cockpits still messed...

   int success = -1, i;
   
   char *new_ptr;
   int models = -1;
   
   new_ptr = ptr;

   //new_ptr = strstr(new_ptr, "models");
	new_ptr = parser_strstr(new_ptr, "models ");

   // if the "models #" substring exists, being processing vehicles
   if(new_ptr) {
		
      // read the number of vehicles to expect
      success = sscanf(new_ptr, "models %d {", &models);
      
	//Com_Printf("models: %d\n", models);

      // if the number of vehicles exists and we read it properly
      if(success) {
         //printf("models %d {\n", models);
         
			new_ptr++;
			new_ptr = parser_strstr(new_ptr, "model ");

			//Com_Printf("models: %d\n", models);

			if(models < MAX_VEHICLE_MODELS) {
				// process each model individually
				for(i = 0; i < models; i++) {
					new_ptr = Parser_ParseModel(new_ptr, vehiclenum, &i);
				}
			} else {
				for(i = 0; i < MAX_VEHICLE_MODELS; i++) {
					new_ptr = Parser_ParseModel(new_ptr, vehiclenum, &i);
				}
			}

         return new_ptr;
      }
   }
   return ptr;
}

char *Parser_ParseDisplay(char *ptr, int *vehiclenum) {
   int success = -1, i;
   
   char *new_ptr;

   new_ptr = ptr;

   new_ptr = parser_strstr(new_ptr, "display {");
   //new_ptr = strstr(new_ptr, "display ");

   if(new_ptr) {

		/*
		new_ptr += strlen("display {");
		while((new_ptr == ' ') || (new_ptr == '\0'))
			new_ptr++;
		*/
		
		/*
		Com_Printf("*****\n");
		for(i = 0; i < MAX_QPATH; i++) {
			Com_Printf("%c", new_ptr[i]);
		}
		Com_Printf("\n*****\n");
		*/

		new_ptr = Parser_ParseModels(new_ptr, vehiclenum);
		new_ptr = strstr(new_ptr, "}");

      return new_ptr;
   }
   return ptr;
}

char *Parser_ParseSound(char *ptr, int *vehiclenum) {
   int success = -1, i;
   
   char *new_ptr;

   new_ptr = ptr;

   //new_ptr = parser_strstr(new_ptr, "sound {\n");
   new_ptr = strstr(new_ptr, "sound {\n");

   if(new_ptr) {
      char movesound1[MAX_QPATH], movesound2[MAX_QPATH];

      parser_clear_string(movesound1, MAX_QPATH);
      parser_clear_string(movesound2, MAX_QPATH);
      
      success = sscanf(new_ptr, "movesound1 %s\n", &movesound1);
      if(success)
         cg_vehicleTemplates[*vehiclenum].vehicleInfo.soundInfo.movesound1 = trap_S_RegisterSound(movesound1);

      success = sscanf(new_ptr, "movesound2 %s\n", &movesound2);
      if(success)
         cg_vehicleTemplates[*vehiclenum].vehicleInfo.soundInfo.movesound2 = trap_S_RegisterSound(movesound2);

      return new_ptr;
   }
   return ptr;
}


char *Parser_ParseVehicle(char *ptr, int *vehiclenum) {
   char *new_ptr;
   int success = -1;
   char vehiclename[MAX_QPATH];

   new_ptr = ptr;
   new_ptr = strstr(new_ptr, "vehicle ");
      
   // if the "vehicle #" substring exists...
   if(new_ptr) {
      parser_clear_string(vehiclename, MAX_QPATH);
      // scan the vehicle # from the "vehicle #" substring
      success = sscanf(new_ptr, "vehicle %s {\n", vehiclename);
      
      // process current vehicle
      if(success) {
         char vehicletype[MAX_QPATH];
         parser_clear_string(vehicletype, MAX_QPATH);

         //printf("      vehiclename %d: vehiclename name: %s {\n", *vehiclenum, vehiclename);
         
         // fill the structs
         cg_vehicleTemplates[*vehiclenum].templateNum = *vehiclenum;

         strcpy(cg_vehicleTemplates[*vehiclenum].vehicleInfo.vehicleName, vehiclename);

			Com_Printf("CGAME: PARSED VEHICLE: %s\n", cg_vehicleTemplates[*vehiclenum].vehicleInfo.vehicleName);
 
			// display and sound should be done on client side...
         new_ptr = Parser_ParseDisplay(new_ptr, vehiclenum);
         new_ptr = Parser_ParseSound(new_ptr, vehiclenum);
         
         new_ptr = strstr(new_ptr, "physics {");
         new_ptr = strstr(new_ptr, "}");
         new_ptr = strstr(new_ptr, "}");

         //printf("      }\n");
         return new_ptr;
      }
   }

   return ptr;
}

char *Parser_ParseVehicles(char *ptr) {
   int success = -1, i;
   
   char *new_ptr;
   int vehicles = -1;
   
   new_ptr = ptr;

   new_ptr = strstr(new_ptr, "vehicles");

   // if the "vehicles #" substring exists, being processing vehicles
   if(new_ptr) {

      // read the number of vehicles to expect
      success = sscanf(new_ptr, "vehicles %d {\n", &vehicles);
      
      // if the number of vehicles exists and we read it properly
      if(success) {
         //printf("vehicles %d {\n", vehicles);
         
         // process each level individually
         for(i = 0; i < vehicles; i++) {
            new_ptr = Parser_ParseVehicle(new_ptr, &i);
         }
         //printf("}\n");

         return new_ptr;
      }
   }
   return ptr;
}

int Parser_ParseVehicleInfo(char *filename) {
   int success;

   int file_size = 0;
   fileHandle_t script_file;

   //char *filename = "./scripts/test.classinfo.small";

   // get the file length, reset the file pointer, and allocate a buffer
   file_size = trap_FS_FOpenFile (filename, &script_file, FS_READ);

   // begin parsing
   if(file_size > 0) {
      char *ptr = 0;
      char buffer[10000];
      
      //fseek(script_file, 0L, 0);
      //buffer = malloc(sizeof(char) * file_size + 1);
      //buffer = G_Alloc(sizeof(char) * file_size + 1);

      //printf("file_size: %d\n", file_size);

      // read in the file to the buffer and terminate the buffer
      trap_FS_Read(&buffer, file_size, script_file);
      buffer[sizeof(char) * file_size] = '\0';

      //Com_Printf("%d\n%s\n", file_size, buffer);
      
      // start at the beginning of the buffer
      ptr = buffer;

      // and awaaaayyyyy we go!
      ptr = Parser_ParseVehicles(ptr);

      trap_FS_FCloseFile(script_file);
      //getch();

      //if(buffer)
      //   free(buffer);
      //BG_TempFree(sizeof(char) * file_size + 1);

      return 1;
   }

   return 0;
}