/*
 * 4m v2.15 (misc.c)
 * (C) Copyright 1990 by Carrick Sean Casey
 * (C) Copyright 1993 by Scott Chasin and Michaeljon Miller
 *
 * 3-24-93 See file COPYING for copyright information.
 *
 * Miscellaneous routines
 */

#include "4m.h"
#include "externs.h"

#include "../h/term.h"

#include <sys/types.h>
#include <sys/stat.h>

#ifdef SYSTIME
#include <sys/time.h>
#else
#include <time.h>
#endif

#include <ctype.h>

#ifdef HAS_STRINGS
# include <strings.h>
#endif

#ifdef HAS_STRING
# include <string.h>
#endif

/*
 * c h e c k _ m a i l
 *
 * Returns 1 if new mail has arrived, 0 if not.
 */


extern int fclose ();
void blok ();
char *local_ampm ();
extern time_t time ();
char *ontime ();
char *signon_time();
extern int write ();
extern int atoi ();

int check_mail()
{
    struct stat stb;
    time_t ltime = (time_t) 0;
    static int checked = 0;
    static int counter = 1;

    if ((stat(mbox, &stb) == -1)) {
        return 0;
    }

    if (!checked) {
        timestamp = stb.st_mtime;
        checked = !checked;
    }
    ltime = stb.st_mtime;

    if (ltime != timestamp && stb.st_size != 0) {
        mail = TRUE;
        timestamp = ltime;
        return 1;
    } else {
        mail = FALSE;
        return 0;
    }
}

/*
 * c o u n t _ m a i l
 *
 * Returns the # of letters in the users mailbox.
 */

int count_mail()
{
    int i = 0;
    char buffer[1024];
    FILE *fp;

    if ((fp = fopen(mbox, "r")) != NULL) {
        while ((fgets(buffer, 1024, fp)) != NULL) {
            if (!strncmp("From ", buffer, sizeof("From ") - 1))
                i++;
        }
        fclose(fp);
    }
    return i;
}


/*
 *  b u i l d
 *
 *  Print or construct any % sequence. Refer to the documentation
 *  for an explanation of the % codes. If d (destination) is NULL, the
 *  string generated is printed, otherwise it is placed into d.
 *
 *  The special character ^ toggles VT100 inverse mode on and off.
 *
 */

void build(s, d)
     char *s;
     char *d;
{

    if (d)
        *d = 0;

    while (*s) {
        if (d)
            while (*d)
                d++;

        if (*s == '^') {
            s++;
            if (inverse) {
                setnormal();
            } else {
                setinverse();
            }
        } else if (*s != '%') {
            if (d) {
                *d++ = *s++;
                *d = 0;
            } else
                put(*s++);
        } else
            switch (s++, *s++) {
                case 'A':
                    blok("%s", d, away ? "Away" : " ");
                    break;

                case 'B':
                    blok("%s", d, strlen(awaymsg) > 2 ? awaymsg : " ");
                    break;

                case 'C':
                    blok("%s", d, nick);
                    break;

                case 'G':
                    blok("%s", d, group);
                    break;

                case 'M':
                    blok("%s", d, local_ampm(time(NULL), 1));
                    break;

                case 'I':
                    blok("%s", d, insert_mode ? "INS" : "OVR");
                    break;

                case 'S':
                    blok("%s", d, gv.default_host);
                    break;

                case 'N':
                    blok("%s", d, msg_from);
                    break;

                case 'O':
                    blok("%s", d, mode);
                    break;

                case 'P':
                    blok("%d", d, (char *) gv.default_port);
                    break;

                case 'T':
                    blok("%s", d, local_ampm(time(NULL), 0));
                    break;

                case 'V':
                    blok("%s", d, VERSION);
                    break;

                case 'm':
                    blok("%s", d, mail ? "Mail Waiting" : "            ");
                    break;

                case '&':
                    blok("%d", d, (char *) count_mail());
                    break;

                case '#':
                    blok("%s", d, msg_str);
                    break;

                case '@':
                    blok("%s", d, ontime(startup_t));
                    break;

                case '%':
                    blok("%%", d, "");
                    break;

                case '|':
                    blok("\n", d, "");
                    break;

                case '^':
                    blok("^", d, "");
                    break;

                case 0:
                    return;
            }
    }

    return;
}

/*
 *  b l o k
 *
 *  A kludged way to allow any type of variable to be printed or
 *  displayed without using vsprint.
 *
 */

/*VARARGS2*/

void blok(format, dest, item)
     char *format;
     char *dest;
     char *item;
{
    char out[1024];

    sprintf(out, format, item);

    if (dest)
        strcat(dest, out);
    else
        write(1, out, strlen(out));

    return;
}


