/***************************************************************************
 *   copyright           : (C) 2003-2005 by Hendrik Sattler                *
 *   mail                : post@hendrik-sattler.de                         *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <options.h>
#include <helper.h>
#include <gtincl.h>
#include <w32compat.h>

#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <unistd.h>

void use_envvars (struct args_def* list,
		  void (*arg_fill) (int short_opt,
				    const char* long_opt,
				    char* argument))
{
  char* temp;

  if (arg_fill == NULL) return;

  while (list != NULL &&
	 list->long_name != NULL &&
	 list->short_name != 0 &&
	 list->env_var != NULL) {
    if (list->env_var != NULL &&
	(temp = getenv(list->env_var)) != NULL)
      arg_fill(list->short_name, list->long_name,temp);
    ++list;
  }
}

static void help_print_line_options (const char* longopt,
				     const char* longopt_arg,
				     size_t space,
				     char shortoption)
{
  char line[6*space+1];
  size_t extraspace = 0;

  extraspace += (str_len(longopt)-str_width(longopt));
  extraspace += (str_len(longopt_arg)-str_width(longopt_arg));

  memset(line,0,sizeof(line));

  //first line of an option
  if (longopt != NULL) {
    if (longopt_arg == NULL) snprintf(line,6*space," --%s",longopt);
    else snprintf(line,6*space," --%s <%s>",longopt,longopt_arg);
  }
  memset(line+strlen(line),' ',space+extraspace-strlen(line));

  if (isalpha((int)shortoption)) {
    line[space+extraspace-4] = '-';
    line[space+extraspace-3] = shortoption;
  }

  fprintf(stdout,"%*s",(int)space,line);
}

static char* help_print_line_text (const char* text, size_t space) {
  char* temp = NULL;
  size_t i = space;

  if (str_width(text) > i) {
    while (!isspace((int)text[i]) && i > 0) --i;
    if (!i) i = space;
/*     while (!strn_valid(text,i)) --i; */
/*     if (!i) i = space; */
  }

  temp = strn_dup(text,i);
  fprintf(stdout,"%s\n",temp);
  i = str_len(temp);
  mem_realloc(temp,0);
  return (char*)text+i;
}

static void help_print_line(const char* longopt,
			    const char* longopt_arg,
			    size_t longspace,
			    char shortoption,
			    const char* text)
{
  long line_len = console_width(STDOUT_FILENO);
  size_t textspace;
  const char* temp = text;

  longspace += 6+4;
  help_print_line_options(longopt,longopt_arg,longspace,shortoption);
  textspace = line_len-longspace;

  do {
    temp = help_print_line_text(temp,textspace);
    if (str_len(temp)) fprintf(stdout,"%*s",(int)longspace," ");
    else break;
    while (isspace((int)*temp)) ++temp;
  } while (1);
}

#ifndef PATH_SEPARATOR
#define PATH_SEPARATOR '/'
#endif

#include <disclaimer.h>
void help (char* me,
	   struct args_def_type* types,
	   struct args_def* params,
	   char* extra_args)
{
  char* name = strrchr(me,PATH_SEPARATOR);
  unsigned int i = 0, k;
  unsigned int total = 0;

  if (name == NULL) name = me;
  else ++name;

  print_disclaimer();
  printf("%s: %s",_("Syntax"),name);
  for (; types[i].name != NULL; ++i)
    if (types[i].required) printf(" %s",_(types[i].name));
    else printf(" [%s]",_(types[i].name));
  if (extra_args) printf(" %s",extra_args);
  printf("\n");
/*   printf(" [%s...]\n",_("files")); */

  for (k = 0; params[k].long_name || params[k].short_name; ++k) {
    i = str_width(_(params[k].long_name));
    if (params[k].pname) i += str_width(_(params[k].pname));
    if (total < i) total = i;
  }

  for (i = 0; types[i].name; ++i) {
    name = _(types[i].name);
    printf("\n%c%s:\n",toupper((int)name[0]),name+1);
    for (k = 0; params[k].long_name || params[k].short_name; ++k) {
      if (types[i].id == params[k].type_id)
	help_print_line(params[k].long_name,_(params[k].pname),total,
			params[k].short_name,_(params[k].descr));
    }
  }
}

