/*+JMJ***************************************************************
qdstar.c - Quick and Dirty Pseudo Starfield Generator in C
2011/2/4 David Meyer <[email protected]>
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 =
 "<[email protected]>";
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);
}