char *idle_time (moment)
long moment;
{
    long since;
    int sec, min, hour, day, week;
    static char idletime[8];

    since = moment;
    sec = since;
    since /= 60;

    min = since % 60;
    since /= 60;

    hour = since % 24;
    since /= 24;

    day = since % 7;
    since /= 7;
/*
sprintf (idletime, "%dh %dm %d", hour, min, moment);
*/
    if (sec == 0)
       strcpy (idletime, "  -");
    if (sec > 0 && sec < 60)
       sprintf (idletime, " %ds", sec);
    if (min > 0 && min < 60)
       sprintf (idletime, " %dm", min);
    if (hour > 0 && hour < 24)
       sprintf (idletime, " %dh", hour);
    if (day > 0 && day < 7)
       sprintf (idletime, " %dd", day);
    if (day >= 7)
       sprintf (idletime, " %dw", since);
    return (idletime);
}

char *
idlephrase(num)
     char *num;
{
    int seconds = atoi(num);
    static char idlestring[20];

    if (seconds < 60)
        sprintf(idlestring, "%d seconds", seconds);
    else if (seconds > 60 && seconds < 3600)
        sprintf(idlestring, "%d minute(s)", seconds / 60);
    else if (seconds > 3600 && seconds < 21600)
        sprintf(idlestring, "%d hour(s)", seconds / 3600);
    return (idlestring);
}

/* return a string indicating response time */

char *
response(num)
     char *num;
{
    int secs = atoi(num);
    static char rtime[8];

    if (secs >= 2) {
        sprintf(rtime, " %2ds", secs);
        return (rtime);
    } else
        return ("   -");
}

char *
ontime(when)
     long int when;
{
    int m, h;
    long now, s;
    static char buf[10];

    now = time(NULL);
    s = now - when;
    m = s / 60L;
    h = m / 60L;

    if (h)
        m = m % 60;

    sprintf(buf, "%02d:%02d", h, m);
    return (buf);
}


/* return a time, i.e "7:45pm" */

char *
local_ampm(secs, style)
     time_t secs;
     int style;
{

    struct tm *t, *localtime();

    static char timestr[12];
    int hr, mn;

    t = localtime(&secs);
    hr = t->tm_hour;
    mn = t->tm_min;

    if (style) {
        sprintf(timestr, "%02d:%02d", hr, mn);
        return (timestr);
    }
    if (hr >= 12)
        sprintf(timestr, "%2d:%02dpm", (hr > 12) ? hr - 12 : hr, mn);
    else if (hr > 0)
        sprintf(timestr, "%2d:%02dam", hr, mn);
    else
        sprintf(timestr, "12:%02dam", mn);

    return (timestr);
}

char *
gm_ampm(secs, style)
     time_t secs;
     int style;
{
    struct tm *t, *gmtime();
    static char timestr[12];
    int hr, mn;

    t = gmtime(&secs);
    hr = t->tm_hour;
    mn = t->tm_min;

    sprintf(timestr, "%02d%02dGMT", hr, mn);

    return (timestr);
}

char *
datestr(when)
     time_t when;
{
    struct tm *ptm, *gmtime();
    static char date[15];

    ptm = gmtime(&when);

    sprintf(date, "%d/%d/%d", ptm->tm_mon, ptm->tm_mday, ptm->tm_year);

    return (date);
}
void 
cipher(str, len, key)
     char *str;
     int len;
     char *key;
{
    int key_len, key_pos, i;
    char mix, tmp;

    key_len = strlen(key);
    key_pos = 0;
 /* mix = key[key_len-1]; */
    mix = 0;
    for (i = 0; i < len; i++) {
        tmp = str[i];
        str[i] = mix ^ tmp ^ key[key_pos];
        mix ^= tmp;
        key_pos = (key_pos + 1) % key_len;
    }
    str[len] = '\0';

    return;
}

void 
decipher(str, len, key)
     char *str;
     int len;
     char *key;
{
    int key_len, key_pos, i;
    char mix, tmp;

    key_len = strlen(key);
    key_pos = 0;
 /* mix = key[key_len-1]; */
    mix = 0;
    for (i = 0; i < len; i++) {
        tmp = mix ^ str[i] ^ key[key_pos];
        str[i] = tmp;
        mix ^= tmp;
        key_pos = (key_pos + 1) % key_len;
    }
    str[len] = '\0';

    return;
}

char *signon_time(moment)
long moment;
{
   long now, since;
   int min, hour, day;
   static char stime [15];

   now = time(NULL);

   since  = now - moment;
   since /= 60;               

   min = since % 60;
   since /= 60;

   hour = since % 24;
   since /= 24;

   day = since % 7;
   since /= 7;

   if (day > 0)  
      if (strlen (datestr (moment)) == 6)
        sprintf (stime, " %s", datestr (moment));
      else
        sprintf (stime, "%s", datestr (moment));
   else
      sprintf (stime, "%s",  local_ampm (moment, 0));

   return (stime);
}
