/*
   An Treasure genrator , usable with X11, it is written with Athena Widgets
 It use Form, Label, and Command Widget.

   You need to do something like this for running this program :
  
   cc -I/local/X11R5/include -L/local/X11R5/lib -o tg tg.c -lXaw -lXmu -lXt -lXext -lX11

   
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>

#include <X11/Xaw/Cardinals.h>

/* Simple widgets                                             */
#include <X11/Xaw/Command.h>        /* commandWidgetClass     */ 
#include <X11/Xaw/Label.h>          /* labelWidgetClass       */ 
#include <X11/Xaw/Logo.h>           /* logoWidgetClass        */ 

/* Composite and Constraint Widgets                           */
#include <X11/Xaw/Form.h>           /* formWidgetClass        */ 

#include <X11/Shell.h>

static void quit(), Treasure(), PopDown(), Treasure_Gen();
/* static void T_En(), Tre();  */

String fallback_resources[] = {

 "*borderWidth:           1",
 "*defaultDistance:       4",
 "*Treasure*Translations :#override \\n\
    <KeyPress>: PopDown()",
 "*Translations :#override \\n\
    Ctrl<Key>C: quit()",
 NULL
};

XtActionsRec actions[] = {
  { "quit",       (XtActionProc) quit },
  { "PopDown",    (XtActionProc) PopDown},
};

/************** Globale variabler ***************/
Widget       root;            /* Root of all the widgets */


main( argc, argv )
int  argc;
char **argv;
{
  XtAppContext app_con;
  Widget       fo,cm,cm2,cm3;
  int          i;
  char         str[5],*s;

  argv[0] = "Treasure generator";
  srand( (short) (time(NULL) % 37) );
  
  root = XtAppInitialize( &app_con, "Root",
                          NULL, ZERO,         /* Option's parsering */
			  &argc, argv,
                          fallback_resources, 
			  NULL, ZERO          /* Application shell parameter */
                        );
  
  if ( argc != 1 )    /* Something has fucked up */
    exit(1);

  XtAppAddActions( app_con, actions, XtNumber(actions) );

  fo = XtCreateManagedWidget( "Xform", formWidgetClass, root, NULL, ZERO );

  /**** Lager en vertikal rekke  ***********/
  cm = XtVaCreateManagedWidget( "A", commandWidgetClass, fo, 
                                XtNwidth, 25, 
                                NULL );
  XtAddCallback( cm, XtNcallback, Treasure_Gen, (XtPointer)NULL );
  cm2 = cm;
  str[1] = '\0';
  for( i = 66; i < 76; i++ ) {
    str[0] = i; 
    cm = XtVaCreateManagedWidget( str, commandWidgetClass, fo,
                                  XtNfromVert, cm, 
                                  XtNwidth, 25, 
                                  NULL );
    XtAddCallback( cm, XtNcallback, Treasure_Gen, (XtPointer)NULL );
  }

  /***** Lager en horisontal rekke *********/
  cm3 = cm2;
  for( i = 76; i < 87; i++ ) {
    str[0] = i; 
    cm3 = XtVaCreateManagedWidget( str, commandWidgetClass, fo,
                                  XtNfromHoriz, cm3,
                                  XtNwidth, 25, 
                                  NULL );
    XtAddCallback( cm3, XtNcallback, Treasure_Gen, (XtPointer)NULL );
  }

  s = "\nWhich treasure (push a button) ?\n\n\
The result is written to a file\n\
named Treasure_(A..V)\n\n\
Ctrl-C to quit the program."; 
  cm = XtVaCreateManagedWidget("xl", labelWidgetClass,fo,
                               XtNfromVert, cm3,
                               XtNhorizDistance, 50,
                               XtNvertDistance, 15,
                               XtNborderWidth, 2,
                               XtNlabel, s,
                               NULL);

  cm = XtVaCreateManagedWidget("xlogo", logoWidgetClass,fo,
                               XtNfromVert, cm3,
                               XtNhorizDistance, 150,
                               XtNvertDistance, 150,
                               XtNborderWidth, 1,
                               NULL );  
  XtRealizeWidget( root );

  XtAppMainLoop( app_con );    /* Run until killed */  
}                   

