/*
 * Name   : Capture.c
 * Desc   : C Module task that captures the screen
 * Author : James Bye
 * Date   : 3rd June 1993
 *
 *
 * **********************************************
 * * Disclaimer                                 *
 * * ----------                                 *
 * *                                            *
 * * The software is provided "as is" Acorn     *
 * * Computers Limited ("Acorn") makes no       *
 * * warranty, express or implied, of the       *
 * * merchantability of this software or its    *
 * * fitness for any particular purpose. In no  *
 * * circumstances shall Acorn be liable for any*
 * * damage, loss of profits, or any indirect or*
 * * consequential loss arising out of the use  *
 * * of this software or inability to use this  *
 * * software, even if Acorn has been advised of*
 * * the possibility of such loss.              *
 * **********************************************
 */

#include "wimp.h"        /*  access to WIMP SWIs                      */
#include "wimpt.h"       /*  wimp task facilities                     */
#include "win.h"         /*  registering window handlers              */
#include "event.h"       /*  poll loops, etc                          */
#include "baricon.h"     /*  putting icon on icon bar                 */
#include "sprite.h"      /*  sprite operations                        */
#include "werr.h"        /*  error reporting                          */
#include "res.h"         /*  access to resources                      */
#include "resspr.h"      /*  sprite resources                         */
#include "flex.h"        /*  dynamic mem alloc from WIMP              */
#include "template.h"    /*  reading in template file                 */
#include "bbc.h"         /*  olde-style graphics routines             */
#include "colourtran.h"  /*  interface to colour translation module   */
#include "os.h"          /*  low-level RISCOS access                  */
#include "dbox.h"        /*  dialogue box handling                    */
#include "saveas.h"      /*  data export from dbox by icon dragging   */
#include "visdelay.h"    /*  show the hourglass for delay             */


#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "kernel.h"

#define TRACE 0
#include "trace.h"


/*-- menu definitions --*/

#define m_IconBar_Title "Capture"
#define m_IconBar_Hits  ">Info,Quit"
#define m_IconBar_Info  1
#define m_IconBar_Quit  2

/*-- static variables --*/

static menu    iconbar_menu;
static wimp_i  iconbar_icon;
static char   *iconbar_buffer     = NULL;
static int     iconbar_buffer_len = 8;
static sprite_area *my_area;
static wimp_t task_handle = 0;


/**************************************************
 * Static functions                               *
 **************************************************/

/*
 * save proc
 */

static BOOL save_proc ( char *filename, void *handle )
{                             
  /*-- use sprite op to save sprite area --*/

  wimpt_complain(sprite_area_save(my_area,filename));

  /*-- free the workspace --*/

  flex_free((flex_ptr)&my_area);

  return(TRUE);
}

/*
 * grabs a copy of the screen
 */

#define SAFE_GUARD  (50*1024)  /*-- 50k safe-gaurd --*/

static void grab_screen ( void )
{
int screen_x,screen_y,x0,y0,x1,y1;
int size;    
int xeig,yeig;
os_error *err = NULL;

  /*-- first we must read mode variables for current mode --*/

  screen_x = bbc_vduvar(bbc_XWindLimit);
  screen_y = bbc_vduvar(bbc_YWindLimit);
  xeig     = bbc_vduvar(bbc_XEigFactor);
  yeig     = bbc_vduvar(bbc_YEigFactor);

  /*-- calculate a bounding box for the screen --*/

  x0 = 0;
  y0 = 0;
  x1 = screen_x;
  y1 = screen_y;

  /*-- calculate size of sprite area  --*/

  size = (screen_x * screen_y) + sizeof(sprite_area) + SAFE_GUARD;

  /*-- allocate ourselves a sprite area and init --*/

  if(!flex_alloc((flex_ptr)&my_area,size))
  {
    werr(0,"Not enough space for sprite area");
    return;
  }                                             

  my_area->size   = size;
  my_area->sproff = 16;
  sprite_area_initialise(my_area,size);

  /*-- now we capture the screen as a sprite --*/

  err = sprite_get_given(my_area,"screen",sprite_haspalette,
                         x0,y0,x1<<xeig,y1<<yeig);

  if(err != NULL)
  {
    wimpt_complain(err);
    flex_free((flex_ptr)&my_area);
    return;
  }
  
  /*-- adjust text on iconbar (abit pointless really!) --*/

  strcpy(iconbar_buffer,"Save");
  wimp_set_icon_state(-1,iconbar_icon,0,0);   
  
  /*-- now we will save the sprite using saveas --*/
    
  saveas(0xFF9,"ScreenShot",size,save_proc,NULL,NULL,NULL);

  /*-- adjust text on iconbar (abit pointless really!) --*/

  strcpy(iconbar_buffer,"Ready");
  wimp_set_icon_state(-1,iconbar_icon,0,0);   
}
    

/*
 * shows the info box
 */

extern void show_info ( void )
{
dbox d = dbox_new("info");

  if(d == NULL)
    werr(1,"No memory for DBox");
  dbox_show(d);
  dbox_fillin(d);
  dbox_dispose(&d);              
}                                


/*
 * menu handler for the iconbar
 */

static void iconbar_menu_events ( void *handle, char *hit )
{                          
  handle = handle;
  switch(hit[0])
  {
     case m_IconBar_Info : show_info();
                           break;
     case m_IconBar_Quit : task_handle = 0;
                           exit(0);
                           break;
     default             : break;
  }
}


/*
 * iconbar click proc
 */

static void click_proc ( wimp_i i )
{
  i = i;

  /*-- grab a copy of the screen -*/

  grab_screen();
}


/*
 * service call handler
 */

#define Service_Memory       0x11

extern void MyService ( int service_number, _kernel_swi_regs *r, void *pw )
{
  pw = pw;

  /*-- keep application workspace (r2 holds CAO pointer) */

  switch(service_number)
  {
    case Service_Memory : if(r->r[2] == (int)Image__RO_Base)
                          {
                            r->r[1] = 0; /*-- refuse to release app. workspace --*/
                          }
                          break;
  }
}


/**************************************************
 * Main C function                                *
 **************************************************/

int main ( void )
{
  /*-- init ourselves with the wimp --*/

  wimpt_init("Capture");
  task_handle = wimpt_task();
  res_init("Capture");
  resspr_init();
  flex_init();
  template_init();
  dbox_init();
  visdelay_init();

  event_setmask(wimp_EMPTRLEAVE | wimp_EMPTRENTER);

  trace_on();


  /*-- place the icon on the iconbar --*/
 
  iconbar_buffer = malloc(iconbar_buffer_len);
  strcpy(iconbar_buffer,"Ready");

  iconbar_icon = baricon_textandsprite("!capture",iconbar_buffer,iconbar_buffer_len,
                                          1,click_proc);

  /*-- create & attach the menu to the iconbar --*/
                
  iconbar_menu = menu_new(m_IconBar_Title,m_IconBar_Hits);
  event_attachmenu(win_ICONBAR,iconbar_menu,iconbar_menu_events,NULL);

  /*-- inifinite polling loop --*/

  while(TRUE)
    event_process();
}

/*-- end --*/

