/*
    ####             #    #     # #
    #   #            #    #       #          The FreeWare C library for
    #   #  ##   ###  #  # #     # ###             RISC OS machines
    #   # #  # #     # #  #     # #  #   ___________________________________
    #   # ####  ###  ##   #     # #  #
    #   # #        # # #  #     # #  #    Please refer to the accompanying
    ####   ### ####  #  # ##### # ###    documentation for conditions of use
    ________________________________________________________________________

    File:    Dialog.h
    Author:  Copyright  1993 Tim Browse, with modifications by JW
    Version: 1.01 (02 Mar 1994)
    Purpose: Very high-level window (dialogue box) handling
*/

#ifndef __dl_dialog_h
#define __dl_dialog_h

#ifdef __cplusplus
extern "C" {
#endif


#ifndef __dl_wimp_h
#include "Wimp.h"
#endif

#ifndef __dl_window_h
#include "Window.h"
#endif


/*K**************************************************************************

> Dialog Boxes


  A dialog box is a window that is popped open to get user choices and
  then goes away - They can act like menus (go away when you click outside
  them) if opened with Dialog_Show(), or can be permanent windows if
  you open them using Dialog_ShowStatic().
  This code simplifies popping up such dialogs, as it handles opening,
  closing and simple processing of the window for you.

  To use Dialog, you do something like the following:
  (Assuming a window where icon 0 is the 'OK' button, and icon 1 is the
   'Cancel' button)

  {
    dialog dlog;

    dlog = Dialog_Create("template", 0);           // Create the window
    Dialog_ShowStatic(dlog, open_UNDERPOINTER);    // Pop up under pointer

    while (Dialog_WaitForClick(dlog) > 1 || Dialog_Persist(dlog))
      |* Busy wait loop *| ;                       // Wait for OK/Cancel

    Window_Hide(dlog);      // Hide the window before we start processing

    if (Dialog_LastClicked(dlog) == 0)
      ProcessTheData();     // OK was clicked, so go ahead with processing

    Dialog_Destroy(dlog);
  }


  SeeAlso:  dialog_record; dialog

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



typedef struct
  {
    window_handle window;         /* The window handle of this dialog      */

    icon_handle   lastclicked;    /* The icon handle of the last icon that
                                   * was clicked, or dialog_NOCHOICE if no
                                   * icons have been clicked yet.
                                   */

    button_state  button;         /* The button state for the last
                                   * click event.
                                   */
    struct
    {
      unsigned int stillopen : 1; /* The dialogue window is still open     */

      unsigned int persist   : 1; /* It should persist (adjust was clicked)*/

      unsigned int isstatic  : 1; /* It is a static (permanent) dialogue   */
    } state;
  } dialog_record;
/*
  Purpose:  Encapsulate the information pertaining to a particular dialog
            box.  It records the dialog box's current state, and details
            of the last event it received.
  SeeAlso:  dialog; Dialog Boxes
*/



typedef dialog_record *dialog;
/*
  Purpose:  The usual type passed to Dialog functions.  The dialog_record
            type specifies the information contained therein.
  SeeAlso:  dialog_record; Dialog Boxes
*/




#define dialog_CLOSE    ((icon_handle) -1)
/*
  MACRO:    Constant: dialog_CLOSE

  Purpose:  Used by Dialog_WaitForClick to signify when the user causes the
            dialog box to be closed by click outside the window or clicking
            on a close icon.
  SeeAlso:  Dialog_WaitForClick
*/



#define dialog_NOCHOICE ((icon_handle) -2)
/*
  MACRO:    Constant: dialog_NOCHOICE

  Purpose:  The setting returned by Dialog_LastClicked() when the user has
            not yet done anything (i.e. no icons have been clicked and the
            window is open)
  SeeAlso:  Dialog_LastClicked
*/



extern dialog Dialog_Create(char *template_name, int maxtitlesize);
/*
  Inputs:   template_name - the name of the window template to use in
                            constructing the dialog box.
            maxtitlesize  - the maximum space to reserve for the dialog box
                            title bar (See Window_Create for more details).
  Returns:  dialog - the newly created dialog box, or NULL if it was not
                     possible to create the dialog.
  Purpose:  Creates (but does not show) a dialog box from a named template.
  Errors:   Out of memory; Could not find window template
  SeeAlso:  Window_Create; Dialog_Show; Dialog_ShowStatic
*/



extern void Dialog_Destroy(dialog d);
/*
  Inputs:   d - the dialog box to destroy.
  Purpose:  Removes from display and deletes a dialog box structure.
            NOTE that the dialog structure is free'd by this, so you cannot
            call any dialog functions (except Create of course) with it
            after a Destroy.
  SeeAlso:  Dialog_Create; Dialog_Hide
*/




