/* ************************************************************************
*  file: utility.c, Utility module.                       Part of DIKUMUD *
*  Usage: Utility procedures                                              *
*  Copyright (C) 1990, 1991 - see 'license.doc' for complete information. *
************************************************************************* */

#include <stdio.h>
#include <strings.h>
#include <ctype.h>
#include <assert.h>

#include "structs.h"
#include <time.h>
#include "utils.h"

extern struct time_data time_info;


int MIN(int a, int b)
{
	return a < b ? a:b;
}


int MAX(int a, int b)
{
	return a > b ? a:b;
}

/* creates a random number in interval [from;to] */
int number(int from, int to) 
{
	if(to<from) to=from;
	return((random() % (to - from + 1)) + from);
}



/* simulates dice roll */
int dice(int number, int size) 
{
  int r;
  int sum = 0;

	assert(size >= 1);

  for (r = 1; r <= number; r++) sum += ((random() % size)+1);
  return(sum);
}



/* Create a duplicate of a string */
char *strdup(char *source)
{
	char *new;

	CREATE(new, char, strlen(source)+1);
	return(strcpy(new, source));
}



/* returns: 0 if equal, 1 if arg1 > arg2, -1 if arg1 < arg2  */
/* scan 'till found different or end of both                 */
int str_cmp(char *arg1, char *arg2)
{
	int chk, i;

	for (i = 0; *(arg1 + i) || *(arg2 + i); i++)
		if (chk = LOWER(*(arg1 + i)) - LOWER(*(arg2 + i)))
			if (chk < 0)
				return (-1);
			else 
				return (1);
	return(0);
}



/* returns: 0 if equal, 1 if arg1 > arg2, -1 if arg1 < arg2  */
/* scan 'till found different, end of both, or n reached     */
int strn_cmp(char *arg1, char *arg2, int n)
{
	int chk, i;

	for (i = 0; (*(arg1 + i) || *(arg2 + i)) && (n>0); i++, n--)
		if (chk = LOWER(*(arg1 + i)) - LOWER(*(arg2 + i)))
			if (chk < 0)
				return (-1);
			else 
				return (1);

	return(0);
}



/* writes a string to the log */
void log(char *str)
{
	long ct;
	char *tmstr;

	ct = time(0);
	tmstr = asctime(localtime(&ct));
	*(tmstr + strlen(tmstr) - 1) = '\0';
	fprintf(stderr, "%s :: %s\n", tmstr, str);
}
	


void sprintbit(long vektor, char *names[], char *result)
{
	long nr;

	*result = '\0';

	for(nr=0; vektor; vektor>>=1)
	{
		if (IS_SET(1, vektor))
			if (*names[nr] != '\n') {
				strcat(result,names[nr]);
				strcat(result," ");
			} else {
				strcat(result,"UNDEFINED");
				strcat(result," ");
			}
		if (*names[nr] != '\n')
		  nr++;
	}

	if (!*result)
		strcat(result, "NOBITS");
}



void sprinttype(int type, char *names[], char *result)
{
	int nr;

	for(nr=0;(*names[nr]!='\n');nr++);
	if(type < nr)
		strcpy(result,names[type]);
	else
		strcpy(result,"UNDEFINED");
}


/* Calculate the REAL time passed over the last t2-t1 centuries (secs) */
struct time_info_data real_time_passed(time_t t2, time_t t1)
{
	long secs;
	struct time_info_data now;

	secs = (long) (t2 - t1);

  now.hours = (secs/SECS_PER_REAL_HOUR) % 24;  /* 0..23 hours */
  secs -= SECS_PER_REAL_HOUR*now.hours;

  now.day = (secs/SECS_PER_REAL_DAY);          /* 0..34 days  */
  secs -= SECS_PER_REAL_DAY*now.day;

	now.month = -1;
  now.year  = -1;

	return now;
}



/* Calculate the MUD time passed over the last t2-t1 centuries (secs) */
struct time_info_data mud_time_passed(time_t t2, time_t t1)
{
	long secs;
	struct time_info_data now;

	secs = (long) (t2 - t1);

  now.hours = (secs/SECS_PER_MUD_HOUR) % 24;  /* 0..23 hours */
  secs -= SECS_PER_MUD_HOUR*now.hours;

  now.day = (secs/SECS_PER_MUD_DAY) % 35;     /* 0..34 days  */
  secs -= SECS_PER_MUD_DAY*now.day;

	now.month = (secs/SECS_PER_MUD_MONTH) % 17; /* 0..16 months */
  secs -= SECS_PER_MUD_MONTH*now.month;

  now.year = (secs/SECS_PER_MUD_YEAR);        /* 0..XX? years */

	return now;
}



struct time_info_data age(struct char_data *ch)
{
	long secs;
	struct time_info_data player_age;

	player_age = mud_time_passed(time(0),ch->player.time.birth);

  player_age.year += 17;   /* All players start at 17 */

	return player_age;
}

int default_loc(int hometown)
{
	switch(hometown) {
		case 0:
			return(1200);
			break;
		case 1:
			return(3001);
			break;
		case 2:
			return(12591);
			break;
		default:
			log("Bad hometown!");
			break;
	}
}

int jail_hometown(int hometown)
{
	switch(hometown) {
		case 0:
			return(10);
			break;
		case 1:
			return(3067);
			break;
		case 2:
			return(12585);
			break;
		default:
			log("Bad hometown!");
			break;
	}
}

void strToLower(char *s1)
{
   int i, len;

   len = strlen(s1);
   for (i = 0; i < len; i++) {
	if(s1[i] >= 'A' && s1[i] <= 'Z')
		s1[i] += 'a'-'A';
   }
} /* strToLower */

#if CONFIG_STRSTR
/*
 * PURPOSE:
 *    strstr() locates the first occurrence in the string pointed to by s1 of
 *    the sequence of characters in the string pointed to by s2.  A NULL value
 *    is returned if s2 was not found within s1.
 */
char *strstr (s1, s2)
   char *s1;
   char *s2;
{
   char *s1Ptr; /* A pointer into string s1 */
   char *s2Ptr; /* A pointer into string s2 */

   if (*s2 == '\0') {
     return s1;
   } /* if */

   while (*s1 != '\0') {
      if (*s1 == *s2) {

         s1Ptr = s1;
         s2Ptr = s2;

         while ((*s1Ptr != '\0') && (*s1Ptr == *s2Ptr)) {
            ++s1Ptr;
            ++s2Ptr;
	 } /* while */

	 if (*s2Ptr == '\0') {
            /*
             * At this point the entire s2 string has been processed.
             * This implies that the substring was found in s1.
             */
            return s1;
	 } /* if */
         else if (*s1Ptr == '\0') {
            /*
             * If were at the end of s1 and not at the end of s2
             * the substring doesn't exist.
             */
            return NULL;
	 } /* if */
      } /* if */
      ++s1;
   } /* while */

   return NULL;

} /* strstr */
#endif