#include "ui_vehicles_parser.h"


char *Parser_ParseStats(char *ptr, int *vehiclenum) {
	// dont actually process any of the info...
   int success = -1, i;
   
   char *new_ptr;

   new_ptr = ptr;

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

   // if we found the "weapons #" substring
   if(new_ptr) {
      //printf("        starting weapons for vehicle... \n");
      
      new_ptr = parser_strstr(new_ptr, "health ");
		new_ptr = parser_strstr(new_ptr, "armor ");
		new_ptr = strstr(new_ptr, "}\n");

      return new_ptr;
   }
   return ptr;
}

char *Parser_ParseWeapon(char *ptr, int *weaponnum, int *vehiclenum) {
	// dont actually process any of this info...
   int success = -1;
   char *new_ptr;

   new_ptr = ptr;

   new_ptr = parser_strstr(new_ptr, "weapon ");
	new_ptr++;

   if(new_ptr) {
      return new_ptr;
   }
   
   return ptr;
}

char *Parser_ParseWeapons(char *ptr, int *vehiclenum) {
	// dont actually process any of this info
   int success = -1, i;
   
   char *new_ptr;
   int weapons = -1;

   new_ptr = ptr;

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

   // if we found the "weapons #" substring
   if(new_ptr) {
      //printf("        starting weapons for vehicle... \n");
      
      // read the number of classes from the current "weapons #" substring
      success = sscanf(new_ptr, "weapons %d {\n", &weapons);

      // if we read the number of weapons successfully
      if(success) {
         // parse items
         //printf("        weapons %d {\n", weapons);
         
         for(i = 0; i < weapons; i++) {
            new_ptr = Parser_ParseWeapon(new_ptr, &i, vehiclenum);
            
            // force it to the next line...
            // should fix this...
            //new_ptr++;
         }
         
         //printf("        }\n");

			new_ptr = strstr(new_ptr, "}");
			new_ptr++;

         return new_ptr;
      }
   }
   return ptr;
}

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

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

			ui_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 = 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) {
					ui_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].model = -1;
				} else {
					ui_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 = 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) {
					ui_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].skin = -1;
				} else {
					ui_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 = 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) {
					ui_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].shader = -1;
				} else {
					ui_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].shader = trap_R_RegisterShaderNoMip(shader);	
				}
			}

			// read the g2 radius... once within this radius, use g2 for per poly collision
			new_ptr = strstr(new_ptr, "g2radius ");
			success = sscanf(new_ptr, "g2radius %f\n", &g2radius);
			if(success) { 
				ui_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 = strstr(new_ptr, "offset ");
			success = sscanf(new_ptr, "offset (%f,%f,%f)\n", &(offset[0]), &(offset[1]), &(offset[2]));
			if(success) { 
				//Com_Printf("offset: (%f %f %f)\n", offset[0], offset[1], offset[2]);
				ui_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].offset[0] = offset[0];
				ui_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].offset[1] = offset[1];
				ui_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 = strstr(new_ptr, "angles ");
			success = sscanf(new_ptr, "angles (%f,%f,%f)\n", &(angles[0]), &(angles[1]), &(angles[2]));
			if(success) { 
				//Com_Printf("angles: (%f %f %f)\n", angles[0], angles[1], angles[2]);
				ui_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].angles[0] = angles[0];
				ui_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].angles[1] = angles[1];
				ui_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) { 
				//Com_Printf("scale: %f\n", scale);
				ui_vehicleTemplates[*vehiclenum].vehicleInfo.displayInfo.models[modelType].scale = scale;
			}

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

      return new_ptr;
   }
   return ptr;
}

char *Parser_ParseModels(char *ptr, int *vehiclenum) {
	// dont actually process any of the info here...
	//  just parse it to skip it correctly
   int success = -1, i;
   
   char *new_ptr;
   int models = -1;
   
   new_ptr = ptr;

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

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

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

      // read the number of vehicles to expect
      success = sscanf(new_ptr, "models %d {\n", &models);
      
      // if the number of vehicles exists and we read it properly
      if(success) {
         //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);
				}
			}

			new_ptr = strstr(new_ptr, "}");
			new_ptr++;

         return new_ptr;
      }
   }
   return ptr;
}

char *Parser_ParseDisplay(char *ptr, int *vehiclenum) {
	// dont actually process any of the info here... 
	//  just parse it to properly skip it
   int success = -1, i;
   
   char *new_ptr;

   new_ptr = ptr;

   new_ptr = parser_strstr(new_ptr, "display ");

   if(new_ptr) {

		new_ptr = Parser_ParseModels(new_ptr, vehiclenum);
		
		new_ptr = parser_strstr(new_ptr, "}");
		new_ptr++;

      return new_ptr;
   }
   return ptr;
}

char *Parser_ParseSound(char *ptr, int *vehiclenum) {
	// dont actually process any of this info...
	//  just parse it to properly skip it
   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) {
      new_ptr = strstr(new_ptr, "movesound1");
		new_ptr = strstr(new_ptr, "movesound2");

      return new_ptr;
   }
   return ptr;
}

char *Parser_ParsePhysics(char *ptr, int *vehiclenum) {
	// dont actually process any of this info...
   int success = -1, i;
   
   char *new_ptr;

   new_ptr = ptr;

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

   if(new_ptr) {
      new_ptr = strstr(new_ptr, "type ");
      new_ptr = strstr(new_ptr, "width ");
      new_ptr = strstr(new_ptr, "height ");
      new_ptr = strstr(new_ptr, "maxspeed ");
      
		new_ptr = strstr(new_ptr, "}\n");
		new_ptr++;

      return new_ptr;
   }
   return ptr;
}

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

	int i = 0;

   new_ptr = ptr;
   new_ptr = strstr(new_ptr, "vehicle ");
      
   // if the "vehicle #" substring exists...
   if(new_ptr) {
      ui_vehicleTemplates[*vehiclenum].templateNum = *vehiclenum;

      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

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

			Com_Printf("UI: PARSED VEHICLE: %s\n", ui_vehicleTemplates[*vehiclenum].vehicleInfo.vehicleName);

         // scan the type
			new_ptr = strstr(new_ptr, "type ");
         success = sscanf(new_ptr, "type %s {\n", vehicletype);
         ui_vehicleTemplates[*vehiclenum].vehicleInfo.vehicleType = VehicleInfo_GetBitForVehicleType(vehicletype);
         
         new_ptr = Parser_ParseStats(new_ptr, vehiclenum);
         new_ptr = Parser_ParseWeapons(new_ptr, vehiclenum);
         new_ptr = Parser_ParseDisplay(new_ptr, vehiclenum);
         new_ptr = Parser_ParseSound(new_ptr, vehiclenum);
         new_ptr = Parser_ParsePhysics(new_ptr, vehiclenum);

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