dbna/clans/
dbna/councils/
dbna/deity/
dbna/gods/
dbna/houses/
dbna/space/

#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
/* #include <stdlib.h> */
#include <time.h>
#include "mud.h"


PLANET_DATA *first_planet;
PLANET_DATA *last_planet;

GUARD_DATA *first_guard;
GUARD_DATA *last_guard;


void fread_planet args( ( PLANET_DATA * planet, FILE * fp ) );
bool load_planet_file args( ( char *planetfile ) );
void write_planet_list args( ( void ) );

PLANET_DATA *get_planet( char *name )
{
  PLANET_DATA *planet;

  for( planet = first_planet; planet; planet = planet->next )
    if( !str_cmp( name, planet->name ) )
      return planet;
  return NULL;
}

void write_planet_list(  )
{
  PLANET_DATA *tplanet;
  FILE *fpout;
  char filename[256];

  sprintf( filename, "%s%s", PLANET_DIR, PLANET_LIST );
  fpout = fopen( filename, "w" );
  if( !fpout )
  {
    bug( "FATAL: cannot open planet.lst for writing!\n\r", 0 );
    return;
  }
  for( tplanet = first_planet; tplanet; tplanet = tplanet->next )
    fprintf( fpout, "%s\n", tplanet->filename );
  fprintf( fpout, "$\n" );
  fclose( fpout );
}

void save_planet( PLANET_DATA * planet )
{
  FILE *fp;
  char filename[256];
  char buf[MAX_STRING_LENGTH];

  if( !planet )
  {
    bug( "save_planet: null planet pointer!", 0 );
    return;
  }

  if( !planet->filename || planet->filename[0] == '\0' )
  {
    sprintf( buf, "save_planet: %s has no filename", planet->name );
    bug( buf, 0 );
    return;
  }

  sprintf( filename, "%s%s", PLANET_DIR, planet->filename );

  fclose( fpReserve );
  if( ( fp = fopen( filename, "w" ) ) == NULL )
  {
    bug( "save_planet: fopen", 0 );
    perror( filename );
  }
  else
  {
    AREA_DATA *pArea;

    fprintf( fp, "#PLANET\n" );
    fprintf( fp, "Name         %s~\n", planet->name );
    fprintf( fp, "Filename     %s~\n", planet->filename );
    fprintf( fp, "BaseValue    %ld\n", planet->base_value );
    fprintf( fp, "Flags        %d\n", planet->flags );
    fprintf( fp, "PopSupport   %.0f\n", planet->pop_support );
    if( planet->starsystem && planet->starsystem->name )
      fprintf( fp, "Starsystem   %s~\n", planet->starsystem->name );
    if( planet->governed_by && planet->governed_by->name )
      fprintf( fp, "GovernedBy   %s~\n", planet->governed_by->name );
    for( pArea = planet->first_area; pArea; pArea = pArea->next_on_planet )
      if( pArea->filename )
        fprintf( fp, "Area         %s~\n", pArea->filename );
    fprintf( fp, "End\n\n" );
    fprintf( fp, "#END\n" );
  }
  fclose( fp );
  fpReserve = fopen( NULL_FILE, "r" );
  return;
}

#if defined(KEY)
#undef KEY
#endif

#define KEY( literal, field, value )					\
				if ( !str_cmp( word, literal ) )	\
				{					\
				    field  = value;			\
				    fMatch = TRUE;			\
				    break;				\
				}

void fread_planet( PLANET_DATA * planet, FILE * fp )
{
  char buf[MAX_STRING_LENGTH];
  char *word;
  bool fMatch;

  for( ;; )
  {
    word = feof( fp ) ? "End" : fread_word( fp );
    fMatch = FALSE;

    switch ( UPPER( word[0] ) )
    {
      case '*':
        fMatch = TRUE;
        fread_to_eol( fp );
        break;

      case 'A':
        if( !str_cmp( word, "Area" ) )
        {
          char aName[MAX_STRING_LENGTH];
          AREA_DATA *pArea;

          sprintf( aName, fread_string( fp ) );
          for( pArea = first_area; pArea; pArea = pArea->next )
            if( pArea->filename && !str_cmp( pArea->filename, aName ) )
            {
              pArea->planet = planet;
              LINK( pArea, planet->first_area, planet->last_area, next_on_planet, prev_on_planet );
            }
          fMatch = TRUE;
        }
        break;

      case 'B':
        KEY( "BaseValue", planet->base_value, fread_number( fp ) );
        break;

      case 'E':
        if( !str_cmp( word, "End" ) )
        {
          if( !planet->name )
            planet->name = STRALLOC( "" );
          return;
        }
        break;

      case 'F':
        KEY( "Filename", planet->filename, fread_string_nohash( fp ) );
        KEY( "Flags", planet->flags, fread_number( fp ) );
        break;

      case 'G':
        if( !str_cmp( word, "GovernedBy" ) )
        {
          planet->governed_by = get_clan( fread_string( fp ) );
          fMatch = TRUE;
        }
        break;

      case 'N':
        KEY( "Name", planet->name, fread_string( fp ) );
        break;

      case 'P':
        KEY( "PopSupport", planet->pop_support, fread_number( fp ) );
        break;

      case 'S':
        if( !str_cmp( word, "Starsystem" ) )
        {
          planet->starsystem = starsystem_from_name( fread_string( fp ) );
          if( planet->starsystem )
          {
            SPACE_DATA *starsystem = planet->starsystem;

            LINK( planet, starsystem->first_planet, starsystem->last_planet, next_in_system, prev_in_system );
          }
          fMatch = TRUE;
        }
        break;

      case 'T':
        KEY( "Taxes", planet->base_value, fread_number( fp ) );
        break;

    }

    if( !fMatch )
    {
      sprintf( buf, "Fread_planet: no match: %s", word );
      bug( buf, 0 );
    }

  }
}