/***********************************************************************/
/*

*/
static void Treasure( txt )
char *txt;
{

  Widget   fo,popup,cm,cm2,cm3;
  Arg      args[5];
  int      i;
  Cardinal n;
  Position width,height,x,y;
  char     str[5],*s;
 
  n = 0;
  XtSetArg(args[0], XtNwidth, &width); n++;
  XtSetArg(args[1], XtNheight, &height); n++;
  XtGetValues(root, args, n);
  XtTranslateCoords(root, (Position) (width), (Position) (height/1024),
                      &x, &y);
  n = 0;
  XtSetArg(args[n], XtNx, x);        n++;
  XtSetArg(args[n], XtNy, y);        n++;
  popup = XtCreatePopupShell("Treasure", transientShellWidgetClass, root,
          args, n);
 
  /*fo = XtCreateManagedWidget( "form", formWidgetClass, popup, NULL, ZERO );*/
  XtVaCreateManagedWidget( "xtxt", labelWidgetClass, popup, 
                           XtNlabel, txt , NULL );

  XtPopup( popup, XtGrabExclusive );
}

/***********************************************************************/
/*
    This is the callback rountine, which is called when we have pressed
  A..V button on the screen. 
*/
static void Treasure_Gen( w, client_data, call_data )
Widget    w;
XtPointer client_data,call_data;
{
 char *t_name,fname[60];
 FILE *f;

 /** Make a file name for where we are going to write treasure stat **/ 
 t_name   = XtName( w ); 
 strcpy( fname, "Treasure_X" );
 fname[9] = t_name[0];

 unlink( fname );
 f = fopen( fname, "a+" );
 Tre( t_name, f );
 fclose( f ); 
}


/***********************************************************************/
/*
    T_En Generates the treasure, write it to a file, and pop a window
  with the result.
*/
int T_En(  PrCP, antCP, ternCP, PrSP, antSP, ternSP,
           PrEP, antEP, ternEP, PrGP, antGP, ternGP,
           PrPP, antPP, ternPP,
           Prgem, antTG, ternG,
           PrJew, antTJ, ternJ,
           PrSpe, antTS, ternS,
           PrMag, strM,
           multi,f, id
          )
int  PrCP, antCP, ternCP,     /* Copper coins                 */
     PrSP, antSP, ternSP,     /* Silver coins                 */
     PrEP, antEP, ternEP,     /* Electium coins               */
     PrGP, antGP, ternGP,     /* Gold coins                   */
     PrPP, antPP, ternPP,     /* Platina coins                */
     Prgem, antTG, ternG,     /* Gems                         */
     PrJew, antTJ, ternJ,     /* Jewelry                      */
     PrSpe, antTS, ternS,     /* Special Magical Treasure     */
     PrMag;                   /* Magical Item                 */
char *strM;
int  multi;
FILE *f;                      /* File to place the output     */
char id;                      /* Name of treasure to generate */
 
