/******************************************************************************
             Copyright (c) 1999 Unigraphics Solutions, Inc.
                       Unpublished - All Rights Reserved

*******************************************************************************/
/*
This is a complete example of using the change state mechanism. In 
this scenario a custom dialog is created that launches a UIStyler 
dialog. When this dialog is launched the button that launches the 
UIStyler dialog becomes greyed out.
*/

#include <Xm/XmAll.h>
#include <uf.h>
#include <uf_ui.h>
#include <uf_ui_xt.h>
#include <uf_styler.h>
/*  Local Function Prototypes */
static void ok_cb( Widget w, XtPointer client_data,
                   XtPointer call_data);
static void back_cb( Widget w, XtPointer client_data,
                     XtPointer call_data);
static void cancel_cb( Widget w, XtPointer client_data,
                       XtPointer call_data);
static void launch_da2_cb( Widget w, XtPointer button_state,
                           XtPointer client_data);
static UF_UI_change_state_fn_t lock_change_state(int new_state);
static int initialize_uf( void );
static void call_end_dialog_xt( XtPointer call_data,
                                XtIntervalId *id );
static void call_end_dialog ( void );
static void create_custom_dialog(Position x, Position y,
                                 Widget parent);
/*  Defines */
#define UFUN_INITIALIZED 0
#define UFUN_NOT_INITIALIZED 1
/*  Global Variables */
static Widget custom_dialog;
static Widget  push_button;
extern void
ufusr(char *param, int *retcod, int param_len)
{
  int        rcode;
  Widget     ug_parent;
  Position   x, y;
  if( initialize_uf() == UFUN_NOT_INITIALIZED )
      return;
  /* Use UG parent and standard dialog area 2 location for */
  /* the custom dialog location                            */
  ug_parent = (Widget)UF_UI_get_default_parent();
  UF_UI_get_DA2_coords(&x, &y);
  create_custom_dialog(x, y, ug_parent);
  rcode = UF_UI_register_change_state_fn(
         (UF_UI_change_state_fn_t)lock_change_state,
         "locktest_change_state");
  if (rcode == UF_UI_FAILURE)
      UF_UI_set_status("Could not register a change state 
function");
  XtManageChild (custom_dialog);
  UF_terminate();
}
static void create_custom_dialog(Position x, Position y,
                                 Widget parent)
{
  int        i;
  Arg        args[20];
  Widget     form;
  XmString   canstr, helpstr, okstr;
  canstr = XmStringCreate(" Back ", XmSTRING_DEFAULT_CHARSET);
  helpstr = XmStringCreate("Cancel", XmSTRING_DEFAULT_CHARSET);
  okstr = XmStringCreate("  OK  ", XmSTRING_DEFAULT_CHARSET);
  /* Create the specified dialog. */
  i = 0;
  XtSetArg(args[i], XmNcancelLabelString, canstr);   i++;
  XtSetArg(args[i], XmNhelpLabelString, helpstr);   i++;
  XtSetArg(args[i], XmNokLabelString, okstr);   i++;
  XtSetArg(args[i], XmNx, x);   i++;
  XtSetArg(args[i], XmNy, y);   i++;
  XtSetArg(args[i], XmNdefaultPosition, False);   i++;
  XtSetArg(args[i], XmNautoUnmanage, False);  i++;
  XtSetArg(args[i], XmNdeleteResponse, XmDO_NOTHING);  i++;
  XtSetArg(args[i], XmNmarginHeight, 10);  i++;
  XtSetArg(args[i], XmNmarginWidth, 0);  i++;
  XtSetArg(args[i], XmNdialogType, XmDIALOG_WORKING);  i++;
  custom_dialog = XmCreateMessageDialog (parent,
                                         "Launch Styler Dialog ",
                                         args, i);
  XtUnmanageChild( XmMessageBoxGetChild(custom_dialog,
                   XmDIALOG_MESSAGE_LABEL) );
  XtAddCallback (custom_dialog, XmNcancelCallback, back_cb, NULL);
  XtAddCallback (custom_dialog, XmNokCallback, ok_cb, NULL);
  XtAddCallback (custom_dialog, XmNhelpCallback, cancel_cb, NULL);
  /* Turn the default button off. */
  XtVaSetValues(custom_dialog,
                XmNdefaultButton, NULL,
                NULL);
  form = XtVaCreateManagedWidget("grp",
                                   xmFormWidgetClass,
                                   custom_dialog,
                                   NULL);
  push_button =  XtVaCreateManagedWidget( "Launch DA2",
                     xmPushButtonWidgetClass, form,
                     XmNleftAttachment, XmATTACH_FORM,
                     XmNrightAttachment, XmATTACH_FORM,
                     NULL );
  XtAddCallback(push_button,
                XmNactivateCallback,
                (XtCallbackProc) launch_da2_cb,
                NULL);
}
/*************************************************************
 Name:         lock_change_state
 Description:  This is called whenever the state changes. It
               is used to grey out the push button on the
               custom dialog.
 *************************************************************/
static UF_UI_change_state_fn_t lock_change_state(int new_state)
{
    if (custom_dialog != NULL)
    {
        if (new_state == UF_UI_LOCK)
        {
            XtSetSensitive(push_button, FALSE);
        }
        else if (new_state == UF_UI_UNLOCK)
        {
            XtSetSensitive(push_button, TRUE);
        }
    }
    return(NULL);
} /* end locktest_change_state */
/*  The following three functions are the navigation button */
/*  callbacks for the custom dialog                         */
/*************************************************************
    Function:    ok_cb
    Description: This is called whenever the OK button is
                 pressed on the custom dialog.
    Input:       w            - the widget with the action
                 client_data  - any data the user wants to
                                pass on.
    Output:      N/A
    Return:      N/A
**************************************************************/
static void
ok_cb( Widget w, XtPointer client_data, XtPointer call_data)
{
  printf("In ok callback... Not doing anything special\n");
}
/*************************************************************
    Function:    back_cb
    Description: This is called whenever the Back button is
                 pressed on the custom dialog.
    Input:       w            - the widget with the action
                 client_data  - any data the user wants to
                                pass on.
    Output:      N/A
    Return:      N/A
**************************************************************/
static void
back_cb( Widget w, XtPointer client_data, XtPointer call_data)
{
  printf("In back callback... Not doing anything special\n");
}
/*************************************************************
    Function:    cancel_cb
    Description: This is called whenever the Cancel button is
                 pressed on the custom dialog.
    Input:       w            - the widget with the action
                 client_data  - any data the user wants to
                                pass on.
    Output:      N/A
    Return:      N/A
**************************************************************/
static void
cancel_cb( Widget w, XtPointer client_data, XtPointer call_data)
{
  int rcode;
  if (initialize_uf() == UFUN_NOT_INITIALIZED)
      return;
  /*  Check the lock status to see if the person is */
  /*  cancelling when they still have either their  */
  /*  UG/Open dialog or UIStyler dialog still up    */
  if (UF_UI_ask_lock_status() == UF_UI_LOCK)
  {
  /*  Because the UG/Open dialog or UIStyler dialog is   */
  /*  still up then you need to send a cancel message    */
  /*  to Unigraphics to cancel this presentation dialog  */
  /*  It is imperative that you cancel the dialog BEFORE */
  /*  unlocking Unigraphics                              */
      rcode = UF_UI_cancel_uf_dialog (UF_UI_FROM_CUSTOM);
      if (rcode == UF_UI_FAILURE)
      {
        UF_UI_set_status("Could not Cancel the dialog");
        /* You still want to destroy your custom dialog */
        call_end_dialog();
      }
      else   
       XtAppAddTimeOut(XtWidgetToApplicationContext(custom_dialog),
                10,
               (XtTimerCallbackProc) call_end_dialog_xt,
               (XtPointer) NULL);
  }
  else
      call_end_dialog();
  UF_terminate();
}
static void call_end_dialog_xt( XtPointer call_data, 
                                XtIntervalId *id )
{
    call_end_dialog();
}
static void call_end_dialog ( void )
{
  int  rcode;
  if (initialize_uf() == UFUN_NOT_INITIALIZED)
      return;
/*  You must unregister your change state function when  */
/*  your custom dialog is dismissed. If you dismiss your */
/*  dialog in the ok and back callback then this should  */
/*  be done there as well                                */
  rcode = UF_UI_register_change_state_fn(
           NULL, "locktest_change_state");
  XtDestroyWidget(custom_dialog);
  UF_terminate();
}
/**************************************************************
 Name:         launch_da2_cb
 Description:  This is called when the user presses the button
               in the custom dialog. It launches a UIStyler
               dialog.
 **************************************************************/
static void
launch_da2_cb( Widget w, XtPointer button_state, XtPointer 
client_data)
{
    int rcode, response;
    int client;
    char msg[132];
    if (initialize_uf() == UFUN_NOT_INITIALIZED)
        return;
/*  Because this is being launched from a custom dialog you must */
/*  lock Unigraphics before calling a UIStyler dialog or a       */
/*  UG/Open dialog to be displayed                               */
    rcode = UF_UI_lock_ug_access (UF_UI_FROM_CUSTOM);
    if (rcode == UF_UI_LOCK_SET)
    {
        /*  Calling the UIStyler dialog */
        rcode = UF_STYLER_create_dialog("/mydir/da2_test.dlg",
                                          NULL,
                                          0,
                                          (void *)&client,
                                          &response
                                  );
        if (rcode != 0)
        {
            UF_get_fail_message(rcode,msg);
            UF_UI_set_status(msg);
        }
        rcode == UF_UI_unlock_ug_access (UF_UI_FROM_CUSTOM);
        if (rcode == UF_UI_NO_LOCK_EXISTED)
            UF_UI_set_status("No lock existed");
    }
    else
    {
        UF_UI_set_status("Can not lock UG at this time");
    }
    UF_terminate();
}
static int initialize_uf( void )
{
    int        uf_is_initialized;
    int        initialize_rcode;
    uf_is_initialized = UF_is_initialized();
    if( uf_is_initialized == 0 )
    {
        initialize_rcode = UF_initialize();
        if( initialize_rcode != 0 )
        {
            printf("Could not initialize User Function\n");
            return (UFUN_NOT_INITIALIZED);
        }
    }
    return (UFUN_INITIALIZED);
}
int ufusr_ask_unload(void)
{
   /*  Want to only unregister the callback during the */
   /*  unloading of the UG/Open program                */
   return ( UF_UNLOAD_SEL_DIALOG );
}