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

    File:    Window.h
    Author:  Copyright  1992, 1993, 1994, 1995 Jason Williams, Cy Booker 
                                                and Sergio Monesi, 
                                                Mike Smith
    Version: 1.14 (10 Nov 1995)
    Purpose: High-level window management functions
    History: 1.10 (Dec 1994) Jason Williams
             1.11 (05 Mar 1995) - CB - Desk_Window_GetInfo3() now returns 
                                       (Desk_os_error *). 
                                       Added Desk_Window_GainCaret()
             1.12 (14 Jul 1995) - SM - Added Desk_Window_CreateOrig(), 
                                       Desk_Window_DeleteOrig() and
                                       Desk_Window_ForceWholeRedraw()
             1.13 (26 Jul 1995) - SM - Added Desk_Window_MoveWindow()
             1.14 (10 Nov 1995) - MS - Added Desk_Window_IsOpen
*/


#ifndef __Desk_Window_h
#define __Desk_Window_h

#ifdef __cplusplus
	extern "C" {
#endif

#ifndef __Desk_Wimp_h
	#include "Desk.Wimp.h"
#endif

#ifndef __Desk_WimpSWIs_h
	#include "Desk.WimpSWIs.h"
#endif

#ifndef __Desk_Pointer_h
	#include "Desk.Pointer.h"
#endif

#ifndef __Desk_Coord_h
	#include "Desk.Coord.h"
#endif


typedef enum
{
  Desk_open_WHEREVER,             /* As defined in the window template file */
  Desk_open_CENTERED,             /* center of screen */
  Desk_open_CENTEREDUNDERPOINTER, /* Center window on pointer position */
  Desk_open_OVERCARET,            /* Over the current caret position. NOTE: If no
                                caret, window is opened Desk_open_CENTERED */
  Desk_open_UNDERPOINTER,         /* Under the current pointer position (so that
                                the pointer is then in TL corner of window */
  Desk_open_NEARLAST              /* Slightly offset from the T.L. pos of the last
                                window to be opened with Desk_Window_Show  */
} Desk_window_openpos;



extern Desk_window_handle Desk_Window_Create(const char *windowname, int maxtitlesize);
/*
 * This finds the named window template and creates a new copy of the window.
 * It also records the memory allocated for the window so that it can be
 * deallocated when the window is closed (using Desk_Window_Delete)
 *
 * "maxtitlesize" is the maximum length the window's title will be allowed
 * grow to. (See Template.h: Desk_Template_Clone())
 *
 * Returns: The WIMP handle of the newly-created window, or 0 if the template
 * for this window could not be found
 */


extern Desk_window_handle Desk_Window_CreateOrig(const char *windowname);
/*
 * This finds the named window template and creates the window using the
 * data from the template directly (ie. withoud doing a copy).
 * Window created with Desk_Window_CreateOrig should never be deleted but if you
 * want to delete them you must use Desk_Window_DeleteOrig, not Desk_Window_Delete,
 * otherwise the program may crash due to memory deallocation problems.
 *
 * Returns: The WIMP handle of the newly-created window, or 0 if the template
 * for this window could not be found
 */


extern void Desk_Window_Show(Desk_window_handle window, Desk_window_openpos openpos);
/*

 * This opens the given window on-screen in the desired position.
 * (It can be used with ANY window, even if not created with Desk_Window_Create)
 */


extern Desk_window_handle Desk_Window_CreateAndShow(const char *windowname,
                                          int  maxtitlesize,
                                          Desk_window_openpos openpos);
/*
 * Simply calls Desk_Window_Create() and then Desk_Window_Show()
 * (Just to make your programs slightly tidier)
 */


#define Desk_Window_Hide(handle) Desk_Wimp_CloseWindow(handle)
/*
 * Closes the specified window (removes it from screen)
 * THE WINDOW IS NOT DELETED, just "hidden". It is preferable that you use
 * Desk_Window_Create() and Desk_Window_Delete() every time you want a window to
 * appear/disappear, to avoid problems.
 *
 * extern void Desk_Window_Hide(Desk_window_handle window);
 */


extern void Desk_Window_Delete(Desk_window_handle window);
/*
 * This Hides and deletes ANY window.
 * It also removes any Event handlers attached to the window.
 * If the window was created with Desk_Window_Create(), then it also deallocates
 * any memory used by the window.
 */


extern void Desk_Window_DeleteOrig(Desk_window_handle window);
/*
 * This Hides and deletes a window created with Desk_Window_CreateOrig
 * It also removes any Event handlers attached to the window.
 * If the window was created using Desk_Window_Create you *must* use Desk_Window_Delete.
 */


extern void Desk_Window_GetInfo(Desk_window_handle window, Desk_window_info *result);
/*
 * This is simply a frontend to the Desk_Wimp_GetWindowInfo call. However, it
 * returns the Window info block with the icon definitions STRIPPED.
 * Thus, you can use a Desk_window_info structure in your local variables without
 * having to allocate enough memory to cope with any icons that the window
 * happens to have in it. This is the old, slow, nasty RISC OS 2 compatible
 * version of this function. See Desk_Window_GetInfo3 (below) for RISC OS 3
 * specialness
 */


extern void	Desk_Window_GetInfo3(Desk_window_handle window, Desk_window_info *result);
/*
 * This is simply a frontend to the Desk_Wimp_GetWindowInfo call. However, it
 * returns the Window info block with the icon definitions STRIPPED.
 * Thus, you can use a Desk_window_info structure in your local variables without
 * having to allocate enough memory to cope with any icons that the window
 * happens to have in it.
 *
 * This version is a smaller, tidier, faster version of the GetInfo call
 * which makes use of a new feature of the SWI, available only under RISC OS 3
 */


extern void Desk_Window_ParentName(Desk_window_handle window, char *windowname);
/*
 * Given any window's handle, this function attempts to find the name
 * (8 characters only, truncated if necessary) of the template from which
 * the window was created (only works if created with Desk_Window_Create)
 * - if the window handle is a negative number, "iconbar" is returned.
 */


extern Desk_bool Desk_Window_AutoHelp(Desk_window_handle window, Desk_icon_handle icon);
/*
 * This adds an event handler for the given window and icon (Desk_event_ANY and
 * Desk_window_ICONBAR may be used). Every HelpRequest message thereafter
 * received for that window will be answered (if possible) with a message
 * from your messages (see Msgs) file.
 * The message tag used will be constructed from the window's template-name
 * and the icon number, as in:
 *    mainwind.-1   - Any part of the window not covered by an icon
 *    mainwind.3    - Icon 3 of any window created from "mainwind" template
 *
 * In the messages file, you can also use a catch-all message of:
 *    mainwind.*
 * which will catch ALL helprequests for the window, so ANY part of the
 * window is guaranteed to give help (if no specific help for an icon is
 * found, then the catch-all help will be used)
 *
 * NOTE that this function (Window.AutoHelp.c) may be recompiled to use
 * Desk_EventMsg_Claim rather than Desk_Event_Claim if you so desire. However,
 * note that currently EventMsg ignores the icon handle.
 * EventMsg is more efficient than having multiple Desk_Event_Claims on
 * incoming message events (especially when you add individual handlers for
 * single windows/icons), but ONLY if you are using several message event
 * handlers. Thus, the default here is to use Desk_Event_Claim so as to not
 * "pull in" the code for EventMsg unless you want to use it.
 */


extern Desk_bool Desk_Window_HelpHandler(Desk_event_pollblock *event, void *reference);
/*
 * This is an event handler (added with Desk_Window_AutoHelp) which provides
 * help on windows and their icons.
 * If you wish to augment the help available for a window, you can call
 * this handler yourself. Checking if it returns Desk_bool_TRUE or Desk_bool_FALSE gives an
 * indicator of whether or not a help reply has been sent.
 * Generally, you will check if the pointer is in an area of the window
 * and supply help for that special area - if not, you drop back to a
 * "fallback" position, and allow the "default" action, by callinf this
 * handler.
 * The other method is to add your own specialised help handler with
 * Desk_Event_Claim, and then add this handler, so that your handler gets first
 * choice when the event comes in.
 */


extern void Desk_Window_ModeChange(void);
/*
 * This function will go through all your templates and all windows that
 * were created with Desk_Window_ calls, and re-find their outline fonts so
 * that they are displayed correctly - this needs to be done after some
 * mode changes. See Handler.h - Desk_Handler_ModeChangeWithFonts() to see
 * how this should/can be used.
 *
 * NOTE: If you create ANY windows without using Desk_Window_Create calls, then
 * this function will not fix their outline font use - but MUCH MORE
 * IMPORTANTLY it will release the font, which may later be replaced
 * by another font (or worse, cease to exists totally), so strange or
 * unhealthy effects might ensue. i.e. ONLY use this if using Desk_Window_Create.
 *
 * Note also that this does NOT attempt to fix fonts in window titles
 * because
 *  a) The WIMP currently gets antialiased fonts *very* wrong with toolsprites
 *     and/or titlebar selection, so they aren't recommended
 *  b) Acorn DO have a new WIMP which uses an Outline font instead of system,
 *     so the problem WILL go away with the next OS release.
 *  c) This would involve re-creating the window, which would mean a possible
 *     change in the window handle, which is something we can't do.
 */


extern void Desk_Window_SetTitle(Desk_window_handle window, const char *title);
/*
 * (equivalent of RISC OS Lib's Desk_win_settitle, only far better)
 * This sets the text in the titlebar of the given window to the given string
 *
 * NOTE that if the title is not indirected, It will be unable to change
 * the text, i.e. nothing will happen!
 *
 * It has several advantages over Desk_win_settitle, however:
 *  + It uses legal OS calls to work out the rectange to redrawm so works
 *    properly even with strange sized toolsprite sets
 *  + It doesn't try to redraw anything if the window is CLOSED!
 *  + It handles indirected and text-only title icons, rather than bombing
 *    completely if the titlebar is not indirected.
 *  + It actually terminates the string if it was too long to fit!!!
 *
 *  (And people wonder why I think ROLib is a load of excrement!)
 *
 *  Unfortunately it is not possible to only invalidate the VISIBLE area
 *  of the window, so this may still create the occasional flicker of any
 *  windows over the top of your titlebar... this can't be helped.
 */


extern void Desk_Window_BringToFront(Desk_window_handle window);
/*
 *  Pulls the given window to the front of the window stack
 */


#define Desk_Window_ConstrainMouse(WND) (Desk_Pointer_RestrictToWindow(WND))
/*
 *  Constrains the mouse pointer to the window bounds
 *    extern Desk_os_error *Desk_Window_ConstrainMouse(Desk_window_handle window);
 */


extern void Desk_Window_SetExtent(Desk_window_handle wh, int x0, int y0, int x1, int y1);
/*
 *  Change the size of a window's work area extent.
 *  If the window is open on screen, Desk_Wimp_OpenWindow will be automatically
 *  called to force the change to be realised on screen
 */


extern void Desk_Window_ForceRedraw(Desk_window_handle wh,
                               int x0, int y0, int x1, int y1);
/*
 *  Marks a screen area for redraw by the Wimp.
 *  (x0, y0) is the bottom left corner.
 *  Work Area coordinates, ie the top-left corner is generally 0, 0 with y
 *  increasingly negative working down the screen.
 *
 *  Essentially just a veneer for Desk_Wimp_ForceRedraw().
 */


extern void Desk_Window_GetCoords(Desk_window_handle wh, Desk_convert_block *coords);
/*
 *  The coords 'Desk_convert_block' passed into this function is filled
 *  with the relevant info for window 'wh'.
 */


extern void	Desk_Window_GainCaret(Desk_window_handle window);
/*
 * this intelligently gives the specified window the input focus
 * if the window is 0 then it loses any input focus
 * if the window already has the input focus in an icon then nothing happens
 * otherwise the first writable, non-deleted, non-shaded icon gains the caret
 *
 * see also: Desk_Wimp_SetCaretPosition(), Desk_Icon_SetCaret()
 */


extern void	Desk_Window_ForceWholeRedraw(Desk_window_handle window);
/*
 *  Forces the redraw of the window screen area
 */


extern Desk_bool Desk_Window_MoveWindow(Desk_event_pollblock *event, void *reference);
/*
 *  This function allows you to move a window by dragging any (or all)
 *  of its icons. From the event hadler that deals with mouse clicks
 *  you should call this function (passing the parameters you received)
 *  for the icon(s) that you want to work like the title bar.
 *  Remember to set the icon button type to Desk_iconbtype_CLICK (3).
 *
 *  If you want that all the icons work this way, you can just register
 *  this function with the event module using:
 *    Desk_Event_Claim(Desk_event_CLICK, handle, Desk_event_ANY,  Desk_Window_MoveWindow, ref);
 *
 *  In this case you should set all the icons and also the window
 *  background to button type Desk_iconbtype_CLICK (3) so that you will be
 *  able to move the window clicking in any point inside it.
 *
 *  Note that this function always returns Desk_bool_TRUE.
 */


Desk_bool Desk_Window_IsOpen( Desk_window_handle window);
/*
Returns Desk_bool_TRUE is the window is open, ot false if it is closed.
Calls Desk_Error2_XHandle if an error occurs (eg window doesn't exist), and
returns Desk_bool_FALSE is the error isn't handled.
 */



void	Desk_Window_ToggleShow( Desk_window_handle window, Desk_window_openpos openpos);
/*
Calls Desk_Window_Hide if the window is already open, else calls
Desk_Window_Show.
 */

#ifdef __cplusplus
}
#endif

#endif
