/*
    Status line management file
    Copyright (c) 1993, 1994 Tudor Hulubei & Andrei Pitis

This file is part of UIT (UNIX Interactive Tools)

UIT is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2, or (at your option) any later version.

UIT is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
details .

You should have received a copy of the GNU General Public License along with
UIT; see the file COPYING.  If not, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA.  */


#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/utsname.h>

#include "tty.h"
#include "xmalloc.h"
#include "window.h"
#include "status.h"
#include "config.h"
#include "misc.h"


extern int  AnsiColorSequences;


static window *status_win = NULL;
static char *stemp;
static int columns;
static int line;
static char *default_msg;
static char dummy[] = "";
static struct utsname u;


#define STATUSBAR_FIELDS	9

static char *StatusBarFields[STATUSBAR_FIELDS] =
{
    "StatusBarForeground",
    "StatusBarBackground",
    "StatusBarBrightness",
    "StatusBarWarningForeground",
    "StatusBarWarningBackground",
    "StatusBarWarningBrightness",
    "StatusBarErrorForeground",
    "StatusBarErrorBackground",
    "StatusBarErrorBrightness"
};

#ifdef HAVE_LINUX
static int StatusBarColors[STATUSBAR_FIELDS] =
{
    BLACK, CYAN, OFF, BLACK, WHITE, OFF, WHITE, RED, ON
};
#else	/* not HAVE_LINUX */
static int StatusBarColors[STATUSBAR_FIELDS] =
{
    BLACK, WHITE, OFF, BLACK, WHITE, OFF, BLACK, WHITE, ON
};
#endif	/* not HAVE_LINUX */

#define StatusBarForeground 		StatusBarColors[0]
#define StatusBarBackground 		StatusBarColors[1]
#define StatusBarBrightness 		StatusBarColors[2]
#define StatusBarWarningForeground 	StatusBarColors[3]
#define StatusBarWarningBackground 	StatusBarColors[4]
#define StatusBarWarningBrightness 	StatusBarColors[5]
#define StatusBarErrorForeground 	StatusBarColors[6]
#define StatusBarErrorBackground 	StatusBarColors[7]
#define StatusBarErrorBrightness 	StatusBarColors[8]


char *day_name[] =
{
    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};


char *month_name[] =
{
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};


void status_init(int _columns, int _begin_y, char *def_msg)
{
    char *data;
    int index, i;
    
    columns	= _columns;
    line	= _begin_y;
    default_msg	= def_msg;
    status_win	= window_init(0, _begin_y, 1, _columns);
    stemp	= xmalloc(columns);

    uname(&u);


    use_section(AnsiColorSequences ? cSection : bwSection);

    get_colorset_var(StatusBarColors, StatusBarFields, STATUSBAR_FIELDS);
}


void status_end(void)
{
    window_end(status_win);
}


static void build_msg(char *msg_name)
{
    time_t time_value;
    char date_str[32];
    char *ptr, *temp_msg;
    struct tm *time_struct;
    int i, j, len, temp_msg_len;


    memset(stemp, ' ', columns);
    if (msg_name == NULL) msg_name = default_msg;

    temp_msg = xmalloc(temp_msg_len = (strlen(msg_name) + 1));

    for (i = 0, j = 0; msg_name[i]; i++)
	if (msg_name[i] == '\\')
	    switch (msg_name[i + 1])
	    {
		case 'h' :	ptr = u.nodename;	goto get_system_info;
		case 's' :	ptr = u.sysname;	goto get_system_info;
		case 'm' :	ptr = u.machine;

			    get_system_info:

				if (ptr[0])
				{
				    len = strlen(ptr);
				    temp_msg = xrealloc(temp_msg,
				    			temp_msg_len += len);
				    memcpy(&temp_msg[j], ptr, len);
				}
				else
				{
				    len = 6;
				    temp_msg = xrealloc(temp_msg,
				    			temp_msg_len += len);
				    memcpy(&temp_msg[j], "(none)", len);
				}

				j += len;
				i++;
				break;

		case 'd' :	time(&time_value);
				time_struct = localtime(&time_value);
				sprintf(date_str, "%s %s %02d %d",
					day_name[time_struct->tm_wday],
					month_name[time_struct->tm_mon],
					time_struct->tm_mday,
					time_struct->tm_year + 1900);
				len = strlen(date_str);
				temp_msg = xrealloc(temp_msg,
						    temp_msg_len += len);
				memcpy(&temp_msg[j], date_str, len);
				j += len;
				i++;
				break;

		case '\\':	temp_msg[j++] = '\\';
				i++;
				break;

		case '\0':	temp_msg[j++] = '\\';
				break;

		default  :	temp_msg[j++] = '\\';
				temp_msg[j++] = msg_name[++i];
				break;
	    }
	else
	    temp_msg[j++] = msg_name[i];

    temp_msg[j] = 0;

    len = strlen(msg_name = temp_msg);

    if (len < columns)
        memcpy(stemp + ((columns - len) >> 1), msg_name, len);
    else
        memcpy(stemp, msg_name, columns);

    free(temp_msg);

    for (i = 0; i < columns; i++)
        if (stemp[i] == '\r' || stemp[i] == '\n' || stemp[i] == '\t')
            stemp[i] = ' ';
}


int status(char *msg_name, int wait, int sound, int restore, int msg_type)
{
    int key = 0;
    tty_status status;
    struct key_struct *ks;


    tty_save(&status);
    tty_cursor(OFF);

    build_msg(msg_name);

    if (sound) tty_beep();

    switch (msg_type)
    {
        case MSG_WARNING:

	    tty_bright(StatusBarWarningBrightness);
	    tty_foreground(StatusBarWarningForeground);
	    tty_background(StatusBarWarningBackground);
	    break;

        case MSG_ERROR:

	    tty_bright(StatusBarErrorBrightness);
	    tty_foreground(StatusBarErrorForeground);
	    tty_background(StatusBarErrorBackground);
	    break;

        default:

	    tty_bright(StatusBarBrightness);
	    tty_foreground(StatusBarForeground);
	    tty_background(StatusBarBackground);
	    break;
    }

    window_cursormove_notify(status_win, 0, 0);
    window_write(stemp, columns);

    if (wait)
    {
	ks = tty_getkey(NULL);
	window_cursormove(status_win, line, columns);
	key = ks->key_seq[0];
    }

    if (restore)
    {
	build_msg(default_msg);

        tty_bright(StatusBarBrightness);
        tty_foreground(StatusBarForeground);
        tty_background(StatusBarBackground);

        window_cursormove_notify(status_win, 0, 0);
        window_write(stemp, columns);
    }

    tty_restore(&status);
    return key;
}