bool load_planet_file( char *planetfile )
{
  char filename[256];
  PLANET_DATA *planet;
  FILE *fp;
  bool found;

  CREATE( planet, PLANET_DATA, 1 );

  planet->governed_by = NULL;
  planet->next_in_system = NULL;
  planet->prev_in_system = NULL;
  planet->starsystem = NULL;
  planet->first_area = NULL;
  planet->last_area = NULL;
  planet->first_guard = NULL;
  planet->last_guard = NULL;

  found = FALSE;
  sprintf( filename, "%s%s", PLANET_DIR, planetfile );

  if( ( fp = fopen( filename, "r" ) ) != NULL )
  {

    found = TRUE;
    for( ;; )
    {
      char letter;
      char *word;

      letter = fread_letter( fp );
      if( letter == '*' )
      {
        fread_to_eol( fp );
        continue;
      }

      if( letter != '#' )
      {
        bug( "Load_planet_file: # not found.", 0 );
        break;
      }

      word = fread_word( fp );
      if( !str_cmp( word, "PLANET" ) )
      {
        fread_planet( planet, fp );
        break;
      }
      else if( !str_cmp( word, "END" ) )
        break;
      else
      {
        char buf[MAX_STRING_LENGTH];

        sprintf( buf, "Load_planet_file: bad section: %s.", word );
        bug( buf, 0 );
        break;
      }
    }
    fclose( fp );
  }

  if( !found )
    DISPOSE( planet );
  else
    LINK( planet, first_planet, last_planet, next, prev );

  return found;
}

void load_planets(  )
{
  FILE *fpList;
  char *filename;
  char planetlist[256];
  char buf[MAX_STRING_LENGTH];

  first_planet = NULL;
  last_planet = NULL;

  log_string( "Loading planets..." );

  sprintf( planetlist, "%s%s", PLANET_DIR, PLANET_LIST );
  fclose( fpReserve );
  if( ( fpList = fopen( planetlist, "r" ) ) == NULL )
  {
    perror( planetlist );
    exit( 1 );
  }

  for( ;; )
  {
    filename = feof( fpList ) ? "$" : fread_word( fpList );
    log_string( filename );
    if( filename[0] == '$' )
      break;

    if( !load_planet_file( filename ) )
    {
      sprintf( buf, "Cannot load planet file: %s", filename );
      bug( buf, 0 );
    }
  }
  fclose( fpList );
  log_string( " Done planets " );
  fpReserve = fopen( NULL_FILE, "r" );
  return;
}