{
  unsigned int cp, sp, ep, gp, pp, gem, jew, spe, mag;
  int          tall,i;
  float        xp;
  char         str[1024],txt[1024];
 
  cp = sp = ep = gp = pp = gem = jew = spe = mag = 0;
 
  if ( PrCP != 0 ) {
    tall = rand() % 100;
    if ( tall < PrCP ) {
      for( i=1;  i <= antCP; i++ )
        cp += ( rand() % ternCP );
    }
    cp *= multi;
  }
 
  if ( PrSP != 0 ) {
    tall = rand() % 100;
    if ( tall < PrSP ) {
      for( i=1;  i <= antSP; i++ )
        sp += ( rand() % ternSP );
    }
    sp *= multi;
  }
 
  if ( PrEP != 0 ) {
    tall = rand() % 100;
    if ( tall < PrEP ) {
      for( i=1;  i <= antEP; i++ )
        ep += ( rand() % ternEP );
    }
    if ( (id == 'H') )  ep *= (multi * 10);
    else                ep *= multi;
  }
 
  if ( PrGP != 0 ) {
    tall = rand() % 100;
    if ( tall < PrGP ) {
      for( i=1;  i <= antGP; i++ )
        gp += ( rand() % ternGP );
    }
    if ( (id == 'G') || (id == 'H') )  gp *= (multi * 10);
    else                               gp *= multi;
  }
 
  if ( PrPP != 0 ) {
    tall = rand() % 100;
    if ( tall < PrPP ) {
      for( i=1;  i <= antPP; i++ )
        pp += ( rand() % ternPP );
    }
    pp *= multi;
  }
 
  if ( Prgem != 0 ) {
    tall = rand() % 100;
    if ( tall < Prgem ) {
      for( i=1;  i <= antTG; i++ )
        gem += ( rand() % ternG );
    }
  }
 
  if ( PrJew != 0 ) {
    tall = rand() % 100;
    if ( tall < PrJew ) {
      for( i=1;  i <= antTJ; i++ )
        jew += ( rand() % ternJ );
    }
  }
 
  if ( PrSpe != 0 ) {
    tall = rand() % 100;
    if ( tall < PrSpe ) {
      for( i=1;  i <= antTS; i++ )
        spe += ( rand() % ternS );
    }
  }
 
  if ( PrMag != 0 ) {
    tall = rand() % 100;
    if ( tall < PrMag )  mag = 1;
  }

  /************** Utskrift ************/
  fprintf( f, "Overview over generated treasure\n\n");
  sprintf( txt, "Overview over generated treasure\n\n");
  if ( cp != 0 ) {
    fprintf( f, "%u cp\n", cp );
    sprintf( str, "%u cp\n", cp );
    strcat( txt, str );
  }
  if ( sp != 0 ) {
    fprintf( f, "%u sp\n", sp );
    sprintf( str, "%u sp\n", sp );
    strcat( txt, str );
  }
  if ( ep != 0 ) {
    fprintf( f, "%u ep\n", ep );
    sprintf( str, "%u ep\n", ep );
    strcat( txt, str );
  }
  if ( gp != 0 ) {
    fprintf( f, "%u gp\n ", gp );
    sprintf( str, "%u gp\n", gp );
    strcat( txt, str );
  }
  if ( pp != 0 ) {
    fprintf( f, "%u pp\n", pp );
    sprintf( str, "%u pp\n", pp );
    strcat( txt, str );
  }
  if ( gem != 0 ) {
    fprintf( f, "%u number of gem(s)\n", gem );
    sprintf( str, "%u number of gem(s)\n", gem );
    strcat( txt, str );
  }
  if ( jew != 0 ) {
    fprintf( f, "%u piece(s) of Jewelry\n", gem );
    sprintf( str, "%u piece(s) of Jewelry\n", gem );
    strcat( txt, str );
  }
  if ( spe != 0 ) {
    fprintf( f, "%u number of special treasure's\n", spe );
    sprintf( str, "%u number of special treasure's\n", spe );
    strcat( txt, str );
  }
  if ( mag == 1 ) {
    fprintf( f, "Magical Items : %s\n", strM );
    sprintf( str, "Magical Items : %s\n", strM );
    strcat( txt, str );
  }
 
  xp = (cp/1000) + (sp/100) + (ep/2) + gp + (5*pp);
 
  fprintf( f, "\nTreasure give %1.0f in xp points\n", xp );
  sprintf( str, "\nTreasure give %1.0f in xp points\n", xp );
  strcat( txt, str );
  strcat( txt, "\n<<  Press any key to pop down this window  >>\n" );
  Treasure( txt );
}

/***********************************************************************/
/*
    Tre is called from Treasure_Gen, and valg determines which kind of
  treasure to be generated. If you want to change the treasure it is easy
  to do it here.
*/ 
int Tre( valg,f )
char *valg;
FILE *f;

