#include   <stdio.h>
#include   <string.h>
#include   <sys/stat.h>
#include   <ctype.h>
#include   <stdlib.h>
#include   <fcntl.h>
#include   <sys/file.h>
#include   <stdio.h>
#include   <string.h>
#include   "db.h"
#include   "config.h"
#include   "structs.h"
#include   "utils.h"
#include   "functions.h"
#include   "command.h"
#include   "weather.h"

/* VARIABLES */
extern struct descriptor_data *desc_list;
extern struct player_index_element *player_table;

extern int  top_of_p_table;

extern struct descriptor_data *desc, *desc_next;

//////////////////////////////////////////////////
//																//
// By 	:	Charles Humphrey							//
// MODS :													//
//																//
// This function will handle the ticking hands	//
// of time, basicly there are 11 ticks in a day //
// each tick is part of the day i.e. MORNING,	//
// DAY and so on... At the end of each day, the //
// weather is checked for changes and 				//
// implemented. The time of day is held in 		//
// DAY_NIGHT with it's constants held in the 	//
// struct TODAY. The weather is made up of 		//
// various elements from wind and temp to 		//
// humidity and cloud cover, all combined giving//
// the weather for the day. Cuz Michel Fish 		//
// ocasionaly gets the weather wrong i have also//
// put in a bit of a random factor :-)				//
//																//
//////////////////////////////////////////////////
void   amend_TODAY(void)
{
   // Move the time on.
   TICKS++;
	
   // If end of day, reset TICKS and check the weather.
   if(TICKS > 11)
   {
      TICKS = 0;			
      chk_Weather();

      if(DEBUG_WORLD)
      {
         printf("\033[36mIt's the \033[0m%s \033[36mday of \033[37m%s" 
				"\033[36min the \033[0m%s "
            "\033[36myear of AXIA\033[0m\n\r",DY[DAYS-1].desc,MON[MONTHS].desc,
				DY[YEARS-1].desc);
			
      }		
   }

   SetWeather();
   // clean the string and load it with the current time of day.
   // kill this mat if you think its a bit overkill on the saftey - you know 
	// me, better safe than sorry.
   sprintf(DAY_NIGHT,"%s\n",TODAY[TICKS].desc);

   // If server is running in debug mode.
   if(DEBUG_WORLD)
      printf(DAY_NIGHT);

   // Slap in a NULL just in case (i know, overkill !).
   DAY_NIGHT[strlen(DAY_NIGHT)-1] = '\0';

}
// OK, here is the sloppy weather system, don't worry, I'll clean it up and 
// streamline it a bit.
// I don't know, you speed freaks !! ! !  :-)
void   chk_Weather(void)
{
   // Increment the days.
   DAYS++;

   // Is it the end of the month ?
   if(DAYS > MONTH)
   {
      // If so, reset DAYS and increment the month.
      MONTHS++;
      DAYS = 1;

      // But what if it is the end of the year !!! 
      if(MONTHS > YEAR)
      {
         // Reset month and increment year.
         MONTHS = 1;
         YEARS ++;
      }
   }
	
   // K, there are four seasons (nice set of tunes by the way)
   // So if the days * month go exactly into 87 (one quarter of the year)
   // move the season on. I would like this to be a bit more gnarly and have a 
	// grey area
   // between each season. Later maybe.
   if(!((DAYS * MONTHS) % 87))
      SEASON++;

   // If the season is spring, move back to summer.
   if(SEASON > 3)
      SEASON = 0;
	
   if(((rand() % 100) + 1) <= SEASONS[SEASON].Change)
      WeatherChange();	
}
// A sloppy function by Mr Supper Saftey String :-)
void   WeatherChange(void)
{
   // Get the settings from the season min and max for each set. - See the 
	//const of SEASONS.
   Tmp = (rand() % (SEASONS[SEASON].TempMax - SEASONS[SEASON].TempMin)) +
 		SEASONS[SEASON].TempMin;
   Wnd = (rand() % (SEASONS[SEASON].WindMax - SEASONS[SEASON].WindMin)) +
	 	SEASONS[SEASON].WindMin;
   Cld = (rand() % (SEASONS[SEASON].CloudMax - SEASONS[SEASON].CloudMin)) +
 		SEASONS[SEASON].CloudMin;
	
   // Find the humidity level.
   Tpe = HUMID[Cld].hum[Wnd];
	
   // Load the strings
   SetWeather();
   SetWeatherRep();

   if(DEBUG_WORLD)
   {
      // Fire ! !! 
      printf("%d %d %d %d : %d\n",Tmp,Wnd,Cld,Tpe,WTABLE[Tmp].weather[Tpe]);
      printf(WeatherRep);		
      printf(Weather);	
   }
}
void   SetWeather(void)
{
   if(strlen(WEATHER[WTABLE[Tmp].weather[Tpe]].desc) <= 0)
	{
      sprintf(Weather,"It's a %s %s in %s...",TEMP[Tmp].desc,TODAY[TICKS].desc,
			MON[MONTHS].desc);
	}
   else
      sprintf(Weather,"%s",WEATHER[WTABLE[Tmp].weather[Tpe]].desc);

   strcat(Weather,"\n\r");
}
void   SetWeatherRep(void)
{
      sprintf(WeatherRep,"%s: \n\rTemperature: %s\n\rWind: %s \n\rCloud: %s\n\r"
			,SEASONS[SEASON].desc,TEMP[Tmp].desc,WIND[Wnd].desc,CLOUD[Cld].desc);
}
// ok, more stuff you will probably hate :-)
// Put these here as they are for the weather and i think it makes more sense.
// The weather file is '@' delimited and has five entres, SEASON,TICK,DAY,
// MONTH and YEAR.
void   LoadSeasonDate(void)
{
   FILE   *fp;         // File handle.
   char   tmp[40+1];   // I/O buffer.
   char   ch[2];       // I/O char.
   char   cnt;         // Counter.
  
   // Open the weather file.
   if(!(fp = fopen("world/SeasonDate.sav","r+b"))) 
   {
      perror("Failed to open/build SeasonDate.sav - Defaults set.");
      printf("Failed to open/build SeasonDate.sav - Setting defaults.");      		
      TICKS = 0;
      DAYS = 1;
      MONTHS = 1;
      YEARS = 1;
   } 
   else 
      printf("Loading Weather & Date\n");
	
   for(cnt = 0;!feof(fp) && ch[0] != '~';cnt++)
   {
      ch[0] = fgetc(fp);
      tmp[cnt] = ch[0];
      tmp[cnt+1] = '\0';
   }

   if(!cnt)
   {
      TICKS = 0;
      DAYS = 1;
      MONTHS = 1;
      YEARS = 1;
   }
   else
   {
      // Get the SEASON.		
      if((SEASON = atoi(tmp)) > 3)
      {
         perror("Corrupt Season ! - Setting default.");
         printf("Failed to load Season..... - setting default\n");
         SEASON = 0;
      }		
      // Get DAY.
      if((DAYS = atoi(tmp+6)) > MONTH)
      {
         perror("Corrupt Days ! - Setting default.");
         printf("Failed to load Day..... - Setting default.\n");
         DAYS = 1;
      }
      // Get TICKS.
      if((TICKS = atoi(tmp+3)) >= 11)
      {
         perror("Corrupt Ticks ! - Setting default.");
         printf("Failed to load Ticks..... - Setting default\n");
         DAYS++;
         TICKS = 0;
      }
      // Get MONTH.
      if((MONTHS = atoi(tmp+9)) > YEAR)
      {
         perror("Corrupt Month ! - Setting default.");
         printf("Failed to load Month..... - Setting default.\n");
         MONTHS = 1;
      }

      if(!(YEARS = atol(tmp+12)))
      {
         perror("Corrupt Year ! - Setting default.");
         printf("Failed to load Year..... - Setting default.\n");
         YEARS = 1;
       }
	
   }
	
   // Let the server know the date and stuff.	
	if(DEBUG_WORLD)
	   printf("WEATHER Pattern = %d(%s)-%d%d%d%d%ld\n",strlen(tmp),tmp,SEASON,
			TICKS,DAYS,MONTHS,YEARS);
	
   // Close the weather file.
   fclose(fp);
}
char   SaveSeasonDate(void)
{
   FILE   *fp;         // File handle.
   char   tmp[40+1];   // I/O buffer.
   char   ret = 0;     // Return value. 0 = failure.

   // Open the file.
   if(!(fp = fopen("world/SeasonDate.sav","w"))) 
   {
      // There maybe trouble ahead........
      perror("Failed to open SeasonDate.sav");
      printf("Failed to open SeasonDate.sav");      		
   } 
   else 
   {
      // Let the searver know.
      printf("Saving Weather & Date.. \n\r");
		
      // Do the job !
		 if(TICKS > 0)
			  sprintf(tmp,"%02d@%02d@%02d@%02d@%03ld~\n",SEASON,TICKS-1,DAYS,MONTHS,
				YEARS);
      else
         sprintf(tmp,"%02d@%02d@%02d@%02d@%03ld~\n",SEASON,11,DAYS,MONTHS,
				YEARS);

      fputs(tmp,fp);

		ret = 1;
   }
   // Close the file.
   fclose(fp);

   return(ret);

}
// The tell all Weather combo, stolen from both your do_tell and
// send_2_all. I hope this is ok. I also put another Prefs flag
// in just in case players want to switch off the weather updates.
void	send_weather(void)
{
   extern struct descriptor_data *desc_list;

   SetWeather();
   for(desc = desc_list;desc;desc = desc_next) 
   {
      desc_next = desc->next_in_list;
      if(desc->character->CON_STATE == CON_PLYNG && BTST(desc->character->in_room->flags,OUTSIDE)) {
      	if(!BTST(desc->character->PREFS,NO_WEATH))
            send_2_output(Weather,desc);         
      }
   }
}




