muddy/
muddy/CVS/
muddy/area/
muddy/area/CVS/
muddy/clans/CVS/
muddy/classes/CVS/
muddy/doc/
muddy/doc/CVS/
muddy/etc/CVS/
muddy/etc/i3/
muddy/etc/i3/CVS/
muddy/imc/CVS/
muddy/lang/CVS/
muddy/licenses/CVS/
muddy/msgdb/CVS/
muddy/new/CVS/
muddy/notes/
muddy/player/
muddy/races/CVS/
muddy/religions/CVS/
muddy/src/CVS/
muddy/src/comm/CVS/
muddy/src/db/CVS/
muddy/src/intermud/
muddy/src/intermud/CVS/
muddy/src/irc/CVS/
muddy/src/olc/CVS/
#include <stdio.h>
#include "defs.h"
#if	defined (WIN32)
#	include <compat/compat.h>
#else
#	include <dirent.h>
#endif
//#include "compat/compat.h"
#include "str.h"
#include "util.h"
#include "files.h"

#define MAX_POSITIONS 10
#define MAX_FIELD_NAME_LEN 70
#define MAX_PNAME_LEN 20
#define MAX_PLAYER 100

typedef struct rank_player	 RANK_PLAYER;
struct rank_player
{
	char PName[MAX_PNAME_LEN]; 
	int Values[MAX_POSITIONS]; 
};

typedef struct rank_data	 RANK_DATA;
struct rank_data
{
	char *name; 
	char *pfile_field; 
	char *output_file_name; 
	int MinValue;
};

static RANK_DATA rankings[MAX_POSITIONS];

static int PositionCount;
static int Number;

/* local functions */
unsigned int BuildRankings(RANK_PLAYER ** result );
void ReadRankingDescr (void);
int compare( const void *arg1, const void *arg2 ); 
/*************************************/

void main (void)
{
    RANK_PLAYER * rank;
	unsigned int Count, i;
	int j;
	FILE * ResFile;


	ReadRankingDescr();
	printf("%d\n",PositionCount);
	Count = BuildRankings(&rank);

	if ((ResFile = dfopen (TMP_PATH, ALL_RANKS_FILE, "w")) == NULL)
		{
			printf ("BuildRankings: Can't open file %s.",ALL_RANKS_FILE);
			return;
		}

	for (i = 0; i < Count; i++)
	{
		fprintf(ResFile, "%s ", rank[i].PName);
		for (j = 0; j < PositionCount; j++)
			fprintf(ResFile, "%d ",rank[i].Values[j]);
		fprintf(ResFile, "\n");
	}
	fclose (ResFile);

	for (Number = 0; Number < PositionCount; Number++)
	{
		if ((ResFile = dfopen (TMP_PATH, rankings[Number].output_file_name, "w")) == NULL)
		{
			printf ("BuildRankings: Can't open file %s.",
				rankings[Number].output_file_name);
			return;
		}
		
		qsort((void*)rank, Count, sizeof(RANK_PLAYER), compare);
		printf("%s\n",rankings[Number].name);
		for (i = 0; i < Count; i++)
		{
			if (rank[i].Values[Number] == 0)
				break;
			fprintf(ResFile,"%s %d\n", rank[i].PName, rank[i].Values[Number]);
		}
		fclose (ResFile);
	}

}

