/* !DLibEx.c.!RunImage */

/* DeskLib Example main program */

/* Must be linked with:
  
  1. Error.c         (From DeskLib)
  2. AttachMenu.c    (DeskLib migration code)
  3. SaveBox.c       (DeskLib migration code)
  
*/
 
/* Standard C Library includes */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
                         
/* DeskLib includes. !DeskLib must have been "seen" */

#include "DeskLib:Wimp.h"
#include "DeskLib:Icon.h"
#include "DeskLib:WimpSWIs.h"
#include "DeskLib:Event.h"
#include "DeskLib:Menu.h"
#include "DeskLib:Screen.h"
#include "DeskLib:Template.h"
#include "DeskLib:Window.h"
#include "DeskLib:Resource.h"
#include "DeskLib:Handler.h"
#include "DeskLib:EventMsg.h" 
#include "DeskLib:File.h"
#include "DeskLib:SWI.h"

/* Includes for DeskLib migration code */

#include "AttachMenu.h" 
#include "SaveBox.h"

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

/* Global variables */

char message[120];    /* Message to be displayedvin writable field.  */
BOOL boxon;           /* Flag determining whether the window is open */
window_handle mainw;  /* Handle for the main window. In the RISC_OSLib
                         version this is a dbox.                     */
                                                            
/**********************************************************************/

/* Function called when icon bar click occurs */
/* Equivalent to a baricon_clickproc */

BOOL Example_IBarClick(event_pollblock *pb,void *ref)
{   
  BOOL rcode=FALSE;
  
  ref=ref;
  
  if(pb->data.mouse.button.data.select) {
    Icon_SetText(mainw,2,message);         /* Set the text field */
    Window_Show(mainw,open_WHEREVER);      /* Open the window    */
    Icon_SetCaret(mainw,2);                /* Put the caret in the writable
                                              field. Notice that this
                                              is far easier here than
                                              in the RISC_OSLib
                                              version. */
    boxon=TRUE;
    rcode=TRUE;
  }           
  
  return rcode;    /* Returns true if the event has been acted upon */
  
  /* It is important that these functions do not return TRUE after a
    menu click, otherwise the menu attachment function may not work! */

}

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

/* This is the menu handler for the icon bar menu */
/* Note that menu selections now start from 0 */

void Example_MenuHandler(void *ref,int hit[])
{
  ref=ref;
  
  switch(hit[0]) { 
    case 0:
      /* InfoBox displayed automatically. This will never be run */
      break;
    case 1:
      exit(0);   /* Quit the program. No need for confirm box */
      break;
  }
}
                                                    
/**********************************************************************/

/* This function is called when a mouse button is pressed within the
main window. In responds to select and adjust clicks on the action
buttons */

BOOL Example_BoxClick(event_pollblock *pb,void *ref)
{    
  BOOL rcode=FALSE;
  
  ref=ref;
  
  if(pb->data.mouse.button.data.select || pb->data.mouse.button.data.adjust) {
    switch(pb->data.mouse.icon) {
      case 0:                           /* OK button */
        Icon_GetText(mainw,2,message);    /* Store text away */
        Window_Hide(mainw);               /* Close the window */
        boxon=FALSE;                      /* Reset window flag */
        break;
      case 1:                           /* Cancel button */
        Window_Hide(mainw);               /* As above, */
        boxon=FALSE;                      /* but don't store text */
        break;
    }
    rcode=TRUE;
  }
  
  return rcode;       
  
  /* Again, returns FALSE for menu clicks */
}
                                                           
/**********************************************************************/

/* This is called if their is a keypress that is not recognised by the
writable icon. It picks out RETURN presses, and has the same effect as
clicking OK. DeskLib does not automatically 'fake' a click on OK when
RETURN is pressed */

BOOL Example_KeyPress(event_pollblock *pb,void *ref)
{
  BOOL rcode=FALSE;
  
  ref=ref;
  
  if(pb->data.key.code==13) {        /* RETURN */
    Icon_GetText(mainw,2,message);   /* Same as for OK clicks, above */
    Window_Hide(mainw);
    boxon=FALSE;
    rcode=TRUE;
  }
  
  return rcode;
}  

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

/* Called when the SaveBox system wants a file to be saved. This
function is actually very similar to its RISC_OSLib equivalent, but I
have used DeskLib's File commands instead of <stdio.h>. This should be
a little quicker, and I prefer it. Of course, <stdio.h> could still be
used if you need it */