extern void Dialog_Show(dialog d);
/*
  Inputs:   d - the dialog box to show.
  Purpose:  Shows a dialog box in the centre of the screen, as a submenu
            window. (i.e. clicking outside the window or pressing escape
            will remove it)
  SeeAlso:  Dialog_ShowAt; Dialog_ShowStatic
*/



extern void Dialog_ShowAt(dialog d, int x, int y);
/*
  Inputs:   d    - the dialog to show.
            x, y - the position to show the window at (top-left of window
                   area).
  Purpose:  Shows a dialogue box at a specified position. (i.e. clicking
            outside the window or pressing escape will remove it)
  SeeAlso:  Dialog_Show; Dialog_ShowStatic
*/




extern void Dialog_ShowStatic(dialog d, window_openpos openpos);
/*
  Inputs:   d - the dialog to show.
            openpos - where to show the dialog.
  Purpose:  As Dialog_Show(), but more permanent - only a click on the close
            icon (if present) will close it.  Of course it may be closed by
            other means if the application assigns special meaning to an
            icon  - e.g. a cancel button - and closes it itself when this
            icon is clicked on.
            Opens the window at the position requested (see Window.h), of:
              open_ WHEREVER, CENTERED, OVERCARET, UNDERPOINTER, NEARLAST

            (It is very convenient if dialogs always appear under the mouse
            pointer especially as mouse-movement distances (screen sizes)
            increase.)
  SeeAlso:  Dialog_Show; Dialog_ShowAt
*/



extern void Dialog_Hide(dialog d);
/*
  Inputs:   d - the dialog to hide.
  Purpose:  Hides the dialog box by closing the window, but does not
            destroy it.
            Subsequent calls to Dialog_Show[Static] will work correctly.
  SeeAlso:  Dialog_Show; Dialog_Destroy
*/



extern int Dialog_WaitForClick(dialog d);
/*
  Inputs:   d - the dialog to process click events for.
  Returns:  The handle of the icon clicked, or dialog_CLOSE.
  Purpose:  Waits for an icon to be clicked in the dialogue box.  All other
            events are processed as usual.  If the user closes the window,
            dialog_CLOSE is returned.
            Note that Dialog_LastClicked can be called at any time up until
            you call Dialog_Destroy() to find out what the last valid icon
            click was (i.e. the last positive value that Dialog_WaitForClick
            returned)
  SeeAlso:  Dialog_LastClicked
*/



#define Dialog_WindowHandle(d) ((d)->window)
/*
  MACRO:    window_handle Dialog_WindowHandle(dialog d)

  Inputs:   d - the dialog in question.
  Returns:  Window handle of the dialog.
  Purpose:  Obtain the RISC OS Wimp window handle associated with this
            dialog box.  This allows filling in of fields using, e.g.
            DeskLib's 'Icon' module.
*/



#define Dialog_Persist(D) ((D)->state.persist && (D)->lastclicked >= 0)
/*
  MACRO:    BOOL Dialog_Persist(dialog d);

  Inputs:   d - the dialog to be checked for persistence.
  Returns:  TRUE if the last choice made on this dialog was made using
            'adjust' - i.e. the user wants the dialog to stay open;
            FALSE otherwise.
  Purpose:  Find out if the user wants the dialog to stay open after a
            click event.
            Unlike RISC OS Lib, this remembers the last click rather than
            just checking if Adjust is down when called, so will work even
            after an indentation delay.
  SeeAlso:  Dialog_LastClicked; Dialog_StillOpen
*/



#define Dialog_LastClicked(D) ((D)->lastclicked)
/*
  MACRO:    icon_handle Dialog_LastClicked(dialog d);

  Inputs:   d - the dialog to check for the click event.
  Returns:  The handle of the icon that was last clicked on this dialog,
            or dialog_NOCHOICE if the user has not yet clicked an icon.
  Purpose:  find out the last icon clicked on by the user in this dialog.
  SeeAlso:  Dialog_Persist; Dialog_StillOpen
*/



#define Dialog_StillOpen(D) ((D)->state.stillopen)
/*
  MACRO:    BOOL Dialog_StillOpen(dialog d)

  Inputs:   d - the dialog to check.
  Returns:  TRUE if the dialog box is still open on screen;
            FALSE otherwise.
  Purpose:  Find out if a dialog box is still open or not.
  SeeAlso:  Dialog_Persist; Dialog_LastClicked.
*/


#ifdef __cplusplus
}
#endif


#endif
