atd/area/
atd/build/
atd/clans/
atd/log/
atd/player/store/
atd/site/
atd/src/bin/
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>     /* OLC 1.1b */
#include <time.h>
#include "merc.h"
#include "build.h"

extern int maxSocial;

/*
 * Social editor
 */
const struct olc_cmd_type sedit_table [ ] =
{
    { "name",          sedit_name     },
    { "create",           sedit_create   },
    { "delete",        sedit_delete   },
    { "show",          sedit_show     },

    { "char_no_arg",	sedit_cna     },
    { "cna",		sedit_cna     },
    { "others_no_arg",	sedit_ona     },
    { "ona",		sedit_ona     },
    { "char_found",	sedit_cf      },
    { "cf",		sedit_cf      },
    { "others_found",	sedit_of      },
    { "of",		sedit_of      },
    { "victim_found",	sedit_vf      },
    { "vf",		sedit_vf      },
    { "char_auto",	sedit_ca      },
    { "ca",		sedit_ca      },
    { "others_auto",	sedit_oa      },
    { "oa",		sedit_oa      },

    { "commands",      show_commands  },
    { "?",             show_help      },
    { "",              0              }
};

/*
 * Find a social based on name
 */
int social_lookup (const char *name)
{
    int i;

    for (i = 0; i < maxSocial ; i++)
        if (!str_cmp(name, social_table[i].name))
            return i;

    return -1;
}


void sedit( CHAR_DATA *ch, char *argument )
{
    char arg [ MAX_INPUT_LENGTH ];
    char command [ MAX_INPUT_LENGTH ];
    int cmd;
    struct social_type *pSoc;

    EDIT_SOCIAL(ch, pSoc);

    smash_tilde( argument );
    strcpy( arg, argument );
    argument = one_argument( argument, command );
    
    if( ch->pcdata->security <= 10 )
    {
        stc( "SEdit:  Insufficient security to modify social.\n\r", ch );
        return;
    }
    
    if( arg[0] == '\0' )
    {
        sedit_show( ch, argument );
        return;
    }

    if( !str_cmp( arg, "done" ) )
    {
        edit_done(ch);
        return;
    }

    for( cmd = 0; *sedit_table[cmd].name; cmd++ )
    {
        if( !str_prefix( command, sedit_table[cmd].name ) )
        {
            if( (*sedit_table[cmd].olc_fun) ( ch, argument ) )
                save_socials();
            return;
        }
    }

    /* Default to Standard Intepreter. */
    interpret( ch, arg );
    return;
}

void do_sedit(CHAR_DATA *ch, char *argument)
{
    struct social_type *pSocial;
    char command[MIL];
    int social;

    if ( IS_NPC(ch) || ch->desc == NULL )
    	return;

    if ( argument[0] == '\0' )
    {
    	send_to_char( "Syntax : SEdit [social]\n\r", ch );
    	send_to_char( "         SEdit new [social]\n\r", ch );
    	send_to_char( "         SEdit delete [social]\n\r", ch );
    	return;
    }

    if (ch->pcdata->security < 10 )
    {
    	send_to_char( "SEdit : Insuficant security to edit socials.\n\r", ch );
    	return;
    }

    argument = one_argument( argument, command );

    if ( !str_cmp( command, "new" ) )
    {
        if ( sedit_create(ch, argument) )
            save_socials();
	return;
    }

    if ( !str_cmp( command, "delete" ) )
    {
    	if ( sedit_delete(ch, argument) )
            save_socials();
    	return;
    }

    if( command[0] == 's' && !str_prefix( command, "save"  ) )
    {
        save_socials( );
        return;
    }

    if ( (social = social_lookup(command)) == -1 )
    {
        send_to_char( "SEdit : Social doesn't exist.\n\r", ch );
        return;
    }

    pSocial = &social_table[social];

    ch->desc->pEdit=(void *)pSocial;
    ch->desc->editor= ED_SOCIAL;
    sedit_show( ch, "" );
    return;
}

