/*
 *  Auto Prefs v1.0 (Dec 31, 1996)
 *
 *  Copyright (c) 1996 by Patrick Kellum (patrick@syix.com)
 *
 *  Auto Prefs will allow players to save their indentation, spacing, notifier, 
 *  verbosity, etc prefs between games that include this library.  
 *
 *  This library will work with the Standard (ADV/STD) TADS libraries, 
 *  Whizzard's ADV libraries, or WorldClass.  Setting the #define at the start 
 *  of the source will switch between the versions (neet huh :)  All the 
 *  #ifdef's and such make the source a little confusing (at least to me) but 
 *  it was the best way to make this library compatable with the different 
 *  libraries without having to release different libraries (and updating all of 
 *  them).  If you find any bugs or typos, please email me at patrick@syix.com.  
 *  I will release updated versions as I get any bugs fixed.
 *
 *  The prefs file saved with this library will be compatable with all games 
 *  that include this library and between the standard, WADV,  and WorldClass 
 *  versions.
 *
 *  ------------------------Adding Additional Prefs----------------------------
 *
 *  If you have added additional features to your game that you want to use with 
 *  this library that are already available for a different library version (for 
 *  example, a score notifier to the Standard libraries) you can just modify the 
 *  source to allow it (see the modifications to allow score notification with 
 *  both WorldClass and WADV for a good example).  If you use some features that 
 *  don't have any similar feature (for example, title highlighting), then 
 *  PLEASE email me, I'll be happy to add a place in the 'tadspref.dat' file for 
 *  it.  I just don't want to see different, incompatable, versions of the prefs 
 *  files floating around :)
 *
 *  NOTE:  The Standard and WADV versions have not been tested much.  If you are 
 *         using this with either of those libraries then I recomended you test 
 *         the results before releasing the finished product.
 *
 *
 *  --------------------------Install instructions-----------------------------
 *
 *  WorldClass instructions:
 *
 *     To use this library, add an include in your source (#include <prefs.t>) 
 *     and add this line to userinit, in the 'global.restarting = nil' block:
 *
 *     loadprefs ();
 *
 *     For example, you might add a replace in your source like below.
 *
 *     ---Example---
 *
 *     replace userinit: function
 *        {
 *         if ( global.restarting = nil ) 
 *            {
 *             "\b";
 *             loadprefs ();
 *             "\b";
 *             intro();
 *            }
 *         global.lastactor := Me;
 *         Me.location.enter ( Me );
 *        }
 *
 *     ---Example---
 *
 *
 *  Standard (ADV/STD) instructions:
 *
 *     To use this library, add an include in your source (#include <prefs.t>) 
 *     and add this line to init:
 *
 *     loadprefs ();
 *
 *     For example, you might add a replace in your source like below.
 *
 *     ---Example---
 *
 *     replace init: function
 *        {
 *         "\b";
 *         loadprefs ();
 *         "\b";
 *         version.sdesc; 
 *         setdaemon ( turncount, nil );
 *         setdaemon ( sleepDaemon, nil );
 *         setdaemon ( eatDaemon, nil );
 *         Me.location := startroom;
 *         startroom.lookAround ( true );
 *         startroom.isseen := true;
 *         scoreStatus ( 0, 0);
 *        }
 *
 *     ---Example---
 *  
 *
 * Whizzard's ADV (WADV) instructions:
 *
 *     To use this library, add an include in your source (#include <prefs.t>) 
 *     and add this line to userinit:
 *
 *     loadprefs ();
 *
 *     For example, you might add a replace in your source like below.
 *
 *     ---Example---
 *
 *        replace userinit: function ( parm )
 *           {
 *            "\b";
 *            loadprefs ();
 *            "\b";
 *            version.sdesc;
 *            Me.location := global.start;
 *            global.start.lookAround( true );
 *            global.start.isseen := true;
 *           }
 *
 *     ---Example---
 *
 *  -------------------------Instructions Addition-----------------------------
 *
 *  You might want to add the following to any sort of instructions command you 
 *  use:
 *
 * ---Clip---
 *
 *  PREFS - Brings up a menu for setting and saving various game prefs.  These 
 *          will be loaded every time you load the game and the prefs file may 
 *          be transfered to other games using this feature. 
 *
 * ---Clip---
 *
 *  -----------------About the title highlighting menu choice------------------
 *
 *  In the game(s) I'm working on, there is an option to highlight room titles.  
 *  It doesn't serve any real use, but I think it looks nicer.  Here's the 
 *  WorldClass code in case anyone else wants to use it.  It could be done with 
 *  the standard libraries (I've done it in the past) but I no longer have that 
 *  code available.  It was rather easy though from what I remember.  If you 
 *  don't want this to appear in the prefs menu in your game, just comment out 
 *  the text output in loadprefs and prefs (but leave the code functional!  Only 
 *  comment out out text output) and comment out the 'case '5'' block in prefs.  
 *  This will remove the option without messing up the prefs file.
 *
 *     modify Room
 *        banner = 
 *           {
 *            local actor := global.lastactor;
 *
 *            if ( global.highlight )
 *               {
 *                "\(<<self.tdesc>>\)";
 *               }
 *            else
 *               {
 *                self.tdesc;
 *               }
 *            if ( actor and not isclass ( self, Nestedroom ) ) 
 *               {
 *                if ( actor.location = self ) 
 *                   {
 *                    switch ( actor.position ) 
 *                       {
 *                        case 'sitting':
 *                           ", sitting down";
 *                           break;
 *                        case 'lying':
 *                           ", lying down";
 *                           break;
 *                       }
 *                   }
 *               }
 *           }
 *
 *
 *  -------------------------------Copyright-----------------------------------
 *
 *  This module is Copyright (c) 1996 Patrick Kellum.  Permission to use any or 
 *  all of this code in other TADS games is granted provided credit is given in
 *  your "CREDITS" command for this code and that you leave this copyright 
 *  message in the source whenever distributed.  Please make all changes in a 
 *  backward compatible manner and make them available for free.  If you do use 
 *  this module, please email me and let me know.
 *  (copyright notice modified from the one included with Jeff Laing's modules)
 *
 */