unsigned int BuildRankings(RANK_PLAYER ** result)
{
    struct dirent * dp ;

    DIR  * dirp   ;
    FILE * pfile  ;
    char   letter ;
    char * word   ;
	bool section_ended, found, not_empty;
	int CurrValue, i;
	int Reserved = 0, Filled = 0;

    if ((dirp = opendir (PLAYER_PATH)) == NULL)
    {
        printf ("BuildRankings: unable to open player directory.");
        exit(1) ;
    }

	
	if (!(*result = malloc(sizeof(RANK_PLAYER)*MAX_PLAYER)))
		return 0;
	Reserved = MAX_PLAYER;

    for (dp = readdir (dirp) ; dp != NULL ; dp = readdir (dirp))
    {
        const char * pname ;

        // only BSD implementation has d_type member of dirent structure
        #if defined (__FreeBSD__)
        if (dp->d_namlen < 3 || dp->d_type != DT_REG) continue ;
        #else
        if (strlen(dp->d_name) < 3) continue ;
        #endif

        // do not process HOLDER_LIST file in any
        if (!str_cmp (dp->d_name, HOLDER_LIST)) continue ;

        // open pfile
		//printf("processing %s\n", dp->d_name);
        if ((pfile = dfopen (PLAYER_PATH, dp->d_name, "r")) == NULL)
        {
            printf ("BuildRankings: Can't open player file %s.",
                 dp->d_name) ;
            continue ;
        }

        // look through player data
        pname = NULL ;
		section_ended = FALSE;

        for (;;)
        {
            if (section_ended)
				break;

			letter = fread_letter (pfile) ;

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

            if (letter != '#')
            {
                printf ("BuildRankings: # not found in %s.\n",
                            dp->d_name) ;
                break ;
            }

            word = fread_word (pfile) ;

            // process player section
            if (!str_cmp (word, "PLAYER"))
            {
				not_empty = FALSE;
                for (;;)
                {
                    word = fread_word (pfile) ;

                    // until EOF or End
                    if (feof (pfile) || !word || !str_cmp (word, "End")) 
					{
						section_ended = TRUE;
						if (not_empty)
						{
							Filled++;
							if(Filled == Reserved)
							{
								Reserved += MAX_PLAYER;
								if (!(*result = realloc(*result,sizeof(RANK_PLAYER)*Reserved)))
									return 0;
							}
						}
						break;
					}

                    // load player name
                    if (!str_cmp (word, "Name"))
                    {
                        free_string (pname) ;
                        pname = fread_string (pfile);
						memset ((*result)+Filled, 0, sizeof(RANK_PLAYER));
						memcpy ((*result)[Filled].PName, pname, UMAX(strlen(pname),MAX_PNAME_LEN-1));
						//printf("name=%s\n",pname);
                    }
					else
					{
						found = FALSE;
						for (i = 0; i < PositionCount; i++)
						{
							if (!str_cmp (word, rankings[i].pfile_field))
							{
								CurrValue = fread_number(pfile);
								if (CurrValue >= rankings[i].MinValue)
								{
									found = TRUE;
									not_empty = TRUE;
									(*result)[Filled].Values[i] = CurrValue;
									//printf("%s = %d\n",word, CurrValue);
									break;
								}
							}
						}
						if (!found)
							fread_to_eol (pfile);

					}
                }
            }
        }

        free_string (pname) ;
        fclose      (pfile) ;
    }

    closedir (dirp) ;
	// final realloc - free unused space
	if (!(*result = realloc(*result,sizeof(RANK_PLAYER)*Filled)))
		return 0;
	return Filled;
}

void ReadRankingDescr (void)
{
	FILE * DescFile;
	int Num = 0;

	if ((DescFile = dfopen (ETC_PATH, RANK_DESC_FILE, "r")) == NULL)
	{
		printf ("BuildRankings: Can't open player file %s.",
			RANK_DESC_FILE) ;
		return;
	}
	for (;;)
        {
			rankings[Num].name = fread_string (DescFile);
			rankings[Num].pfile_field = fread_string (DescFile);
			//printf("%s\n",rankings[Num].pfile_field);
			rankings[Num].MinValue = fread_number (DescFile);
			rankings[Num].output_file_name = fread_string (DescFile);

			Num++;

			if (feof (DescFile) || Num > MAX_POSITIONS)
				break;
		}
	fclose (DescFile);
	PositionCount = Num;
}

int compare( const void *arg1, const void *arg2 )
{
      return ((RANK_PLAYER *)arg2)->Values[Number] - ((RANK_PLAYER *)arg1)->Values[Number];
}