BOOL Example_SaveText(char *name,BOOL safe,void *ref)
{
  file_handle fh;
  char buffer[120];
  
  ref=ref;
  safe=safe;   /* safe flag is ignored, because we do not have a
                  modified flag */
  
  Icon_GetText(mainw,2,buffer);
  
  fh=File_Open(name,file_WRITE);
  File_WriteBytes(fh,buffer,strlen(buffer));
  File_Close(fh);
  
  SWI(3,0,0x08,18,name,0xfff); /* Set file type */
  
  return TRUE;  /* Always return TRUE. If there is a serious chance of
                   not being able to save the data, you should include
                   a system to return FALSE when things go wrong */
                   
}

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

/* Called when the user makes a selection in the main window menu.
Same idea as the icon bar menu handler, above. */          

void Example_BoxMenu(void *ref,int hit[])
{
  ref=ref;
  
  switch(hit[0]) {
    case 0:
      SaveBox_PopUp("TextFile",0xfff,Example_SaveText,0);
      break;
    case 1:
      Icon_SetText(mainw,2,"");
      Icon_SetCaret(mainw,2);
      break;
  }
}                             

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

/* Main function. The program's entry point */

int main(void) 
{    
  menu_ptr ibarmen,dbmen;              
  window_handle progInfo;
  
  Event_Initialise("Example (DeskLib)");  /* Tell the WIMP that we are
                                             here. */
                        
/* If this was a RISC OS 3 only program, I would have used
   Event_Initialise3 */                                             
                                             
  Resource_Initialise("DLibEx");          /* Resources in <DLibEx$Dir>  */
  Template_Initialise();               /* Initialise template system... */
  Template_LoadFile("Templates");      /* ... and load Templates file.  */
  EventMsg_Initialise();               /* Initialise message claiming 
                                          system. */
  
  AttachMenu_Initialise();    /* Initialise the two DeskLib migration */
  SaveBox_Initialise();       /* code modules.                        */

  Screen_CacheModeInfo();     /* Needed for Menu_New to work properly */
  
  /* Create an icon bar menu, complete with an InfoBox which the WIMP
opens automatically. There are ways of doing this with RISC_OSLib, but
they are very rarely used. */
  
  ibarmen=Menu_New("Example","Info,Quit"); 
  progInfo=Window_Create("progInfo",-1);
  Menu_AddSubMenu(ibarmen,0,(menu_ptr)progInfo);  /* Add Info box as submenu.
                                                This looks like a nasty hack,
                                                  but works very well. */
                                               
  
  /* The next two lines are equivalent to baricon() */
  
  Icon_BarIcon("!dlibex",iconbar_RIGHT);
  Event_Claim(event_CLICK,window_ICONBAR,event_ANY,Example_IBarClick,0); 
  
  /* Attach menu to the icon bar icon. */
  
  Event_AttachMenu(window_ICONBAR,ibarmen,Example_MenuHandler,0);
                          
  /* Create main window (window, NOT dialog box as with RISC_OSLib) */
  
  mainw=Window_Create("mainw",-1);                  
  
  /* Set up all the event handlers for the main window: */
                                                          
  /* This one makes the window moveable */
  Event_Claim(event_OPEN,mainw,event_ANY,Handler_OpenWindow,0);
  
  /* This one responds to clicks on the action buttons. It is
approximately equivalent to dbox_eventhandler() */
  Event_Claim(event_CLICK,mainw,event_ANY,Example_BoxClick,0);
  
  /* And this one is for unrecognised key presses. */
  Event_Claim(event_KEY,mainw,event_ANY,Example_KeyPress,0);
  
  /* Create a menu and stick it to the window */
  
  dbmen=Menu_New("Example",">Save,Clear");
  Event_AttachMenu(mainw,dbmen,Example_BoxMenu,0); 

  boxon=FALSE;
  
  /* Set up initial value for text message. Of course, ideally I
should be using MessageTrans but... */
  
  strcpy(message,"Hello, World - DeskLib");
  
  /* Repeatedly collect an event from the Window manager and deal with
it. This is equivalent to event_process() */
  
  for(;;)
    Event_Poll();
                                            
  /* zero return code. This line should never be executed, but it
looks good if the compiler decides to do some checking. */  
    
  return(0);
}
  