/*
 * DLibrary, an example program using the Acorn Toolbox and TPlusLib.
 * (c) Tony Howat / 20-20 Software, and RISC User 1997
 *
 * This part deals with the add dialogue which appears when a draw file
 * is dragged to the main library window.
 *
 * Version : 1.00
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "kernel.h"
#include "swis.h"

#include "event.h"
#include "toolbox.h"
#include "gadgets.h"
#include "wimplib.h"
#include "window.h"
#include "TPlusLib:drawwin.h"
#include "TPlusLib:flex.h"
#include "tpluslib:tplus.h"
#include "tpluslib:panes.h"
#include "tpluslib:alarm.h"
#include "dlibrary.h" /* headers for routines in dlibrary.c */

/* user messages */
#define CADD_HIDDEN   0x11
#define CADD_OPEN     0x12
#define CADD_CANCEL   0x13
#define CADD_ADD      0x14

/* components in main window */
#define CADDPANE         1
#define CADDDESCRIPTION  6
#define CADDFILENAME     2

/* raises any error x */
#define are(x) if(x) { raise_error(x); exit(0); }

/* structure used to store information for each add in progress, one
 * is malloced for each session and a pointer to it is kept in the
 * toolbox client handle of each add window
 */
typedef struct {
  int *drawdata;
  int draw_length;
  ObjectId pane;
  char filename[255];
} addsession;

/* --- our add window is hidden so free up diagram memory--- */

int add_hidden (int event_code, ToolboxEvent *event_block,
                IdBlock *id_blk, void *h)
{
  addsession *session;

  toolbox_get_client_handle(0,id_blk->self_id,(void *)&session);

  flex_free((flex_ptr)&session->drawdata);
  drawwin_deregister(id_blk->self_id);
  free(session);

  return 0;
}

/* --- called when the add button in the window has been clicked -- */

int add_add (int event_code, ToolboxEvent *event_block,
                IdBlock *id_blk, void *h)
{
  addsession *session;
  char desc[255];

  /* find a pointer to the addsession structure, read in the description
   * and then call lib_add_file (in dlibrary.c) to add it to the library */
  toolbox_get_client_handle(0,id_blk->self_id,(void *)&session);
  writablefield_get_value(0,id_blk->self_id,CADDDESCRIPTION,desc,255,NULL);
  lib_add_file(session->drawdata, session->draw_length, session->filename, desc);
  return 0;
}

/* --- called when main window should be opened --- */

void add_open (char *file)
{
  addsession *add;
  ObjectId mainw;
  _kernel_swi_regs r;

  /* allocate memory for this drawing's addsession structure */
  add=malloc(sizeof(addsession));
  if(add==NULL)
  {
    werr(FALSE,msgs_lookup("nmfaw:No memory for add window"));
    return;
  }

  /* create our main and pane windows, giving us ObjectIds for each */
  are(toolbox_create_object(0,"add",&mainw));
  are(toolbox_create_object(0,"addpane",&add->pane));

  /* open the main window */
  are(window_open_centre(0,mainw,0,0));

  /* register the pane with our library, it will be opened for
   * us */
  are(pane_register(mainw,CADDPANE,add->pane));

  /* allocate memory for and load in the drawing */
  add->draw_length=file_size(file);
  if(flex_alloc((flex_ptr)&add->drawdata, add->draw_length) == FALSE) {
    werr(0, msgs_lookup("nmfda:No room, failed to allocate %iK for draw area"),
         add->draw_length/1024);
    return;
  }

  /* load in the drawfile so we can display our thumbnail */
  r.r[0] = 16;
  r.r[1] = (int)file;
  r.r[2] = (int)add->drawdata;
  r.r[3] = 0;
  if(_kernel_swi(OS_File, &r, &r)) {
    flex_free((flex_ptr)&add->drawdata);
    return;
  }

  /* register the drawing to our pane window */
  drawwin_register(DRAWWIN_SCALE_PIC_BESTFIT,add->pane,(void **)&add->drawdata,add->draw_length,95);

  /* now set the client handle of the host window to point to our add
   * structure */
  toolbox_set_client_handle(0,mainw,add);

  /* fill in addsession structure with the source filename */
  strcpy(add->filename,file);                              

  /* register handlers for all the user events generated by the add window */
  event_register_toolbox_handler(mainw, CADD_HIDDEN, add_hidden, NULL);
  event_register_toolbox_handler(mainw, CADD_ADD, add_add, NULL);
  return;
}


