/***********************************************************************
 *
 *	Copyright (c) Geoworks 1993-96 -- All Rights Reserved.
 *
 * PROJECT:	C Sample Applications
 * MODULE:	HelpSamp sample application for GEOS help system.
 * FILE:	helpsamp.goc
 *
 * AUTHOR:  	Peter Dudley, 22 January 1993
 *
 * REVISION HISTORY:
 *      Name    Date            Description
 *      ----    ----            -----------
 *      PjD     1/22/93         Initial version
 *
 * DESCRIPTION:
 *	Sample C file for showing how to use help in a C application.
 *	This file contains the entire application, including object
 *	trees and class code.
 *
 * RCS STAMP:
 *	$Id: helpsamp.goc,v 1.1 97/04/04 16:38:57 newdeal Exp $
 *
 ***********************************************************************/

/**************************************************************************
 *		Include files
 **************************************************************************/

@include <stdapp.goh>

/**************************************************************************
 *		Class & Message Definitions
 **************************************************************************/

/*
 * The three messages defined for HelpSampProcessClass are
 * MSG_HELPSAMP_SET_HELP_FILE
 *	Retrieves the selection in the file list and sets the
 *	GenApplication's help file accordingly.
 * MSG_HELPSAMP_SET_AND_DISPLAY
 *	Retrieves the selection in the file list and sets the
 *	GenApplication's help file accordingly, then brings up
 *	the help screen for it.
 * MSG_HELPSAMP_SET_TYPE
 *	Retrieves the selection in the type list and sets the
 *	GenApplication's help type accordingly.
 */
@class HelpSampProcessClass, GenProcessClass;
@message void MSG_HELPSAMP_SET_HELP_FILE();
@message void MSG_HELPSAMP_SET_AND_DISPLAY();
@message void MSG_HELPSAMP_SET_TYPE();
@endc;

@classdecl HelpSampProcessClass, neverSaved;

/**************************************************************************
 *		UI Objects
 **************************************************************************/

@start AppResource;

/*
 * For all types of help other than Normal Help, you must
 * provide a help control object for it.  Almost always,
 * the help controllers are children of the GenApplication,
 * as in this application.  This application offers Normal Help
 * by default, First Aid help through FirstAidHelpControl, and
 * Simple Help through SimpleHelpControl.
 * The helpcontrol objects you define must be on two different
 * GCN lists, as shown in the definition below.  They must each be
 * on the GAGCNLT_NOTIFY_HELP_CONTEXT_CHANGE list, which notifies
 * all help controllers that a context change has occurred.  They
 * must also be on the MGCNLT_ACTIVE_LIST because they are subclassed
 * from GenControl, and all controllers must be on the active list.
 */
@object GenApplicationClass HelpSampApp = {
    GI_visMoniker = list { @HelpSampTextMoniker };
    GI_comp = @HelpSampPrimary,
              @FirstAidHelpControl,
              @SimpleHelpControl;
    gcnList( MANUFACTURER_ID_GEOWORKS, GAGCNLT_WINDOWS ) =
        @HelpSampPrimary;
    gcnList( MANUFACTURER_ID_GEOWORKS, GAGCNLT_NOTIFY_HELP_CONTEXT_CHANGE ) =
	@FirstAidHelpControl,
	@SimpleHelpControl;
    gcnList( MANUFACTURER_ID_GEOWORKS, MGCNLT_ACTIVE_LIST ) =
	@FirstAidHelpControl,
	@SimpleHelpControl;
}

@visMoniker HelpSampTextMoniker = "C Sample App with Help";

@end AppResource;

/*
 * The HelpControlResource resource contains all of our own help
 * controller objects.  They don't have to be placed in their own
 * resource.
 */
@start HelpControlResource;

/* Each help controller controls one type of help.  The type of help
 * actually used at any given time depends on the type assigned to
 * the GenApplication object with ATTR_GEN_HELP_TYPE.  If that attribute
 * is not applied, Normal Help is used.
 * The HCI_helpType instance field defines the type of help managed
 * by the controller.  These are values of the HelpType enumerated type.
 * Because the default behavior is for a help window to be on top of all
 * other dialog boxes, the window priority of each controller is set to
 * WIN_PRIO_ON_TOP.  The effect is to layer the windows according to their
 * places in the GenApplication's child list.
 * Both controllers are set GS_ENABLED because the default GenControl
 * action is to disable its UI until told to enable it.
 */
@object HelpControlClass FirstAidHelpControl = {
    GI_states = @default | GS_ENABLED;
    HCI_helpType = HT_FIRST_AID;
    ATTR_GEN_WINDOW_CUSTOM_WINDOW_PRIORITY = ( WIN_PRIO_ON_TOP );
}