{
   switch ( valg[0] ) {
 
     case 'A' : T_En( 25,1,6, 30,1,6,  20,1,4, 35,2,6, 25,1,2,
                      50,6,6,  50,6,6,  10,1,2, 30,"Any 3",  1000, f, 'A' );
                break;
     case 'B' : T_En( 50,1,8, 25,1,6,  25,1,4, 35,1,3, 0,0,0,
                      25,1,6,  25,1,6,  0,0,0, 10,"1 Sword and misc. weapon",  
                      1000, f, 'B' );
                break;
     case 'C' : T_En( 20,1,12, 30,1,4,  10,1,4, 0,0,0, 0,0,0,
                      25,1,4,  25,1,4,  5,1,2, 10,"Any 2",  1000, f, 'C' );
                break;
     case 'D' : T_En( 10,1,8,  15,1,12, 0,0,0,  60,1,6, 0,0,0,
                      30,1,8,  30,1,8, 10,1,2, 15,"Any 2 + 1 potion",  
                      1000, f, 'D' );
                break;
     case 'E' : T_En( 5,1,10, 30,1,12, 25,1,4, 25,1,8, 0,0,0,
                      10,1,10,  10,1,10,  15,1,2, 25,"Any 3 + 1 scroll",  
                      1000, f, 'E' );
                break;
     case 'F' : T_En( 0,0,0,  10,2,10, 20,1,8, 45,1,8, 30,1,3,
                 20,2,12, 10,1,12, 20,1,3, 30,"1 Potion, 1 scroll 3 weapons",
                      1000, f, 'F' );
                break;
     case 'G' : T_En( 0,0,0,  0,0,0,  0,0,0,  50,1,4,  50,1,4,
                      25,3,6,  25,1,10,  30,1,3, 35,"Any 4 + 1 scroll", 
                      1000, f, 'G' );
                break;
     case 'H' : T_En( 25,3,8, 50,1,100, 50,1,4, 50,1,6, 25,5,4,
                 50,1,100, 50,1,4, 10,1,2, 15,"Any 4 + one potion and scroll", 
                      1000, f, 'H' );
                break;
     case 'I' : T_En( 0,0,0, 0,0,0,  0,0,0, 0,0,0, 0,0,0,
                      50,2,6, 50,2,6, 5,1,2, 15,"Any 1", 1, f, 'I' );
                break;
     case 'J' : T_En( 25,1,4, 10,1,3,  0,0,0, 0,0,0, 0,0,0,
                      0,0,0,  0,0,0,  0,0,0, 0,"ingen",1000, f, 'J' );
                break;
     case 'K' : T_En( 0,0,0, 30,1,6,  10,1,2, 0,0,0, 0,0,0,
                      0,0,0,  0,0,0,  0,0,0, 0,"ingen",1000, f, 'K' );
                break;
     case 'L' : T_En( 0,0,0, 0,0,0,  0,0,0, 0,0,0, 0,0,0,
                      50,1,4,  0,0,0,  0,0,0, 0,"ingen",  1, f, 'L' );
                break;
     case 'M' : T_En( 0,0,0, 0,0,0,  0,0,0, 40,2,4, 50,3,10,
                      55,5,4,  45,2,6,  0,0,0, 0,"ingen",
                      1000, f, 'M' );
                break;
     case 'N' : T_En( 0,0,0, 0,0,0,  0,0,0, 0,0,0, 0,0,0,
                      0,0,0,0,0,0, 10,1,2, 40,"2-8 potions", 1, f,'N');
                break;
     case 'O' : T_En( 0,0,0, 0,0,0,  0,0,0, 0,0,0, 0,0,0,
                      0,0,0,0,0,0,10,1,3, 50,"1-4 scrolls", 1,f,'O');
                break;
 
     /******* Treasure for individual ********/
 
     case 'P' : T_En( 100,3,8, 0,0,0,  0,0,0, 0,0,0, 0,0,0,
                      0,0,0,  0,0,0,  0,0,0, 0,"ingen",  1, f, 'P' );
                break;
     case 'Q' : T_En( 0,0,0, 100,3,6,   0,0,0, 0,0,0, 0,0,0,
                      0,0,0,  0,0,0,  0,0,0, 0,"ingen",  1, f, 'Q' );
                break;
     case 'R' : T_En( 0,0,0, 0,0,0,  100,2,6, 0,0,0, 0,0,0,
                      5,1,2,  0,0,0,  0,0,0, 0,"ingen",  1, f, 'R' );
                break;
     case 'S' : T_En( 0,0,0, 0,0,0,  0,0,0, 100,2,4, 0,0,0,
                      5,1,2,  0,0,0,  0,0,0, 0,"ingen",  1, f, 'S' );
                break;
     case 'T' : T_En( 0,0,0, 0,0,0,  0,0,0, 0,0,0, 100,1,6,
                      5,1,2,  0,0,0,  0,0,0, 0,"ingen",  1, f, 'T' );
                break;
     case 'U' : T_En( 10,1,100, 10,1,100,  0,0,0, 5,1,100, 0,0,0,
                      5,1,2,  10,1,4,  5,1,2, 2,"Any 1",  1, f, 'U' );
                break;
     case 'V' : T_En( 0,0,0,  10,1,100,  5,1,100, 10,1,100, 5,1,100,
                      10,1,2, 10,1,4,    5,1,2,   5,"Any 1",  1,f, 'V');
   }
}

/***********************************************************************/
/*
    Remove the treasure window, when we are pressing a button in the treasure
  window.
*/

static void PopDown( w, xe, str, num  )
Widget    w;
XEvent    *xe;
String    *str;
Cardinal  *num;

{
  XtDestroyWidget( XtParent(w) );
}

/***********************************************************************/
/*
   Quik and probaly a dirty way out.
*/
static void quit()
{
  exit(0);
}