void do_setplanet( CHAR_DATA * ch, char *argument )
{
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  PLANET_DATA *planet;

  if( IS_NPC( ch ) )
  {
    send_to_pager_color( "Huh?\n\r", ch );
    return;
  }

  argument = one_argument( argument, arg1 );
  argument = one_argument( argument, arg2 );

  if( arg1[0] == '\0' )
  {
    send_to_pager_color( "Usage: setplanet <planet> <field> [value]\n\r", ch );
    send_to_pager_color( "\n\rField being one of:\n\r", ch );
    send_to_pager_color( " base_value flags\n\r", ch );
    send_to_pager_color( " name filename starsystem governed_by\n\r", ch );
    return;
  }

  planet = get_planet( arg1 );
  if( !planet )
  {
    send_to_pager_color( "No such planet.\n\r", ch );
    return;
  }


  if( !strcmp( arg2, "name" ) )
  {
    STRFREE( planet->name );
    planet->name = STRALLOC( argument );
    send_to_pager_color( "Done.\n\r", ch );
    save_planet( planet );
    return;
  }

  if( !strcmp( arg2, "governed_by" ) )
  {
    CLAN_DATA *clan;
    clan = get_clan( argument );
    if( clan )
    {
      planet->governed_by = clan;
      send_to_pager_color( "Done.\n\r", ch );
      save_planet( planet );
    }
    else
      send_to_pager_color( "No such clan.\n\r", ch );
    return;
  }

  if( !strcmp( arg2, "starsystem" ) )
  {
    SPACE_DATA *starsystem;

    if( ( starsystem = planet->starsystem ) != NULL )
      UNLINK( planet, starsystem->first_planet, starsystem->last_planet, next_in_system, prev_in_system );
    if( ( planet->starsystem = starsystem_from_name( argument ) ) )
    {
      starsystem = planet->starsystem;
      LINK( planet, starsystem->first_planet, starsystem->last_planet, next_in_system, prev_in_system );
      send_to_pager_color( "Done.\n\r", ch );
    }
    else
      send_to_pager_color( "No such starsystem.\n\r", ch );
    save_planet( planet );
    return;
  }

  if( !strcmp( arg2, "filename" ) )
  {
    if( planet->filename )
      DISPOSE( planet->filename );
    planet->filename = str_dup( argument );
    send_to_pager_color( "Done.\n\r", ch );
    save_planet( planet );
    write_planet_list(  );
    return;
  }

  if( !strcmp( arg2, "base_value" ) )
  {
    planet->base_value = atoi( argument );
    send_to_pager_color( "Done.\n\r", ch );
    save_planet( planet );
    return;
  }

  if( !strcmp( arg2, "flags" ) )
  {
    char farg[MAX_INPUT_LENGTH];

    argument = one_argument( argument, farg );

    if( farg[0] == '\0' )
    {
      send_to_pager_color( "Possible flags: nocapture\n\r", ch );
      return;
    }

    for( ; farg[0] != '\0'; argument = one_argument( argument, farg ) )
    {
      if( !str_cmp( farg, "nocapture" ) )
        TOGGLE_BIT( planet->flags, PLANET_NOCAPTURE );
      else
        pager_printf_color( ch, "No such flag: %s\n\r", farg );
    }
    send_to_pager_color( "Done.\n\r", ch );
    save_planet( planet );
    return;
  }

  do_setplanet( ch, "" );
  return;
}

void do_showplanet( CHAR_DATA * ch, char *argument )
{
  PLANET_DATA *planet;

  if( IS_NPC( ch ) )
  {
    send_to_pager_color( "Huh?\n\r", ch );
    return;
  }

  if( argument[0] == '\0' )
  {
    send_to_pager_color( "Usage: showplanet <planet>\n\r", ch );
    return;
  }

  planet = get_planet( argument );
  if( !planet )
  {
    send_to_pager_color( "No such planet.\n\r", ch );
    return;
  }

  pager_printf_color( ch, "%s\n\rFilename: %s\n\r", planet->name, planet->filename );
  return;
}

void do_makeplanet( CHAR_DATA * ch, char *argument )
{
  char filename[256];
  PLANET_DATA *planet;
  bool found;

  if( !argument || argument[0] == '\0' )
  {
    send_to_pager_color( "Usage: makeplanet <planet name>\n\r", ch );
    return;
  }

  found = FALSE;
  sprintf( filename, "%s%s", PLANET_DIR, strlower( argument ) );

  CREATE( planet, PLANET_DATA, 1 );
  LINK( planet, first_planet, last_planet, next, prev );
  planet->governed_by = NULL;
  planet->next_in_system = NULL;
  planet->prev_in_system = NULL;
  planet->starsystem = NULL;
  planet->first_area = NULL;
  planet->last_area = NULL;
  planet->first_guard = NULL;
  planet->last_guard = NULL;
  planet->name = STRALLOC( argument );
  planet->flags = 0;
}

void do_planets( CHAR_DATA * ch, char *argument )
{
  PLANET_DATA *planet;
  int count = 0;
  AREA_DATA *area;

  set_char_color( AT_WHITE, ch );
  for( planet = first_planet; planet; planet = planet->next )
  {
    pager_printf_color( ch, "&WPlanet: &G%-15s   &WGoverned By: &G%s %s\n\r",
                        planet->name,
                        planet->governed_by ? planet->governed_by->name : "",
                        IS_SET( planet->flags, PLANET_NOCAPTURE ) ? "(permanent)" : "" );
    pager_printf_color( ch, "&WValue: &G%-10ld&W/&G%-10d   ", get_taxes( planet ), planet->base_value );
    pager_printf_color( ch, "&WPopulation: &G%-5d   &W Pop Support: &G%.1f\n\r", planet->population, planet->pop_support );
    if( IS_IMMORTAL( ch ) )
    {
      pager_printf_color( ch, "&WAreas: &G" );
      for( area = planet->first_area; area; area = area->next_on_planet )
        pager_printf_color( ch, "%s,  ", area->filename );
      pager_printf_color( ch, "\n\r" );
    }
    pager_printf_color( ch, "\n\r" );

    count++;
  }

  if( !count )
  {
    set_char_color( AT_BLOOD, ch );
    send_to_pager_color( "There are no planets currently formed.\n\r", ch );
  }

}

long get_taxes( PLANET_DATA * planet )
{
  long gain;

  gain = planet->base_value;
  gain += planet->base_value * planet->pop_support / 100;
  gain += UMAX( 0, planet->pop_support / 10 * planet->population );

  return gain;
}