bool sedit_create( CHAR_DATA *ch, char *argument )
{
    char buf[MAX_INPUT_LENGTH];
    char *p;
    DESCRIPTOR_DATA *d;
    CHAR_DATA *tch;
    struct social_type *new_table;
    int iSocial; 
	
    if( !argument || argument[0] == '\0' )
    {
        stc( "Syntax: SEdit create <$name>\n\r", ch );
        return FALSE;
    }

    strcpy( buf, argument );
    for( p = &buf[0]; p && *p; ++p )
	*p = LOWER( *p );


    
    iSocial = social_lookup( argument );


    if (iSocial != -1)
    {
        send_to_char ("A social with that name already exists\n\r",ch);
        return FALSE;
    }

    /*
     * Really bad if someone else is editing a social
     * and you delete it.
     */
    for ( d = descriptor_list; d; d = d->next )
    {
        if ( d->connected != CON_PLAYING
             || (tch = CH(d)) == NULL || tch->desc == NULL )
            continue;

        if ( tch->desc->editor == ED_SOCIAL )
            edit_done(ch);
    }


    /* reallocate the table */
    /*
     * Note that the table contains
     * maxSocial socials PLUS one empty spot!
     */

    maxSocial++;
    new_table = realloc (social_table, sizeof(struct social_type) * (maxSocial + 1));

    if (!new_table) /* realloc failed */
    {
        send_to_char ("Memory allocation failed. Brace for impact.\n\r",ch);
        return FALSE;
    }

    social_table = new_table;

    social_table[maxSocial-1].name = str_dup (buf);
    social_table[maxSocial-1].char_no_arg = str_dup ("");
    social_table[maxSocial-1].others_no_arg = str_dup ("");
    social_table[maxSocial-1].char_found = str_dup ("");
    social_table[maxSocial-1].others_found = str_dup ("");
    social_table[maxSocial-1].vict_found = str_dup ("");
    social_table[maxSocial-1].char_auto = str_dup ("");
    social_table[maxSocial-1].others_auto = str_dup ("");

    social_table[maxSocial].name = str_dup (""); /* 'terminating' empty string */

    ch->desc->editor	= ED_SOCIAL;
    ch->desc->pEdit		= (void *) &social_table[maxSocial-1];


    send_to_char( "SEdit:  Social created.\n\r", ch );
    if( strchr( buf, ' ' ) )
	send_to_char( "Be careful with spaces, "
		      "they might stuff you up here.\n\r", ch );
    return TRUE;
}

bool sedit_delete ( CHAR_DATA *ch, char *argument )
{
    DESCRIPTOR_DATA *d;
    CHAR_DATA *tch;
    int i,j,iSocial;
    struct social_type *new_table;

    if ( argument[0] == '\0' )
    {
        send_to_char( "Syntax : delete [social]\n\r", ch );
        return FALSE;
    }

    iSocial = social_lookup(argument);

    if (iSocial == -1)
    {
        send_to_char( "SEdit : social doesn't exhist\n\r", ch );
        return FALSE;
    }

    /*
     * Really bad if someone else is editing a social
     * and you delete it.
     */
    for ( d = descriptor_list; d; d = d->next )
    {
        if ( d->connected != CON_PLAYING
             || (tch = CH(d)) == NULL || tch->desc == NULL )
            continue;

        if ( tch->desc->editor == ED_SOCIAL )
            edit_done(ch);
    }

    new_table = malloc (sizeof(struct social_type) * maxSocial);

    if (!new_table)
    {
        send_to_char ("Memory allocation failed. Brace for impact...\n\r",ch);
        return FALSE;
    }

    /* Copy all elements of old table into new table, except the deleted social */
    for (i = 0, j = 0; i < maxSocial+1; i++)
    {
        if (i != iSocial) /* copy, increase only if copied */
        {
            new_table[j] = social_table[i];
            j++;
        }
    }

    free (social_table);
    social_table = new_table;

    maxSocial--; /* Important :() */

    send_to_char ("Social Deleted.\n\r",ch);
    return TRUE;
}

bool sedit_show( CHAR_DATA *ch, char *argument )
{
    struct social_type *pSocial;

    EDIT_SOCIAL(ch,pSocial );

    ch_printf( ch, "{gName          {b[{c%s{b]\n\r", pSocial->name );
    ch_printf( ch, "{gChar_No_Arg:  {w%s\n\r", pSocial->char_no_arg );
    ch_printf( ch, "{gOthers_No_Arg:{w%s\n\r", pSocial->others_no_arg );
    ch_printf( ch, "{gChar_Found:   {w%s\n\r", pSocial->char_found );
    ch_printf( ch, "{gOthers_Found: {w%s\n\r", pSocial->others_found );
    ch_printf( ch, "{gVictim_Found: {w%s\n\r", pSocial->vict_found );
    ch_printf( ch, "{gChar_Auto:    {w%s\n\r", pSocial->char_auto );
    ch_printf( ch, "{gOthers_Auto:  {w%s\n\r", pSocial->others_auto );
    return FALSE;
}