@object HelpControlClass SimpleHelpControl = {
    GI_states = @default | GS_ENABLED;
    HCI_helpType = HT_SIMPLE_HELP;
    ATTR_GEN_WINDOW_CUSTOM_WINDOW_PRIORITY = ( WIN_PRIO_ON_TOP );
}

@end HelpControlResource


@start Interface;

/* HelpSampPrimary has a single menu child and a single organizational
 * GenInteraction child.  It has the help context "TOC," which will create
 * the primary's help trigger (placed in the title bar) and will bring up
 * the TOC context of the help file specified by the GenApplication.
 */
@object GenPrimaryClass HelpSampPrimary  = {
    GI_comp = @ChangeMenu,
              @StatusBox;
    HINT_PRIMARY_FULL_SCREEN;
    ATTR_GEN_HELP_CONTEXT = "TOC";
}

/* The StatusBox GenInteraction is used only to display which help file
 * and which help type are currently active and affected by the help triggers.
 * Because the change dialog boxes have "Apply" triggers, it can be
 * confusing when the selection in the dialog box does not accurately reflect
 * the help conditions; these status glyphs are provided to show what the
 * GenApplication is actually doing.
 * The glyphs that reflect the help state have three different monikers,
 * one for each option.  When the user changes either the file or the type,
 * a message is sent to the glyph to have it change its moniker appropriately.
 */
@object GenInteractionClass StatusBox = {
    GI_comp = @FileBox,
              @TypeBox;
    HINT_ORIENT_CHILDREN_VERTICALLY;
    HINT_FULL_JUSTIFY_CHILDREN_HORIZONTALLY;
}

@object GenInteractionClass FileBox = {
    GI_visMoniker = "Current Help File";
    GI_comp = @FileGlyph;
    HINT_DRAW_IN_BOX;
    HINT_PLACE_MONIKER_ABOVE;
    HINT_CENTER_MONIKER;
    HINT_EXPAND_WIDTH_TO_FIT_PARENT;
}

@object GenGlyphClass FileGlyph = {
    GI_visMoniker = list { @DefFileMon };
}

@visMoniker DefFileMon = "Default Help File";
@visMoniker BoxFileMon = "Help File with Boxes";
@visMoniker CirFileMon = "Help File with Circles";


@object GenInteractionClass TypeBox = {
    GI_visMoniker = "Current Help Type";
    GI_comp = @TypeGlyph;
    HINT_DRAW_IN_BOX;
    HINT_PLACE_MONIKER_ABOVE;
    HINT_CENTER_MONIKER;
    HINT_EXPAND_WIDTH_TO_FIT_PARENT;
}

@object GenGlyphClass TypeGlyph = {
    GI_visMoniker = list { @NorHelpMon };
}

@visMoniker NorHelpMon = "Normal Help";
@visMoniker FirstAidMon = "First Aid Help";
@visMoniker SimHelpMon = "Simple Help";


/* The ChangeMenu has two dialog box children, one to change the
 * GenApplication's help file and one to change the GenApplication's help
 * type.  The ChangeMenu has the help context "Help Files," which will
 * cause the "Help Files" context from the current help file to be
 * displayed when the F1 key is hit and the menu has the focus.
 */
@object GenInteractionClass ChangeMenu = {
    GI_visMoniker = 'C', "Change";
    GI_comp = @ChangeDialog,
              @TypeDialog;
    GII_visibility = GIV_POPUP;
    ATTR_GEN_HELP_CONTEXT = "Help Files";
}

/* The ChangeDialog dialog box allows the user to change the help
 * file currently being used by the application.  It has a GenItemGroup
 * listing three options:  Default file, a file with graphic boxes, and
 * a file with graphic circles.
 * The reply bar has two "Apply" triggers--one that merely changes
 * the file, and one that also displays the new help file immediately--
 * as well as a "Cancel" trigger and its own help trigger.
 * Because this application uses only one help file at a time
 * (individual objects do not use their own files), the GenApplication
 * controls which file is used.  It does this with ATTR_GEN_HELP_FILE.
 * If this attribute is not applied, the default file (helpsamp) will
 * be used.  If the attribute is applied, the file named therein will
 * be used.  The current help file is managed by manipulating this
 * attribute. The ChangeDialog dialog box has the same help context as
 * the Change menu.
 */
@object GenInteractionClass ChangeDialog = {
    GI_visMoniker = 'C', "Change Help File";
    GI_comp = @ChangeList,
              @ChangeTrig,
              @ChangeAndApplyTrig,
              @CancelTrig;
    GII_visibility = GIV_DIALOG;
    GII_type = GIT_MULTIPLE_RESPONSE;
    HINT_ORIENT_CHILDREN_VERTICALLY;
    ATTR_GEN_HELP_CONTEXT = "Help Files";
}