#pragma C-

//
// Used to switch between the WorldClass , Standard, and Whizzard's versions of 
// the system libraries are being used.
//

//#define WORLDCLASS   // WorldClass library is used

//#define STD          // Standard TADS libraries or Whizzard's ADV without 
                       // Score Notification are used

#define WADV         // Whizzard's ADV libraries with Score Notification are 
                       // used

//
// Version string used by 'version.t' by Jeff Laing.  Comment it out if you are 
// not using that library or the WorldClass conversion of it.
//

autoprefsVersion: versionTag
   id="prefs.t v1.0 (Dec 31, 1996) by Patrick Kellum (patrick@syix.com)\n"
   author='Patrick Kellum (patrick@syix.com)'
   func='Auto Prefs'
;

//
// Prefs verb - WorldClass version.
//

#ifdef WORLDCLASS
prefsVerb: Systemverb, Soloverb
   sdesc = "prefs"
   verb = 'prefs'
   doAction = 'Prefs'
   requires = [[&canusealpha, &canusenumber]]
   soloaction ( actor ) =
      {
       prefs ();
       abort;
      }
;

//
// Prefs verb - Standard and Whizzard's ADV versions.
//

#else
prefsVerb: sysverb
   sdesc = "prefs"
   verb = 'prefs'
   doAction = 'Prefs'
   action ( actor ) =
      {
       prefs ();
       abort;
      }
;
#endif

//
// prefs().  Backs up the old global.* settings, displays a menu and gets input.
//