bool sedit_name( CHAR_DATA *ch, char *argument )
{
    struct social_type *pSocial;

    EDIT_SOCIAL( ch, pSocial );

    if( argument[0] == '\0' )
    {
	send_to_char( "Syntax:  name <$name>\n\r", ch );
	return FALSE;
    }

    free_string( pSocial->name );
    pSocial->name = str_dup( argument );

    send_to_char( "Name set.\n\r", ch );
    return FALSE;
}


bool sedit_change( CHAR_DATA *ch, char *argument, char **which,
		   bool hasvict )
{
    char const *legal = "nNeEmMsSgGoO%$";
    const char *p;

    if( !hasvict )
	legal = "nemsgo%$";
    for( p = strchr( argument, '$' );
	 p && *p; p = strchr( p, '$' ) )
    {
	p++;
	if( !*p || !strchr( legal, *p ) )
	{
	    send_to_char( "Illegal act string.\n\r", ch );
	    return FALSE;
	}
    }
    free_string( *which );
    *which = str_dup( argument );
    send_to_char( "Value set.\n\r", ch );
    return TRUE;
}


bool sedit_cna( CHAR_DATA *ch, char *argument )
{
    struct social_type *pSocial;

    EDIT_SOCIAL( ch, pSocial );

    if( argument[0] == '\0' )
    {
	send_to_char( "Syntax:  cna <$char no arg>\n\r", ch );
	return FALSE;
    }

    return sedit_change( ch, argument, &pSocial->char_no_arg, FALSE );
}


bool sedit_ona( CHAR_DATA *ch, char *argument )
{
    struct social_type *pSocial;

    EDIT_SOCIAL( ch, pSocial );

    if( argument[0] == '\0' )
    {
	send_to_char( "Syntax:  ona <$others no arg>\n\r", ch );
	return FALSE;
    }

    return sedit_change( ch, argument, &pSocial->others_no_arg, FALSE );
}


bool sedit_cf( CHAR_DATA *ch, char *argument )
{
    struct social_type *pSocial;

    EDIT_SOCIAL( ch, pSocial );

    if( argument[0] == '\0' )
    {
	send_to_char( "Syntax:  cf <$char found>\n\r", ch );
	return FALSE;
    }

    return sedit_change( ch, argument, &pSocial->char_found, TRUE );
}


bool sedit_of( CHAR_DATA *ch, char *argument )
{
    struct social_type *pSocial;

    EDIT_SOCIAL( ch, pSocial );

    if( argument[0] == '\0' )
    {
	send_to_char( "Syntax:  of <$others found>\n\r", ch );
	return FALSE;
    }

    return sedit_change( ch, argument, &pSocial->others_found, TRUE );
}


bool sedit_vf( CHAR_DATA *ch, char *argument )
{
    struct social_type *pSocial;

    EDIT_SOCIAL( ch, pSocial );

    if( argument[0] == '\0' )
    {
	send_to_char( "Syntax:  vf <$victim found>\n\r", ch );
	return FALSE;
    }

    return sedit_change( ch, argument, &pSocial->vict_found, TRUE );
}


bool sedit_ca( CHAR_DATA *ch, char *argument )
{
    struct social_type *pSocial;

    EDIT_SOCIAL( ch, pSocial );

    if( argument[0] == '\0' )
    {
	send_to_char( "Syntax:  ca <$char auto>\n\r", ch );
	return FALSE;
    }

    return sedit_change( ch, argument, &pSocial->char_auto, FALSE );
}


bool sedit_oa( CHAR_DATA *ch, char *argument )
{
    struct social_type *pSocial;

    EDIT_SOCIAL( ch, pSocial );

    if( argument[0] == '\0' )
    {
	send_to_char( "Syntax:  oa <$others auto>\n\r", ch );
	return FALSE;
    }

    return sedit_change( ch, argument, &pSocial->others_auto, FALSE );
}