/***********************************************************
	util.c -- utility routines
***********************************************************/
#include <stdio.h>
#include <io.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <ctype.h>
#include <time.h>
#include <stdlib.h>
#include <stdarg.h>
#include "lh.h"
#include "intrface.h"
#include "errmes.h"

uchar pathdelim = '\\';
uchar swchar;

/***************************************
	convert path delimiter
****************************************
	returns *filename
***************************************/
char *convdelim(char *path, char delim)
{
	uchar c;
	uchar *p;
	int kflg;

	kflg = 0;
	for (p = path; (c = *p) != 0; p++) {
		if (kflg) {
			kflg = 0;
		} else if (iskanji(c)) {
			kflg = 1;
		} else if (c == '\\' || c == DELIM || c == DELIM2) {
			*p = delim;
			path = p + 1;
		}
	}
	return path;
}

char *getfilename(char *path)
{
	char *q;

	if ((q = strrchr(path, DELIM)) != NULL ||
		(q = strchr(path, ':')) != NULL) {
		return q + 1;
	} else {
		return path;
	}
}

/*******************************
  get back to parent directory
*******************************/
char *backpath(char *p)
{
	char *q;

	q = getfilename(p);
	*q = '\0';
	return q;
}

/*******************************
		ask 'Y' or 'N'
*******************************/
int getyn(void)
{
	int yn;

	do {
		yn = getch();
		yn = toupper(yn);
		if (yn == '\x03') error(CTRLBRK, NULL);
	} while (yn != 'Y' && yn != 'N');
	eprintf("%c\n", yn);
	return yn;
}

void getswchar(void)
{
	union REGS regs;

	regs.x.ax = 0x3700;
	intdos(&regs, &regs);
	swchar = regs.h.dl;
	if (swchar != '/') {
		pathdelim = '/';
	}
}

time_t dos2unix(struct ftime *ft)
{
	struct tm tm;

	tm.tm_sec   = ft -> ft_tsec * 2;
	tm.tm_min   = ft -> ft_min;
	tm.tm_hour  = ft -> ft_hour;
	tm.tm_mday  = ft -> ft_day;
	tm.tm_mon   = ft -> ft_month - 1;
	tm.tm_year  = ft -> ft_year + 80;
	tm.tm_isdst = timezone;
	return mktime(&tm);
}

struct ftime *unix2dos(time_t utc)
{
	static struct ftime ft;
	struct tm *tm;

	tm = localtime(&utc);
	ft.ft_tsec     = tm -> tm_sec / 2;
	ft.ft_min      = tm -> tm_min ;
	ft.ft_hour     = tm -> tm_hour;
	ft.ft_day      = tm -> tm_mday;
	ft.ft_month    = tm -> tm_mon  + 1;
	ft.ft_year     = tm -> tm_year - 80;
	return &ft;
}

/*******************************
		ratio * 1000
*******************************/
int ratio(ulong a, ulong b, int ord)
{
	int i;

	for (i = 0; i < ord && a < 0x19999999; i++) {
		a *= 10;				/* while not overflow */
	}							/* upto 10^ord times */
	for (; i < ord; i++) {		/* the case of overflow */
		b /= 10;
	}
	if (b == 0) return 0;		/* if diviser == 0 */
	a += b / 2;					/* for round up */
	return (a / b);				/* return (a * 1000 / b) */
}

#define BUFFERSIZE 0x6000

void copyfile(FILE *f1, FILE *f2, long size, int crc_flg)
{
	int xsize;
	int dicsiz;
	void dispmark(char c);
	void fwrite_crc(uchar *p, int n, FILE *f);

	crc = 0;
	if (f2) fflush(f2);
	dicsiz = 1 << interface.dicbit;
	while (size > 0) {
		xsize = (size > BUFFERSIZE) ? BUFFERSIZE : size;
		if (fread(text, 1, xsize, f1) != xsize) {
			fileerror(RDERR, f1);
		}
		fwrite_crc(text, xsize, f2);
		size -= xsize;
		if (crc_flg) {
			while (xsize > 0) {
				dispmark('c');
				xsize -= dicsiz;
			}
		}
	}
}

void far *e_farmalloc(ulong size)
{
	void far *p;

	if ((p = farmalloc(size)) == NULL) error(MEMOVRERR, NULL);
	return p;
}

void *e_malloc(uint size)
{
	void *p;

	if ((p = malloc(size)) == NULL) error(MEMOVRERR, NULL);
	return p;
}

void *e_realloc(void *buf, int size)
{
	void *p;

	if ((p = realloc(buf, size)) == NULL) error(MEMOVRERR, NULL);
	return p;
}

FILE *myeopen(char *path, char *mode, char *errmes)
{
	FILE *f;
	int fd;
	extern int _creat(char *path, int attr);

	f = NULL;
	if (*mode != 'w') {
		f = fopen(path, mode);
	} else {
		fd = _creat(path, 0x20);
		if (fd >= 0) f = fdopen(fd, mode);
	}
	if (f == NULL && errmes != NULL) error(errmes, path);
	return f;
}

FILE *mywopen(char *path, char *errmes)
{
	return myeopen(path, "wb", errmes);
}

FILE *myropen(char *path)
{
	return myeopen(path, "rb", NOFILEERR);
}

void eprintf(char *fmt, ...)
{
	va_list p;

	va_start(p, fmt);
	vfprintf(stderr, fmt, p);
	va_end(p);
}
