/*
 * Display directory contents
 */
#include <stdlib.h>
#include <stdio.h>
#include <console.h>
#include <string.h>
#include <com32.h>
#include <dirent.h>
#include <minmax.h>
#include <unistd.h>
#include <getkey.h>

static int rows, cols;		/* Screen parameters */

#define DIR_CHUNK	1024

static const char *type_str(int type)
{
    switch (type) {
    case DT_FIFO:
	return "[fif]";
    case DT_CHR:
	return "[chr]";
    case DT_DIR:
	return "[dir]";
    case DT_BLK:
	return "[blk]";
    case DT_UNKNOWN:
    case DT_REG:
	return "";
    case DT_LNK:
	return "[lnk]";
    case DT_SOCK:
	return "[sck]";
    case DT_WHT:
	return "[wht]";
    default:
	return "[???]";
    }
}

static void free_dirents(struct dirent **dex, size_t n_de)
{
    size_t i;

    for (i = 0; i < n_de; i++)
	free(dex[i]);

    free(dex);
}

static int compare_dirent(const void *p_de1, const void *p_de2)
{
    const struct dirent *de1 = *(const struct dirent **)p_de1;
    const struct dirent *de2 = *(const struct dirent **)p_de2;
    int ndir1, ndir2;

    ndir1 = de1->d_type != DT_DIR;
    ndir2 = de2->d_type != DT_DIR;

    if (ndir1 != ndir2)
	return ndir1 - ndir2;

    return strcmp(de1->d_name, de2->d_name);
}

static int display_directory(const char *dirname)
{
    DIR *dir;
    struct dirent *de;
    struct dirent **dex = NULL;
    size_t n_dex = 0, n_de = 0;
    size_t i, j, k;
    size_t nrows, ncols, perpage;
    size_t endpage;
    int maxlen = 0;
    int pos, tpos, colwidth;

    dir = opendir(dirname);
    if (!dir) {
	printf("Unable to read directory: %s\n", dirname);
	return -1;
    }

    while ((de = readdir(dir)) != NULL) {
	struct dirent *nde;

	if (n_de >= n_dex) {
	    struct dirent **ndex;

	    ndex = realloc(dex, (n_dex + DIR_CHUNK) * sizeof *dex);
	    if (!ndex)
		goto nomem;

	    dex = ndex;
	    n_dex += DIR_CHUNK;
	}

	nde = malloc(de->d_reclen);
	if (!nde)
	    goto nomem;

	memcpy(nde, de, de->d_reclen);
	dex[n_de++] = nde;

	maxlen = max(maxlen, de->d_reclen);
    }

    closedir(dir);

    qsort(dex, n_de, sizeof *dex, compare_dirent);

    maxlen -= offsetof(struct dirent, d_name) + 1;
    ncols = (cols + 2)/(maxlen + 8);
    ncols = min(ncols, n_de);
    ncols = max(ncols, 1U);
    colwidth = (cols + 2)/ncols;
    perpage = ncols * (rows - 1);

    for (i = 0; i < n_de; i += perpage) {
	/* Rows on this page */
	endpage = min(i+perpage, n_de);
	nrows = ((endpage-i) + ncols - 1)/ncols;

	for (j = 0; j < nrows; j++) {
	    pos = tpos = 0;
	    for (k = i+j; k < endpage; k += nrows) {
		pos += printf("%*s%-5s %s",
			      (tpos - pos), "",
			      type_str(dex[k]->d_type),
			      dex[k]->d_name);
		tpos += colwidth;
	    }
	    printf("\n");
	}

	if (endpage >= n_de)
	    break;

	get_key(stdin, 0);
    }

    free_dirents(dex, n_de);
    return 0;

nomem:
    closedir(dir);
    printf("Out of memory error!\n");
    free_dirents(dex, n_de);
    return -1;
}

int main(int argc, char *argv[])
{
    int rv;

    if (getscreensize(1, &rows, &cols)) {
	/* Unknown screen size? */
	rows = 24;
	cols = 80;
    }

    if (argc < 2)
	rv = display_directory(".");
    else if (argc == 2)
	rv = display_directory(argv[1]);
    else {
	printf("Usage: %s directory\n", argv[0]);
	rv = 1;
    }

    return rv ? 1 : 0;
}
 
