LOP/
LOP/area/
LOP/boards/
LOP/channels/
LOP/clans/
LOP/color/
LOP/councils/
LOP/deity/
LOP/src/specials/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include "h/mud.h"

void free_friend( FRIEND_DATA *ofriend )
{
   if( !ofriend )
      return;
   STRFREE( ofriend->name );
   DISPOSE( ofriend );
}

void free_all_friends( CHAR_DATA *ch )
{
   FRIEND_DATA *ofriend, *ofriend_next;

   if( !ch || !ch->pcdata || !ch->pcdata->first_friend )
      return;

   for( ofriend = ch->pcdata->first_friend; ofriend; ofriend = ofriend_next )
   {
      ofriend_next = ofriend->next;
      UNLINK( ofriend, ch->pcdata->first_friend, ch->pcdata->last_friend, next, prev );
      free_friend( ofriend );
   }
}

FRIEND_DATA *find_friend( CHAR_DATA *ch, char *fname )
{
   FRIEND_DATA *ofriend;

   if( !ch || !fname || fname[0] == '\0' )
      return NULL;
   for( ofriend = ch->pcdata->first_friend; ofriend; ofriend = ofriend->next )
   {
      if( !str_cmp( ofriend->name, fname ) )
         return ofriend;
   }
   return NULL;
}

FRIEND_DATA *add_friend( CHAR_DATA *ch, char *fname )
{
   FRIEND_DATA *ofriend;

   if( !ch || !fname || fname[0] == '\0' )
      return NULL;
   fname = capitalize( fname );
   if( ( ofriend = find_friend( ch, fname ) ) )
      return NULL;
   if( !valid_pfile( fname ) )
      return NULL;
   CREATE( ofriend, FRIEND_DATA, 1 );
   STRSET( ofriend->name, fname );
   LINK( ofriend, ch->pcdata->first_friend, ch->pcdata->last_friend, next, prev );
   return ofriend;
}