/* The ChangeList does not have its own help context for one reason:
 * it would never be used.  If the user clicks a help trigger, the
 * context of the help trigger is used.  If the user hits the F1 key
 * to get help on the current focus object (the list), it will actually
 * display the help screen of the list entry (a GenItem).  This is
 * because it takes the current focus and searches up the generic tree
 * until it finds a help context; since each list entry has its own
 * context, the list's context would never be invoked.
 */
@object	GenItemGroupClass ChangeList = {
    GI_comp = @DefaultFile,
              @BoxFile,
              @CircFile;
    GIGI_numSelections = 1;
    GIGI_selection = 1;
    HINT_ORIENT_CHILDREN_VERTICALLY;
}

@object GenItemClass DefaultFile = {
    GI_visMoniker = "Use Default Help File";
    GII_identifier = 1;
    ATTR_GEN_HELP_CONTEXT = "Default File";
}

@object GenItemClass BoxFile = {
    GI_visMoniker = "Use Help File with Squares";
    GII_identifier = 2;
    ATTR_GEN_HELP_CONTEXT = "Box File";
}

@object GenItemClass CircFile = {
    GI_visMoniker = "Use Help File with Circles";
    GII_identifier = 3;
    ATTR_GEN_HELP_CONTEXT = "Circle File";
}

/* The ChangeTrig sends MSG_HELPSAMP_SET_HELP_FILE to the
 * process object.  This message will set ATTR_GEN_HELP_FILE
 * correctly but will not dynamically update the help window.
 */
@object GenTriggerClass ChangeTrig = {
    GI_visMoniker = "Change File";
    GTI_destination = process;
    GTI_actionMsg = MSG_HELPSAMP_SET_HELP_FILE;
    HINT_SEEK_REPLY_BAR;
}

/* The ChangeAndApplyTrig sends MSG_HELPSAMP_SET_AND_DISPLAY to
 * the process object.  This message will set ATTR_GEN_HELP_FILE
 * correctly and will dynamically update the help window.
 */
@object GenTriggerClass ChangeAndApplyTrig = {
    GI_visMoniker = "Change File and Display";
    GTI_destination = process;
    GTI_actionMsg = MSG_HELPSAMP_SET_AND_DISPLAY;
    HINT_SEEK_REPLY_BAR;
}

/* The CancelTrig trigger closes the GenInteraction without applying
 * any changes.  */
@object GenTriggerClass CancelTrig = {
    GI_visMoniker = "Cancel";
    ATTR_GEN_TRIGGER_INTERACTION_COMMAND = ( IC_DISMISS );
    HINT_SEEK_REPLY_BAR;
}

/* The TypeDialog allows the user to change the help type currently
 * being used by the application.  It is a much simpler dialog than the
 * help file dialog in that it simply changes the help type without offering
 * the option of dynamically updating the help window(s).
 * The help context of the TypeDialog is "Help Types."  When help is
 * invoked, this help context describes help types to the user.  Each entry
 * in the type list in the dialog box also has its own context and help
 * screen.
 */
@object GenInteractionClass TypeDialog = {
    GI_visMoniker = 'T', "Change Help Type";
    GI_comp = @TypeList;
    GII_visibility = GIV_DIALOG;
    GII_type = GIT_PROPERTIES;
    ATTR_GEN_HELP_CONTEXT = "Help Types";
}

@object GenItemGroupClass TypeList = {
    GI_comp = @NormalItem,
              @FirstAidItem,
              @SimpleItem;
    GIGI_numSelections = 1;
    GIGI_selection = HT_NORMAL_HELP;
    GIGI_applyMsg = MSG_HELPSAMP_SET_TYPE;
    GIGI_destination = process;
    HINT_ORIENT_CHILDREN_VERTICALLY;
}

@object GenItemClass NormalItem = {
    GI_visMoniker = "Normal Help";
    GII_identifier = HT_NORMAL_HELP;
    ATTR_GEN_HELP_CONTEXT = "Normal Help";
}

@object GenItemClass FirstAidItem = {
    GI_visMoniker = "First Aid";
    GII_identifier = HT_FIRST_AID;
    ATTR_GEN_HELP_CONTEXT = "First Aid";
}

@object GenItemClass SimpleItem = {
    GI_visMoniker = "Simple Help";
    GII_identifier = HT_SIMPLE_HELP;
    ATTR_GEN_HELP_CONTEXT = "Simple Help";
}

@end Interface;

/**************************************************************************
 *		Methods for HelpSampProcessClass
 *************************************************************************/

/**************************************************************************
 * 	        MSG_HELPSAMP_SET_HELP_FILE
 **************************************************************************
 * SYNOPSIS:	 Gets the new file from the change file dialog box and
 *               sets ATTR_GEN_HELP_FILE in the GenApplication object.
 * PARAMETERS:	 void
 * RETURNS:      void
 * SIDE EFFECTS: Status glyph updated.
 * STRATEGY:	 Retrieve the selection from ChangeList and set
 *		 ATTR_GEN_HELP_FILE appropriately, updating the status glyph.
 * REVISION HISTORY:
 *      Name    Date            Description
 *      ----    ----            -----------
 *      PjD     1/22/93         Initial version
 *************************************************************************/
