/* save.c for !DiscEx */

#include "main.h"
#include "client.h"
#include "save.h"



/*
 * "Saveas" functionality for this application is implemented globally; that
 *  is, single handlers for the AboutToBeShown and SaveToFile events are
 *  registered during program initialisation, and a single SaveAs object is
 *  shared by all menus.
 *
 * The three situations covered are:
 *
 *   - saving the contents of a DiscInfo window as a text file
 *   - saving the contents of an Analysis window as a text file
 *   - saving allocation details from an Analysis window as a text file
 *
 * Every DiscInfo and Analysis window has a client handle which points to
 *  a ClientHandleRec data structure. This structure includes three fields
 *  used by the saveas handlers below:
 *
 *    error * (*pf) (FILE *f, IdBlock *idblock, void *p);
 *    char * (*filename) (IdBlock *idblock, void *p);
 *
 *  'pf' is the function to be called to output the desired information to
 *   the given file, and 'filename' is the function which returns the
 *   address of an array (max 256 chars) in which the "saveas" filename
 *   associated with the data is stored.
 *
 *  'idblock' addresses the idblock associated with the event, and 'p'
 *   addresses the private data structure associated with the window (also
 *   found in the client handle structure).
 *
 * Each SaveAs handler below gains access to the client handle via the
 *  ancestor details in the IdBlock associated with the event.
 *
 * Saving by RAM transfers is not supported.
 */



/*
 * This function is called just before the SaveAs object is shown, and fills
 *  in the object's filename and filetype fields.
 */

Bool save_show
(
    int code,
    ToolboxEvent *event,
    IdBlock *idblock,
    void  *handle
)
{
    ObjectId saveas = idblock->self_id;
    ObjectId dbox = idblock->ancestor_id;
    ClientHandlePtr h;
    char *filename;

    IGNORE(handle);
    IGNORE(event);
    IGNORE(code);

    /* determine client handle */
    EDG (ret, toolbox_get_client_handle (0, dbox, (void **)&h));

    /* and find address of filename */
    filename = (h->filename) (idblock, h->p);

    /* initialise fields in SaveAs object */
    EDG (ret, saveas_set_file_name (0, saveas, filename) );
    EDG (ret, saveas_set_file_type (0, saveas, 0xfff) );        /* text */

  ret:
    return TRUE;
}


/*
 * This function is called when the SaveToFile event is raised.
 */

Bool save_save
(
    int code,
    ToolboxEvent *event,
    IdBlock *idblock,
    void  *handle
)
{
    ObjectId saveas = idblock->self_id;
    ObjectId dbox = idblock->ancestor_id;
    SaveAsSaveToFileEvent *ev = (SaveAsSaveToFileEvent *) event;
    ClientHandlePtr h;
    char *filename;
    FILE *f;
    error *err = NULL;
    int flag = 1;

    IGNORE(handle);
    IGNORE(event);
    IGNORE(code);

    /* determine client handle */
    EDG (ret, toolbox_get_client_handle (0, dbox, (void **)&h));

    /* and find address of filename */
    filename = (h->filename) (idblock, h->p);

    _swix (Hourglass_On, 0);

    /* preserve file-name currently in the SaveAs dbox for next time */
    EDG (ret, saveas_get_file_name (0, saveas, filename, 256, NULL) );

    f = fopen (ev->filename, "w");
    if (f != NULL)
    {
        err = (h->pf) (f, idblock, h->p);   /* output text to file */
        fclose (f);
    }

    if (f == NULL || err != NULL)
        flag = 0;
    EDG (ret, saveas_file_save_completed (1, saveas, ev->filename) );

    if (err)
        error_box (err);

  ret:
    _swix (Hourglass_Off, 0);
    return TRUE;
}


