/
/***********************************************************
*  This color code is based somewhat on Lopes color.      *
*  The big difference is I'm using tables for the colors  *
*  and custom color spots. If you already have Lopes      *
*  color installed, you should be able to install this    *
*  with minimal difficulty. Read the README.color file    *
*  included with this package for ROM installation        *
*  instructions. Please send bugs/fixes/comments to:      *
*  jessechoward@netscape.net                              *
*  This is just a development release so if something is  *
*  missing or you would like to see something in the next *
*  release, e-mail me and I will try to get it done.      *
***********************************************************/
/*******************
* Color V1.0.1    *
* by Thanos for   *
* Carpathia MUD   *
* kyndig.com 9501 *
*******************/

#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#include <sys/time.h>
#endif

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#include "merc.h"
#include "olc.h"

const struct color_type color_table[] = 
{
/*  color,	     letter, flag,	bright, code,	visible */
    { "red",		"r", RED,	0,	31,	TRUE  },
    { "green",		"g", GREEN, 	0,	32,	TRUE  },
    { "yellow",		"y", YELLOW,	0,	33,	TRUE  },
    { "blue",		"b", BLUE,	0,	34,	TRUE  },
    { "magenta",	"m", MAGENTA,	0,	35,	TRUE  },
    { "cyan",		"c", CYAN,	0,	36,	TRUE  },
    { "gray",		"l", GRAY,	0,	37,	TRUE  },
    { "dark gray",	"D", D_GRAY,	1,	30,	TRUE  },
    { "bright red",	"R", B_RED,	1,	31,	TRUE  },
    { "bright green",	"G", B_GREEN,	1,	32,	TRUE  },
    { "bright yellow",	"Y", B_YELLOW,	1,	33,	TRUE  },
    { "bright blue",	"B", B_BLUE,	1,	34,	TRUE  },
    { "bright magenta",	"M", B_MAGENTA,	1,	35,	TRUE  },
    { "bright cyan",	"C", B_CYAN,	1,	36,	TRUE  },
    { "white",		"w", WHITE,	1,	37,	TRUE  },
    { "white",		"W", WHITE,	1,	37,	FALSE },
    { "reset",		"x", END_COLOR,	0,	0,	TRUE  },
    { "reset",		"X", END_COLOR,	0,	0,	FALSE },
    { NULL,		NULL, 0,	0,	0,	FALSE }
};

const struct custom_color_type custom_colors[MAX_CUSTOM_COLORS]=
{
    { "say",	"S",	GREEN,		0		},
    { "tell",	"T",	B_GREEN,	0  		},
    { "immtalk","I",	B_MAGENTA,	LEVEL_IMMORTAL	},
    { "damage", "d",	RED,		0		},
    { "inflicted","i",	B_YELLOW,	0,		},
    { "prompt",	"P",	CYAN,		0,		},
    { "hp",	"h",	B_GREEN,	0,		},
    { "mana",	"a",	B_BLUE,		0,		},
    { "moves",	"v",	B_YELLOW,	0,		},
    { "ooc",	"O",	B_BLUE,		0,		},
    { "ic",	"H",	MAGENTA,	0,		},
    { "wiznet", "z",	YELLOW,		LEVEL_IMMORTAL	},
    { "newbie",	"n",	GREEN,		0,		},
    { "olc",	"o",	B_YELLOW,	LEVEL_IMMORTAL	}
};

int get_color( long flag )
{
    int color;

    /* look for the flag */
    for ( color = 0; color_table[color].color; color++ )
    {
	if ( color_table[color].flag == flag )
	    return color;
    }

    /* not found so default to white */
    for ( color = 0; color_table[color].color; color++ )
    {
	if ( color_table[color].flag == WHITE )
	    return color;
    }

    return -1;
}

int custom_color( CHAR_DATA *ch, char letter )
{
    int icolor;
    long flag;

    for ( icolor = 0; icolor < MAX_CUSTOM_COLORS; icolor++ )
    {
	if ( *custom_colors[icolor].letter == letter )
	{
	    flag = ch->pcdata->colors[icolor];
	    return get_color( flag );
	}
    }

    return -1;
}

