/*+JMJ***************************************************************
 qdstar.c - Quick and Dirty Pseudo Starfield Generator in C
 2011/2/4 David Meyer <papa@freeshell.org>
 ver. 0.2 - Add command line interface to customize field height,
            width, & density. (2011/2/10)
********************************************************************/

#include <argp.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "krcompat.h"

#define IHEIGHT 24
#define IWIDTH 69
#define FDENSITY 0.07

const char *argp_program_version =
  "qdstar 0.2";
const char *argp_program_bug_address =
  "<papa@freeshell.org>";
static char doc[] =
  "qdstar -- Quick and Dirty Pseudo Starfield Generator";
static char args_doc[] = "*** args doc here ***";
static struct argp_option options[] =
  {
    {"density", 'd', "DENSITY", 0, "Portion of starfield to fill with characters. 0 <= DENSITY <= 1.0"},
    {"height", 't', "HEIGHT", 0, "Character HEIGHT (lines) of starfiel."},
    {"width", 'w', "WIDTH", 0, "Character WIDTH (columns) of starfield"},
    {0}
  };
struct args
{
  float density;
  long int height, width;
};
static error_t parse_opt(int key, char *arg, struct argp_state *state)
{
  struct args *args = state->input;

  switch (key)
    {
    case 'd':
      args->density = strtof(arg, NULL);
      break;
    case 'h':
      args->height = strtol(arg, NULL, 10);
      break;
    case 'w':
      args->width = strtol(arg, NULL, 10);
      break;
    case ARGP_KEY_ARG:
      argp_usage(state);
      break;
    default:
      return ARGP_ERR_UNKNOWN;
    }
  return 0;
}

static struct argp argp = {options, parse_opt, args_doc, doc};

int main(int argc, char **argv)
{
  struct args args;
  int r, c;
  float fmag;
  char s;

  args.density = FDENSITY;
  args.height = IHEIGHT;
  args.width = IWIDTH;

  argp_parse(&argp, argc, argv, 0, 0, &args);

  srand( (unsigned) time( NULL ) );

  for ( r = 0; r < args.height; r ++ )
    {
      for ( c = 0; c < args.width; c ++ )
	{
	  if ( ((float) rand() / (float) RAND_MAX) >= args.density )
	    printf( " " );
	  else
	    {
	      fmag = (float) rand() / (float) RAND_MAX;
	      if ( fmag < 0.5 )           s = '.';
	      else if ( fmag < 0.75 )     s = ',';
	      else if ( fmag < 0.875 )    s = 'o';
	      else if ( fmag < 0.9375 )   s = '*';
	      else if ( fmag < 0.96875 )  s = 'O';
	      else if ( fmag < 0.984375 ) s = '0';
	      else                        s = '@';
	      printf( "%c", s);
	    }
	}
      printf("\n");
    }
  exit(0);
}