prefs: function
   {
    local resp, cancelprefs, oldverbose, oldindent, oldspacing, oldnotify, oldhighlight, oldslwidth, slwidth;

    cancelprefs := true;

    oldverbose := global.verbose;
    oldindent := global.indent;
    oldspacing := global.paragraphspacing;
    oldnotify := global.silentincscore;
    oldhighlight := global.highlight;
    oldslwidth := global.statuslinewidth;

    while ( cancelprefs )
       {
        "\b---===Prefs Menu===---\b";
        "\t1\tVerbosity:  ";
        if ( global.verbose )
           "\(VERBOSE\)\n";
        else
           "\(TERSE\)\n";
#ifdef WORLDCLASS
        "\t2\tIndentation:  ";
        if ( global.indent )
           "\(ON\)\n";
        else
           "\(OFF\)\n";
        "\t3\tSpacing:  ";
        if ( global.paragraphspacing )
           "\(DOUBLE\)\n";
        else
           "\(SINGLE\)\n";
        "\t4\tScore notifier:  ";
        if ( not global.silentincscore )
           "\(ON\)\n";
        else 
           "\(OFF\)\n";
#endif
#ifdef WADV
        "\t2\tScore notifier:  ";
        if ( not global.notifyon )
           "\(ON\)\n";
        else
           "\(OFF\)\n";
#endif
#ifdef WORLDCLASS
        "\t5\tTitle highlighting:  ";
        if ( global.highlight )
           "\(ON\)\n";
        else
           "\(OFF\)\n";
        "\t6\tStatus line width:  \(<<global.statuslinewidth>>\)\n";
#endif
        "\b";
        "\tS\tSave prefs\n";
        "\tC\tCancel\n";
        "\tU\tUse without saving\b";
        "Prefs>";

        resp := upper ( input () );
        switch ( resp )
           {
            case 'S':
               cancelprefs := nil;
               saveprefs();
               break;
            case 'C':
            case 'Q':
               cancelprefs := nil;
               global.verbose := oldverbose;
               global.indent := oldindent;
               global.paragraphspacing := oldspacing;
               global.silentincscore := oldnotify;               
               global.highlight := oldhighlight;
               global.statuslinewidth := oldslwidth;
               break;
            case 'U':
               cancelprefs := nil;
               break;
            case '1':
               if ( global.verbose )
                  global.verbose := nil;
               else
                  global.verbose := true;
               break;
#ifdef WORLDCLASS
            case '2':
               if ( global.indent )
                  global.indent := nil;
               else
                  global.indent := true;
               break;
            case '3':
               if ( global.paragraphspacing )
                  global.paragraphspacing := nil;
               else
                  global.paragraphspacing := true;
               break;
            case '4':
               if ( global.silentincscore )
                  global.silentincscore := nil;
               else
                  global.silentincscore := true;
               break;
            case '5':
               if ( global.highlight )
                  global.highlight := nil;
               else
                  global.highlight := true;
               break;
            case '6':
               "Width 12 - 80> ";
               slwidth := 0;
               while ( slwidth < 14 or slwidth > 90 )
                  {
                   slwidth := cvtnum ( input () );
                  }
               if ( slwidth < 14 or slwidth > 90 )
                  slwidth := oldslwidth; // not needed, just being paranoid :)
               global.statuslinewidth := slwidth;
               break;
#endif
#ifdef WADV
            case '2':
               if ( global.notifyon )
                  global.notifyon := nil;
               else
                  global.notifyon := true;
               break;
#endif
           }
       }
   }

//
// saveprefs().  Saves the global.* prefs to the file 'tadspref.dat' and 
// displays a message stating the success.
//

saveprefs: function
   {
    local preffile, prefnum;

    preffile := 'tadspref.dat';
    "Saving prefs file...  ";
    prefnum := fopen ( preffile, 'w+' );

    // Verbosity

    if ( global.verbose )
       {
        if ( fwrite ( prefnum, 'y' ) )
           {
            "\(Error writting to prefs file!\)\n";
            abort;
           }
       }
    else
       {
        if ( fwrite ( prefnum, 'n' ) )
           {
            "\(Error writting to prefs file!\)\n";
            abort;
           }
       }

    // Indentation

    if ( global.indent )
       {                
        if ( fwrite ( prefnum, 'y' ) )
           {
            "\(Error writting to prefs file!\)\n";
            abort;
           }
       }
    else
       {
        if ( fwrite ( prefnum, 'n' ) )
           {
            "\(Error writting to prefs file!\)\n";
            abort;
           }
       }

    // Paragraph spacing

    if ( global.paragraphspacing )
       {
        if ( fwrite ( prefnum, 'y' ) )
           {
            "\(Error writting to prefs file!\)\n";
            abort;
           }
       }
    else
       {
        if ( fwrite ( prefnum, 'n' ) )
           {
            "\(Error writting to prefs file!\)\n";
            abort;
           }
       }

    // Score notifier

#ifdef WADV
    if ( not global.notifyon )
#else
    if ( not global.silentincscore )
#endif
       {
        if ( fwrite ( prefnum, 'y' ) )
           {
            "\(Error writting to prefs file!\)\n";
            abort;
           }
       }
    else
       {
        if ( fwrite ( prefnum, 'n' ) )
           {
            "\(Error writting to prefs file!\)\n";
            abort;
           }
       }

    // Title highlight

    if ( global.highlight )
       {
        if ( fwrite ( prefnum, 'y' ) )
           {
            "\(Error writting to prefs file!\)\n";
            abort;
           }
       }
    else
       {
        if ( fwrite ( prefnum, 'n' ) )
           {
            "\(Error writting to prefs file!\)\n";
            abort;
           }
       }

    // Statusline width

    if ( fwrite ( prefnum, global.statuslinewidth ) )
       {
        "\(Error writting to prefs file!\)\n";
        abort;
       }
    fclose ( prefnum );
    "saved.\n";
   }