int color_lookup( const char *name )
{
    int icolor;

    for ( icolor = 0; color_table[icolor].color; icolor++ )
    {
	if ( !str_cmp( color_table[icolor].color, name ) )
	    return icolor;
    }

    return -1;
}

int custom_color_lookup( const char *name )
{
    int icolor;

    for ( icolor = 0; icolor < MAX_CUSTOM_COLORS; icolor++ )
    {
	if ( !str_cmp( custom_colors[icolor].position, name ) )
	    return icolor;
    }

    return -1;
}

int color( CHAR_DATA *ch, char letter, char *buffer )
{
    char color[20];
    int icolor;

    if ( letter == COLOR_CHAR )
    {
	*buffer++ = letter;
	*buffer = '\0';
	return 1;
    }

    for ( icolor = 0; color_table[icolor].color; icolor++ )
    {
	if ( *color_table[icolor].letter == letter )
	{
	    if ( color_table[icolor].flag == END_COLOR )
		sprintf( color, "\e[0m" );
	    else
		sprintf( color, "\e[%d;%dm",
		    color_table[icolor].bright,
		    color_table[icolor].code );
	    strcpy( buffer, color );
	    return (int)strlen( color );
	}
    }

    if ( ch )
    {
	icolor = custom_color( ch, letter );

	if ( icolor >= 0 )
	{
	    sprintf( color, "\e[%d;%dm",
	    	color_table[icolor].bright,
	    	color_table[icolor].code );
	    strcpy( buffer, color );
	    return (int)strlen( color );
    	}
    }

    return 0;
}

int strip_ansii( const char *txt, char *buffer )
{
   const char *point;
   char *point2;
   char buf[MAX_STRING_LENGTH];

   buf[0] = '\0';
   point2 = buf;
   for( point = txt ; *point ; point++ )
   {
       if( *point == '{' )
       {
           point++;
	   if ( *point == COLOR_CHAR )
	   {
		*point2 = *point;
		*++point2 = '\0';
	   }
           continue;
       }
       *point2 = *point;
       *++point2 = '\0';
   }
   *point2 = '\0';
   *buffer = '\0';
   strcpy( buffer, buf );

   return strlen( buffer );
}

void color_convert( CHAR_DATA *ch, const char *text, char *buffer )
{
    const char *point;
    CHAR_DATA *vch;
    int skip = 0;

    if ( !text )
	return;

    if ( (vch = ch) != NULL &&
	 IS_NPC(ch) )
    {
	if ( ch->desc && ch->desc->original )
	    vch = ch->desc->original;
    }

    if ( !vch || (!IS_NPC(vch) && IS_SET( vch->act, PLR_COLOR )) )
    {
	for ( point = text; *point; point++ )
	{
	    if ( *point == COLOR_CHAR )
	    {
		point++;
		skip = color( vch, *point, buffer );
		while( skip-- > 0 )
		    ++buffer;
		continue;
	    }
	    *buffer = *point;
	    *++buffer = '\0';
	}
	*buffer = '\0';
    }
    else
    {
	strip_ansii( text, buffer );
    }
    return;
}

void reset_colors( CHAR_DATA *ch )
{
    int icolor;

    if ( IS_NPC(ch) || !ch->desc )
	return;

    for ( icolor = 0; icolor < MAX_CUSTOM_COLORS; icolor++ )
	ch->pcdata->colors[icolor] = custom_colors[icolor].default_color;

    return;
}

void set_color( CHAR_DATA *ch, const char *position, const char *color )
{
    int icolor, iposition;

    iposition = custom_color_lookup( position );
    icolor = color_lookup( color );

    ch->pcdata->colors[iposition] = color_table[icolor].flag;

    return;
}

