/* ---------------------------------------------------------------------- */
/*
 *   TADS 3 Tips Extension
 *   Version 1
 *   by Krister Fundin (fundin@yahoo.com)
 */

/* ---------------------------------------------------------------------- */
/*
 *   Introduction.
 */

   There are different ways of making a work of interactive fiction more
accessible to unexperienced players. Some sort of built-in getting-started
text or player's guide is one way, though far from everyone will bother
reading these. Another way is to provide pointers interactively during play,
by responding intelligently to different kinds of errors and informing about
commands as they become relevant. TADS 3 already does this for some of the
system commands, for instance mentioning the NOTIFY OFF command the first
time a score notification is shown. This extension provides a simple
framework for delivering such tips, which automatically ensures that they
are displayed only once. Also, a command is included to turn all tips off,
and this mode can be saved as a default setting, so that tips are turned off
in all stories that use the extension.

/* ---------------------------------------------------------------------- */
/*
 *   Basic usage.
 */

   We start by adding the library file "tips.tl" to our project. We should
also include the header file "tips.h" from wherever tips are defined, so
that we can use the template it defines for our tip objects.

   Let's continue with a practical example. If our story contains some
places where the player could screw up in an obvious way, then a tip about
the UNDO command might be a nice gesture. Defining the tip itself is pretty
easy using the template:

      undoTip: Tip
          "If this didn't turn out quite as intended, note that you can
          always take back one or more commands by typing
          <<aHref('undo', 'UNDO', 'Take back the most recent command')>>."
      ;

   The hyperlink is by no means necessary, but it's a nice touch. Now, we
can trigger this tip wherever it's appropriate by calling:

      undoTip.showTip();

/* ---------------------------------------------------------------------- */
/*
 *   Avoiding redundancy.
 */

   One thing that we should be aware of before we start adding thousands of
tips to our ever so newbie-friendly work, is that for every tip we display,
we might be telling the player something she already knows. This is why a
tip is only shown once by default. In addition to this, though, it's
generally a good idea to pre-emptively cancel a tip if the player does
something indicate that she wouldn't need it. This can be done by calling
the makeShown() method on the relevant tip.

   In the above example, it would be redundant to show a tip about the undo
command if the player had already used said command. A simple way to fix
this would be to add a post-undo object:

      PostUndoObject
          execute()
          {
              undoTip.makeShown();
          }
      ;

/* ---------------------------------------------------------------------- */
/*
 *   Turning tips on and off.
 */

   Everyone won't need tips, obviously, so this extension provides a command
for turning them on and off. This setting is also saved when the SAVE
DEFAULTS command is used, so that the tips can be turned off for all stories
that use them.

   A way to further save the veteran player from having to deal with all
this is to ask whether to show any tips before starting a new session. The
question doesn't have to be phrased this way, though. We could simply ask
something like "are you familiar with interactiv fiction?". Then again, even
that question could be unnecessary. If the default settings indicate that
the tips have already been turned off at some earlier point, then
it's probably best to just leave them off. We can test or change this
setting by referring to the tipMode.isOn property.

   Finally, for some tips, it might be best to show them even when all tips
have been turned off, if they explain some feature that is unique to a
particular story or an extension that it uses. We can achieve this by
overriding the shouldShowTip() method of a tip object so that it only checks
the isShown property and not the tipMode:

      mySpecialTip: Tip
          "In this particular story, etc."

          shouldShowTip()
          {
              return (isShown == nil);
          }
      ;

/* ---------------------------------------------------------------------- */
/*
 *   The style of tips.
 */

   The tips in this extension have their own <.tip> style tag. The text of a
tip will always be wrapped in a pair of these, so that we can alter the way
in which tips are displayed. This can be done by modifying or replacing the
tipStyleTag object, which by default just puts a pair of parentheses around
the text.

   On HTML interpreters, some nice-looking styles can be achived, though we
shouldn't get too carried away. The author of the extension is quite fond of
the following style:

      replace tipStyleTag: HtmlStyleTag 'tip'
          htmlOpenText =
              '<blockquote><font size=-1 color=WHITE
              bgcolor=BLUE>&nbsp;TIP:&nbsp;</font>&nbsp;'
          htmlCloseText = '</blockquote>'

          plainOpenText = '('
          plainCloseText = ')'
;

   If we wanted something completely different, like showing all tips in a
separate banner, then we could modify the Tip class and override the
showTipDesc() property, perhaps to something like this:

      modify Tip
          showTipDesc()
          {
              tipBanner.clearBanner();

              tipBanner.captureOutput({: desc() });
          }
      ;