@method HelpSampProcessClass, MSG_HELPSAMP_SET_HELP_FILE {
    word curSel;
    char BoxHelpFile[] = "squares";
    char CircHelpFile[] = "circles";

    curSel = @call ChangeList::MSG_GEN_ITEM_GROUP_GET_SELECTION();
    if (curSel == 1) {
	(void) @call HelpSampApp::MSG_META_DELETE_VAR_DATA(
            ATTR_GEN_HELP_FILE);
	(void) @call FileGlyph::MSG_GEN_REPLACE_VIS_MONIKER_OPTR(
	    @DefFileMon, VUM_NOW);
    }
    else if (curSel == 2) {
	(void) @call HelpSampApp::MSG_META_SET_HELP_FILE(BoxHelpFile);
	(void) @call FileGlyph::MSG_GEN_REPLACE_VIS_MONIKER_OPTR(
            @BoxFileMon, VUM_NOW);
    }
    else if (curSel == 3) {
	(void) @call HelpSampApp::MSG_META_SET_HELP_FILE(CircHelpFile);
	(void) @call FileGlyph::MSG_GEN_REPLACE_VIS_MONIKER_OPTR(
            @CirFileMon, VUM_NOW);
    }
} /* MSG_HELPSAMP_SET_HELP_FILE */

/**************************************************************************
 * 	        MSG_HELPSAMP_SET_AND_DISPLAY
 **************************************************************************
 * SYNOPSIS:	 Gets the new file from the change file dialog box and
 *               sets ATTR_GEN_HELP_FILE in the GenApplication object.
 *               Then it invokes the help on the new help file.
 * PARAMETERS:	 void
 * RETURNS:      void
 * SIDE EFFECTS: Status glyph updated.
 * STRATEGY:	 Call MSG_HELPSAMP_SET_HELP_FILE and then
 *		 MSG_META_BRING_UP_HELP.
 * REVISION HISTORY:
 *      Name    Date            Description
 *      ----    ----            -----------
 *      PjD     1/22/93         Initial version
 *************************************************************************/
@method HelpSampProcessClass, MSG_HELPSAMP_SET_AND_DISPLAY {

    (void) @call self::MSG_HELPSAMP_SET_HELP_FILE();
    (void) @call HelpSampPrimary::MSG_META_BRING_UP_HELP();
} /* MSG_HELPSAMP_SET_AND_DISPLAY */

/**************************************************************************
 * 	MSG_HELPSAMP_SET_TYPE for HelpSampProcessClass
 **************************************************************************
 * SYNOPSIS:	 Gets the new type from the change type dialog box and
 *               sets ATTR_GEN_HELP_TYPE in the GenApplication object.
 * PARAMETERS:	 void
 * RETURNS:      void
 * SIDE EFFECTS: Status glyph updated.
 * STRATEGY:	 Retrieve the selection from TypeList and set
 *               ATTR_GEN_HELP_TYPE appropriately, updating the status glyph.
 * REVISION HISTORY:
 *      Name    Date            Description
 *      ----    ----            -----------
 *      PjD     1/22/93         Initial version
 *************************************************************************/
@method HelpSampProcessClass, MSG_HELPSAMP_SET_TYPE {
    word curSel;

    curSel = @call TypeList::MSG_GEN_ITEM_GROUP_GET_SELECTION();
    (void) @call HelpSampApp::MSG_META_DELETE_VAR_DATA(ATTR_GEN_HELP_TYPE);
    if (HT_NORMAL_HELP == curSel) {
	(void) @call TypeGlyph::MSG_GEN_REPLACE_VIS_MONIKER_OPTR(
            @NorHelpMon, VUM_NOW);
    }
    else if (HT_FIRST_AID == curSel) {
	(void) @call TypeGlyph::MSG_GEN_REPLACE_VIS_MONIKER_OPTR(
            @FirstAidMon, VUM_NOW);
	(void) @call HelpSampApp::MSG_META_ADD_VAR_DATA(ATTR_GEN_HELP_TYPE,
            sizeof(HelpType), &curSel);
    }
    else if (HT_SIMPLE_HELP == curSel) {
	(void) @call TypeGlyph::MSG_GEN_REPLACE_VIS_MONIKER_OPTR(
            @SimHelpMon, VUM_NOW);
	(void) @call HelpSampApp::MSG_META_ADD_VAR_DATA(ATTR_GEN_HELP_TYPE,
            sizeof(HelpType), &curSel);
    }
} /* MSG_HELPSAMP_SET_TYPE */

