/*
 * notice.c --
 * This application creates a frame, a panel, and 3 panel buttons.
 * A message button, a Quit button (to exit the program) and a 
 * dummy "commit" button.  Extra data is attached to the panel 
 * items by the use of XV_KEY_DATA.  The callback routine for the 
 * quit and Commit buttons is generalized enough that it can apply 
 * to either button (or any arbitrary button) because it extracts 
 * the expected "data" (via XV_KEY_DATA) from whatever panel 
 * button might have called it.
 */
#include <xview/xview.h>
#include <xview/panel.h>
#include <xview/notice.h>

/*
 * assign "data" to panel items using XV_KEY_DATA ... attach the 
 * message panel item, a prompt string specific for the panel 
 * item's notice_prompt, and a callback function if the user 
 * chooses "yes".
 */
#define MSG_ITEM        10 /* any arbitrary integer */
#define NOTICE_PROMPT   11
#define CALLBACK_FUNC   12

main(argc,argv)
int     argc;
char    *argv[];
{
    Frame       frame;
    Panel       panel;
    Panel_item  msg_item;
    Xv_opaque   my_notify_proc();
    extern void  exit();

    /*
     * Initialize XView, and create frame, panel and buttons.
     */
    xv_init(XV_INIT_ARGS, argc, argv, NULL);
    frame = (Frame)xv_create(XV_NULL, FRAME,
        FRAME_LABEL,            argv[0],
        NULL);
    panel = (Panel)xv_create(frame, PANEL,
        PANEL_LAYOUT,           PANEL_VERTICAL,
        NULL);
    msg_item = (Panel_item)xv_create(panel, PANEL_MESSAGE, NULL);
    (void) xv_create(panel, PANEL_BUTTON,
        PANEL_LABEL_STRING,     "Quit",
        PANEL_NOTIFY_PROC,      my_notify_proc,
        XV_KEY_DATA,            MSG_ITEM,       msg_item,
        /* 
         * attach a prompt specific for this button used by 
         * notice_prompt() 
         */
        XV_KEY_DATA,            NOTICE_PROMPT,  "Really Quit?",
        /* 
         * a callback function to call if the user answers "yes" 
         * to prompt 
         */
        XV_KEY_DATA,            CALLBACK_FUNC,  exit,
        NULL);
    /*
     * now that the Quit button is under the message item, 
     * layout horizontally
     */
    xv_set(panel, PANEL_LAYOUT, PANEL_HORIZONTAL, NULL);
    (void) xv_create(panel, PANEL_BUTTON,
        PANEL_LABEL_STRING,     "Commit...",
        PANEL_NOTIFY_PROC,      my_notify_proc,
        XV_KEY_DATA,            MSG_ITEM,       msg_item,
        /* 
         * attach a prompt specific for this button used by 
         * notice_prompt() 
         */
        XV_KEY_DATA,            NOTICE_PROMPT,  "Update all changes?",
        /* 
         * Note there is no callback func here, but one could be 
         * written 
         */
        NULL);

    window_fit(panel);
    window_fit(frame);
    xv_main_loop(frame);
}

/*
 * my_notify_proc()
 * The notice appears as a result of notice_prompt().
 * The "key data" associated with the panel item is extracted via 
 * xv_get().  The resulting choice is displayed in the panel 
 * message item.
 */
Xv_opaque
my_notify_proc(item, event)
Panel_item  item;
Event      *event;
{
    int          result;
    int        (*func)();
    char        *prompt;
    Panel_item   msg_item;
    Panel        panel;

    func = (int(*)())xv_get(item, XV_KEY_DATA, CALLBACK_FUNC);
    prompt = (char *)xv_get(item, XV_KEY_DATA, NOTICE_PROMPT);
    msg_item = (Panel_item)xv_get(item, XV_KEY_DATA, MSG_ITEM);
    panel = (Panel)xv_get(item, PANEL_PARENT_PANEL);
    /*
     *  Create the notice and get a response.
     */
    result = notice_prompt(panel, NULL,
        NOTICE_MESSAGE_STRINGS,
                prompt,
                "Press YES to confirm",
                "Press NO to cancel",
                NULL,
        NOTICE_BUTTON_YES,      "YES",
        NOTICE_BUTTON_NO,       "NO",
        NULL);

    switch(result) {
        case NOTICE_YES:
            xv_set(msg_item, PANEL_LABEL_STRING, "Confirmed", NULL);
            if (func)
                (*func)();
            break;
        case NOTICE_NO:
            xv_set(msg_item, PANEL_LABEL_STRING, "Cancelled", NULL);
            break;
        case NOTICE_FAILED:
            xv_set(msg_item, PANEL_LABEL_STRING, "unable to pop-up", 
              NULL);
            break;
        default:
            xv_set(msg_item, PANEL_LABEL_STRING, "unknown choice", 
              NULL);
    }
}