CMDF( do_friend )
{
   FRIEND_DATA *ofriend;
   DESCRIPTOR_DATA *d;
   char arg[MSL], uname[MSL];
   const char *person;
   short cnt = -1;
   bool found = false, pending = false;

   if( !ch || !ch->pcdata )
      return;
   argument = one_argument( argument, arg );
   if( arg == NULL || arg[0] == '\0' )
   {
      for( ofriend = ch->pcdata->first_friend; ofriend; ofriend = ofriend->next )
      {
         if( !ofriend->name )
            continue;
         if( cnt == -1 )
         {
            send_to_char( "&[white]         Friend          Friend          Friend          Friend\r\n", ch );
            send_to_char( "--------------- --------------- --------------- ---------------\r\n", ch );
            cnt = 0;
         }
         found = true;
         person = color_str( AT_PERSON, ch );
         if( ofriend->sex == SEX_MALE )
            person = color_str( AT_MALE, ch );
         if( ofriend->sex == SEX_FEMALE )
            person = color_str( AT_FEMALE, ch );
         if( !ofriend->approved )
         {
            snprintf( uname, sizeof( uname ), "[%13.13s]", ofriend->name );
            pending = true;
         }
         else
            snprintf( uname, sizeof( uname ), "%15.15s", ofriend->name );
         ch_printf( ch, "%s%15.15s", person, uname );
         if( ++cnt == 4 )
         {
            cnt = 0;
            send_to_char( "\r\n", ch );
         }
         else
            send_to_char( " ", ch );
      }
      if( !found )
         send_to_char( "&[white]You currently have no one as a friend.\r\n", ch );
      else if( cnt != 0 )
         send_to_char( "\r\n", ch );
      if( pending )
         send_to_char( "&[white]Ones in [ ] are pending and not saved until you are approved to have them on your friend list.\r\n", ch );
      return;
   }
   argument = capitalize( argument );
   if( !str_cmp( arg, "add" ) )
   {
      if( !argument || argument[0] == '\0' )
      {
         send_to_char( "Who would you like to add to your friend list?\r\n", ch );
         return;
      }
      for( d = first_descriptor; d; d = d->next )
      {
         if( !d->character || !d->character->pcdata )
            continue;
         if( !str_cmp( d->character->name, argument ) )
            break;
      }
      if( !d || !d->character || !d->character->pcdata || str_cmp( d->character->name, argument ) || !can_see( ch, d->character ) )
      {
         send_to_char( "No one online by that name to add to your friend list.\r\n", ch );
         return;
      }
      if( !( ofriend = add_friend( ch, argument ) ) )
      {
         ch_printf( ch, "Sorry %s can't be added as your friend.\r\n", argument );
         return;
      }
      ofriend->sex = d->character->sex;
      ofriend->approved = false;
      ch_printf( ch, "%s has now been added as your friend.\r\n", argument );
      ch_printf( d->character, "%s would like to have you as a friend.\r\n", ch->name );
      return;
   }
   if( !str_cmp( arg, "remove" ) )
   {
      if( !( ofriend = find_friend( ch, argument ) ) )
      {
         ch_printf( ch, "Sorry %s isn't one of your friends.\r\n", argument );
         return;
      }
      UNLINK( ofriend, ch->pcdata->first_friend, ch->pcdata->last_friend, next, prev );
      free_friend( ofriend );
      ch_printf( ch, "%s is no longer one of your friends.\r\n", argument );
      return;
   }
   if( !str_cmp( arg, "approve" ) )
   {
      if( !argument || argument[0] == '\0' )
      {
         send_to_char( "Who would you like to approve to have you on their friend's list.\r\n", ch );
         return;
      }
      for( d = first_descriptor; d; d = d->next )
      {
         if( !d->character || !d->character->pcdata || !d->character->pcdata->first_friend )
            continue;
         if( str_cmp( d->character->name, argument ) )
            continue;
         if( !( ofriend = find_friend( d->character, ch->name ) ) )
            continue;
         if( ofriend->approved )
         {
            send_to_char( "You have already approved them to have you on their friend list.\r\n", ch );
            return;
         }
         ofriend->approved = true;
         ch_printf( ch, "You have allowed %s to have you on %s friends list.\r\n", d->character->name, his_her[d->character->sex] );
         ch_printf( d->character, "%s has allowed you to have %s on your friends list.\r\n", ch->name, him_her[ch->sex] );

         if( !( ofriend = add_friend( ch, d->character->name ) ) )
            return;
         ofriend->sex = d->character->sex;
         ofriend->approved = true;
         ch_printf( d->character, "You have allowed %s to have you on %s friends list.\r\n", ch->name, his_her[ch->sex] );
         ch_printf( ch, "%s has allowed you to have %s on your friends list.\r\n", d->character->name, him_her[d->character->sex] );
         return;
      }
      send_to_char( "No one by that name was found online wanting you on their friend list.\r\n", ch );
      return;
   }
   if( !str_cmp( arg, "deny" ) )
   {
      if( !argument || argument[0] == '\0' )
      {
         send_to_char( "Who would you like to deny to have you on their friend's list.\r\n", ch );
         return;
      }
      for( d = first_descriptor; d; d = d->next )
      {
         if( !d->character || !d->character->pcdata || !d->character->pcdata->first_friend )
            continue;
         if( str_cmp( d->character->name, argument ) )
            continue;
         if( !( ofriend = find_friend( d->character, ch->name ) ) )
            continue;
         UNLINK( ofriend, d->character->pcdata->first_friend, d->character->pcdata->last_friend, next, prev );
         free_friend( ofriend );
         ch_printf( ch, "You have denied %s having you on %s friends list.\r\n", d->character->name, his_her[d->character->sex] );
         ch_printf( d->character, "%s has denied you having %s on your friends list.\r\n", ch->name, him_her[ch->sex] );
         if( !( ofriend = find_friend( ch, d->character->name ) ) )
            return;
         UNLINK( ofriend, ch->pcdata->first_friend, ch->pcdata->last_friend, next, prev );
         free_friend( ofriend );
         ch_printf( d->character, "You have denied %s having you on %s friends list.\r\n", ch->name, his_her[ch->sex] );
         ch_printf( ch, "%s has denied you having %s on your friends list.\r\n", d->character->name, him_her[d->character->sex] );
         return;
      }
      send_to_char( "No one by that name was found online wanting you on their friend list.\r\n", ch );
      return;
   }

   send_to_char( "&[white]Usage: friend add/remove/approve/deny <name>\r\n", ch );
}

void send_friend_info( CHAR_DATA *ch, char *message )
{
   DESCRIPTOR_DATA *d;
   FRIEND_DATA *ofriend;
   const char *person;

   if( !ch || !message || !ch->pcdata )
      return;
   if( xIS_SET( ch->act, PLR_NOFINFO ) )
      return;
   for( d = first_descriptor; d; d = d->next )
   {
      if( !d->character || !d->character->pcdata || !( ofriend = find_friend( d->character, ch->name ) ) || !ofriend->approved )
         continue;
      /* Might as well go ahead and update the sex if it is needed */
      if( ofriend->sex != ch->sex )
         ofriend->sex = ch->sex;
      if( xIS_SET( d->character->act, PLR_NOFINFO ) )
         continue;
      if( !can_see( d->character, ch ) )
         continue;      
      person = color_str( AT_PERSON, d->character );
      if( ofriend->sex == SEX_MALE )
         person = color_str( AT_MALE, d->character );
      if( ofriend->sex == SEX_FEMALE )
         person = color_str( AT_FEMALE, d->character );
      ch_printf( d->character, "&[white][Friend] %s%s\r\n", person, message );
   }
}