/* 
 *     XaoS, a fast portable realtime fractal zoomer 
 *                  Copyright (C) 1996,1997 by
 *
 *      Jan Hubicka          (hubicka@paru.cas.cz)
 *      Thomas Marsh         (tmarsh@austin.ibm.com)
 *
 * This program 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 of the License, or
 * (at your option) any later version.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#ifdef _plan9_
#include <u.h>
#include <libc.h>
#else
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#endif
#include <config.h>
#include <param.h>
#include <xmenu.h>
#include <version.h>
#include <xerror.h>
#define MAXPARAMS 40
static CONST struct params *params[40];
int nparams;

int params_parser(int argc, char **argv)
{
    int i, p = 0, d;
    int ie = 0;
    int is;
    CONST struct params *par = NULL;
    int error = 0;
    int found;
    for (i = 1; i < argc && !error; i++) {
	found = 0;
#ifdef MACOSX
	if (strncmp("-psn", argv[i], 4) == 0)
	    continue;
#endif
	if (!strcmp("-help", argv[i])) {
	    error = 1;
	    break;
	}
	for (d = 0; d < nparams; d++) {
	    par = params[d];
	    for (p = 0; par[p].name != NULL && !error; p++) {
		if (!strcmp(par[p].name, argv[i])) {
		    found = 1;
		    is = i;
		    switch (par[p].type) {
		    case P_SWITCH:
			*((int *) par[p].value) = 1;
			break;
		    case P_NUMBER:
			{
			    int n;
			    if (i == argc - 1) {
				x_error
				    ("parameter %s requires numeric value.",
				     argv[i]);
				error = 1;
				break;
			    }
			    if (sscanf(argv[i + 1], "%i", &n) != 1) {
				x_error("parameter for %s is not number.",
					argv[i]);
				error = 1;
				break;
			    }
			    *((int *) par[p].value) = n;
			    i++;
			}
			break;
		    case P_FLOAT:
			{
			    float n;
			    if (i == argc - 1) {
				x_error
				    ("parameter %s requires floating point numeric value.",
				     argv[i]);
				error = 1;
				break;
			    }
			    if (sscanf(argv[i + 1], "%f", &n) != 1) {
				x_error
				    ("parameter for %s is not floating point number.",
				     argv[i]);
				error = 1;
				break;
			    }
			    *((float *) par[p].value) = n;
			    i++;
			}
			break;
		    case P_STRING:
			{
			    if (i == argc - 1) {
				x_error
				    ("parameter %s requires string value.",
				     argv[i]);
				error = 1;
				break;
			    }
			    i++;
			    *((char **) par[p].value) = *(argv + i);
			}
		    }
		    ie = i;
		    i = is;
		}
	    }
	}
	if (d == nparams && !found) {
	    i = menu_processargs(i, argc, argv);
	    if (i < 0) {
		error = 1;
		break;
	    } else
		i++;
	} else
	    i = ie;
    }
    if (error) {
	const char *name[] = {
	    "",
	    "number",
	    "string",
	    "f.point"
	};
#ifndef _plan9_
	printf("                 XaoS" XaoS_VERSION " help text\n");
	printf
	    (" (This help is genereated automagically. I am sorry for all inconvencies)\n\n");
#endif
	printf("option string   param   description\n\n");
	for (d = 0; d < nparams; d++) {
	    par = params[d];
	    for (p = 0; par[p].name != NULL; p++) {
		if (par[p].type == P_HELP)
		    printf("\n%s\n\n", par[p].help);
		else if (!par[p].type)
		    printf(" %-14s   %s\n", par[p].name, par[p].help);
		else
		    printf(" %-14s  %s\n%14s    %s\n", par[p].name,
			   name[par[p].type], "", par[p].help);
	    }
	    if (p == 0)
		printf(" No options avaiable for now\n");
	}
	menu_printhelp();
	return 0;
    }
    return (1);
}

void params_register(CONST struct params *par)
{
    params[nparams++] = par;
}