void do_color( CHAR_DATA *ch, char *argument )
{
    int icolor, col;
    char result[MAX_STRING_LENGTH];
    char buf[MAX_STRING_LENGTH];
    char arg[MAX_INPUT_LENGTH];
    char position[MAX_INPUT_LENGTH];

    if ( IS_NPC( ch ) )
	return;

    if ( argument[0] == '\0' )
    {
	TOGGLE_BIT( ch->act, PLR_COLOR );
	sprintf( buf, "Color turned %s\n\r", 
	    IS_SET( ch->act, PLR_COLOR ) ? "{CON{x" : "OFF" );
	send_to_char( buf, ch );
	return;
    }

    arg[0] = '\0';
    argument = one_argument( argument, arg );

    if ( !str_cmp( arg, "on" ) )
    {
	if ( !IS_SET( ch->act, PLR_COLOR ) )
	    SET_BIT( ch->act, PLR_COLOR );
        send_to_char( "Color turned {CON{x\n\r", ch );
        return;
    }

    if ( !str_cmp( arg, "off" ) )
    {
	if ( IS_SET( ch->act, PLR_COLOR ) )
	    REMOVE_BIT( ch->act, PLR_COLOR );
        send_to_char( "Color turned OFF\n\r", ch );
        return;
    }

    result[0] = '\0';

    if ( !str_cmp( arg, "help" ) )
    {
	col = 0;

	for ( icolor = 0; color_table[icolor].color; icolor++ )
	{
	    if ( !color_table[icolor].visible )
		continue;

	    sprintf( buf, "{x[{%s%-14s {{%s{x] ",
		color_table[icolor].letter,
		color_table[icolor].color,
		color_table[icolor].letter );
	    if ( ++col % 4 == 0 )
		strcat( buf, "\n\r" );
	    strcat( result, buf );
	}
	
	if ( col % 4 != 0 )
	    strcat( result, "\n\r" );
	send_to_char( result, ch );
	return;
    }

    if ( !str_cmp( arg, "show" ) )
    {
	col = 0;

	for ( icolor = 0; icolor < MAX_CUSTOM_COLORS; icolor++ )
	{
	    if ( ch->level < custom_colors[icolor].level )
		continue;

	    sprintf( buf, "{%s%-12s{x ",
		color_table[get_color(ch->pcdata->colors[icolor])].letter,
		custom_colors[icolor].position );

	    if ( ++col % 4 == 0 )
		strcat( buf, "\n\r" );
	    strcat( result, buf );
	}

	if ( col % 4 != 0 )
	    strcat( result, "\n\r" );

	send_to_char( result, ch );
	return;
    }

    position[0] = '\0';

    if ( !str_cmp( arg, "set" ) )
    {

	argument = one_argument( argument, position );

	if ( position[0] == '\0' )
	{
	    send_to_char( "COLOR SHOW to see available custom colors.\n\r", ch );
	    return;
	}

	if ( custom_color_lookup( position ) < 0 )
	{
	    send_to_char( "COLOR SHOW to see available custom colors.\n\r", ch );
	    return;
	}

	if ( argument[0] == '\0' )
	{
	    send_to_char( "COLOR SHOW to see available custom colors.\n\r", ch );
	    return;
	}
	
	if ( color_lookup( argument ) < 0 )
	{
	    send_to_char( "COLOR HELP to see available custom colors.\n\r", ch );
	    return;
	}

	set_color( ch, position, argument );
	return;
    }

    return;
}

void save_char_color( CHAR_DATA *ch, FILE *fp )
{
    char buf[MAX_INPUT_LENGTH];
    int icolor;

    if ( !ch->pcdata || IS_NPC(ch) || !fp )
	return;

    fprintf( fp, "Colors " );

    buf[0] = '\0';

    for ( icolor = 0; icolor < MAX_CUSTOM_COLORS; icolor++ )
	fprintf( fp, "%s", fwrite_flag( ch->pcdata->colors[icolor], buf ) );

    fprintf( fp, "~\n" );

    return;
}

void load_char_colors( CHAR_DATA *ch, FILE *fp )
{
    char letter = '~';
    int icolor;

    for ( icolor = 0; icolor < MAX_CUSTOM_COLORS; icolor++ )
    {
	if ( (letter = fread_letter(fp)) == '~' )
	    break;

	ch->pcdata->colors[icolor] = flag_convert( letter );
    }

    while( letter != '~' )
	letter = fread_letter( fp );	

    return;
}