//
// loadprefs().  Loads the global.* prefs from the file 'tadspref.dat' and 
// displays the settings.  If any settings are not found, the settings in 
// global.* are used and this is stated.
//

loadprefs: function
   {
    local preffile, prefnum, preftemp;

    preffile := 'tadspref.dat';
    "Loading prefs file...\n";
    prefnum := fopen ( preffile, 'r+' );
    "\tVerbosity:  ";
    preftemp := fread ( prefnum );
    if ( preftemp )
       {
        if ( preftemp = 'y' )
           {
            global.verbose := true;
            "\(VERBOSE\)\n";
           }
        else 
           {
            global.verbose := nil;
            "\(TERSE\)\n";
           }
       }
    else
       {
        "\(FAILED\) defaulting to ";
        if ( global.verbose )
           "\(VERBOSE\)\n";
        else
           "\(TERSE\)\n";
       }
#ifdef WORLDCLASS
    "\tIndentation:  ";
#endif
    preftemp := fread ( prefnum );
    if ( preftemp )
       {
        if ( preftemp = 'y' )
           {
            global.indent := true;
#ifdef WORLDCLASS
            "\(ON\)\n";
#endif
           }
        else 
           {
            global.indent := nil;
#ifdef WORLDCLASS
            "\(OFF\)\n";
#endif
           }
       }
#ifdef WORLDCLASS
    else
       {
        "\(FAILED\) defaulting to ";
        if ( global.indent )
           "\(ON\)\n";
        else
           "\(OFF\)\n";
       }
    "\tSpacing:  ";
#endif
    preftemp := fread ( prefnum );
    if ( preftemp )
       {
        if ( preftemp = 'y' )
           {
            global.paragraphspacing := true;
#ifdef WORLDCLASS
            "\(DOUBLE\)\n";
#endif
           }
        else 
           {
            global.paragraphspacing := nil;
#ifdef WORLDCLASS
            "\(SINGLE\)\n";
#endif
           }
       }
#ifdef WORLDCLASS
    else
       {
        "\(FAILED\) defaulting to ";
        if ( global.paragraphspacing )
           "\(DOUBLE\)\n";
        else
           "\(SINGLE\)\n";
       }
#endif
#ifndef STD
    "\tScore notifier:  ";
#endif
    preftemp := fread ( prefnum );
    if ( preftemp )
       {
        if ( preftemp = 'y' )
           {
#ifdef WADV
            global.notifyon := nil;
#else
            global.silentincscore := nil;
#endif
#ifndef STD
            "\(ON\)\n";
#endif
           }
        else 
           {
#ifdef WADV
            global.notifyon := true;
#else
            global.silentincscore := true;
#endif
#ifndef STD
            "\(OFF\)\n";
#endif
           }
       }
#ifndef STD
    else
       {
        "\(FAILED\) defaulting to ";
        if ( global.notifyon or global.silentincscore )
           "\(ON\)\n";
        else
           "\(OFF\)\n";
       }
#endif
#ifdef WORLDCLASS
    "\tTitle highlighting:  ";
#endif
    preftemp := fread ( prefnum );
    if ( preftemp )
       {
        if ( preftemp = 'y' )
           {
            global.highlight := true;
#ifdef WORLDCLASS
            "\(ON\)\n";
#endif
           }
        else 
           {
            global.highlight := nil;
#ifdef WORLDCLASS
            "\(OFF\)\n";
#endif
           }
       }
#ifdef WORLDCLASS
    else
       {
        "\(FAILED\) defaulting to ";
        if ( global.highlight )
           "\(ON\)\n";
        else
           "\(OFF\)\n";
       }
    "\tStatus line width:  ";
#endif
    preftemp := fread ( prefnum );
    if ( preftemp )
        global.statuslinewidth := preftemp;
#ifdef WORLDCLASS
    else
        "\(FAILED\) defaulting to ";
    "\(<<global.statuslinewidth>>\)\n";
#endif
    fclose ( prefnum );
    "Prefs loaded.\n";
   }

//
// Worldclass globals that are not present in the standard and WADV libraries 
// but needed as defaults for this library.
//

#ifdef STD
modify global
   indent = true
   paragraphspacing = true
   silentincscore = true
   highlight = true
   statuslinewidth = 74
;
#endif

#ifdef WADV
modify global
   indent = true
   paragraphspacing = true
   highlight = true
   statuslinewidth = 74
;
#endif

#ifdef WORLDCLASS
modify global
   highlight = true
;
#endif

//  End of library, have a nice day :)
