/*
 * Copyright 1993 by the University of Pennsylvania
 *
 * Permission to use, copy, and distribute for non-commercial purposes,
 * is hereby granted without fee, providing that the above copyright
 * notice appear in all copies and that both the copyright notice and this
 * permission notice appear in supporting documentation.
 *
 * The software may be modified for your own purposes, but modified versions
 * may not be distributed.
 *
 * This software is provided "as is" without any expressed or implied warranty.
 */

/**********************************************************************
 This file contiains several MOTIF related funtions which are commonly
 used in MPEGTool
 **********************************************************************/
#include <Xm/DialogS.h>
#include <Xm/RowColumn.h>
#include <Xm/Form.h>
#include <Xm/LabelG.h>
#include <Xm/TextF.h>
#include <Xm/FileSB.h>
#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#define BROWSE_PATTERN_STR "*.stat" /* MPEGTool stat data file's suffix */
/**************************************
     Find top shell of each widget 
 **************************************/
Widget
  GetTopShell(w)
Widget w;
{
  while(w && !XmIsDialogShell(w))
    w = XtParent(w);
  return w;
}
/******************************************
  call back for quit. this Destroys dialog
 ******************************************/
void 
  quit_dialog(widget)
Widget widget;
{
  XtDestroyWidget(GetTopShell(widget));
}
/******************************************
  call back for popdown dilalog. 
  used in main and error.
 ******************************************/
void
  dlg_callback(dialog)
Widget dialog;
{
  XtPopdown(XtParent(dialog));
}
/****************************************/
/* Call backs for text/inter extry box  */
/****************************************/
void
  result_int(ret, returnvalue)
Widget ret;
int *returnvalue;
{
  *returnvalue =  atoi(XmTextGetString(ret));
#ifdef DEBUG
  fprintf(stderr,"the returnvalue is:  -> %d\n", *returnvalue);
#endif
}

void
  result_text(ret, returntext)
Widget ret;
char *returntext;
{
  strcpy(returntext,XmTextFieldGetString(ret));
#ifdef DEBUG
  fprintf(stderr,"the returntext is:  -> %s\n", returntext);
#endif
}

/*********************************************************************
  Widget type that creates a label and textentry box as one component
 *********************************************************************/
/*--------------------- return interger versions ---------------------*/
Widget /* column length control version */
  CreatManagedIntegerTextField(parent, value, col_num) 
Widget parent;
int *value;
int  col_num;
{
  Widget text;
  char value_str[256];
  sprintf(value_str,"%d", *value);
  text = XtVaCreateManagedWidget(NULL, 
           xmTextFieldWidgetClass, parent,
           XmNcolumns,  col_num,
           XmNvalue,    value_str,
           NULL);

  XtAddCallback(text, XmNlosingFocusCallback, result_int, value); 
  XtAddCallback(text, XmNactivateCallback,
    XmProcessTraversal, XmTRAVERSE_NEXT_TAB_GROUP);
  return text;
}

Widget /* form version */
  CreateLabeledTextForm(parent, label_name, value)
Widget parent;
char *label_name;
int  *value;  /* int value */
{
  static Widget ret, form, label;
  char init_value_string[120];

  sprintf(init_value_string,"%d", *value);

  form  = XtVaCreateWidget(NULL, 
            xmFormWidgetClass, parent,
            NULL);
  label = XtVaCreateManagedWidget(label_name, 
            xmLabelGadgetClass,  form,
            XmNleftAttachment,   XmATTACH_FORM,
            XmNrightAttachment,  XmATTACH_FORM,
            XmNtopAttachment,    XmATTACH_FORM,
            XmNalignment,        XmALIGNMENT_BEGINNING,
            NULL);
  ret   = XtVaCreateManagedWidget(NULL, 
            xmTextFieldWidgetClass,   form,
            XmNleftAttachment,   XmATTACH_FORM,
            XmNtopAttachment,    XmATTACH_WIDGET,
            XmNtopWidget,        label,
            XmNrightAttachment,  XmATTACH_FORM,
            XmNbottomAttachment, XmATTACH_FORM,
            XmNcolumns,          20,
            XmNvalue,            init_value_string,
            NULL);
  XtAddCallback(ret, XmNlosingFocusCallback,     result_int, value); 
  XtAddCallback(ret, XmNactivateCallback,     XmProcessTraversal,
    XmTRAVERSE_NEXT_TAB_GROUP);
  return form;
}

Widget /* row column version */
  CreateLabeledTextRC(parent, label_name, value)
Widget parent;
char *label_name;
int  *value;  /* int value */
{
  static Widget ret, rc, label;
  char init_value_string[120];

  sprintf(init_value_string,"%d", *value);

  rc    = XtVaCreateWidget(NULL, 
            xmRowColumnWidgetClass, parent,
            XmNorientation, XmHORIZONTAL,
            NULL);
  label = XtVaCreateManagedWidget(label_name, 
            xmLabelGadgetClass,  rc,
            NULL);
  ret   = XtVaCreateManagedWidget(NULL, 
            xmTextFieldWidgetClass,   rc,
            XmNcolumns,          8,
            XmNvalue,            init_value_string,
            NULL);
  XtAddCallback(ret, XmNlosingFocusCallback,     result_int, value); 
  XtAddCallback(ret, XmNactivateCallback,     XmProcessTraversal,
    XmTRAVERSE_NEXT_TAB_GROUP);
  return rc;
}
/*----------- return text (char*) version, Vertical lable ---------------*/
Widget
  CreateLabeledTextForm2(parent, label_name, text)
Widget parent;
char *label_name;
char *text;
{
  static Widget ret, form, label;
  char init_text_string[120];

  strcpy(init_text_string,text); /* create initial text */

  form  = XtVaCreateWidget("form", 
            xmFormWidgetClass, parent,
            NULL);
  label = XtVaCreateManagedWidget(label_name, 
            xmLabelGadgetClass,  form,
            XmNleftAttachment,   XmATTACH_FORM,
            XmNrightAttachment,  XmATTACH_FORM,
            XmNtopAttachment,    XmATTACH_FORM,
            XmNalignment,        XmALIGNMENT_BEGINNING,
            NULL);
  ret   = XtVaCreateManagedWidget(NULL, 
            xmTextFieldWidgetClass,   form,
            XmNleftAttachment,   XmATTACH_FORM,
            XmNtopAttachment,    XmATTACH_WIDGET,
            XmNtopWidget,        label,
            XmNrightAttachment,  XmATTACH_FORM,
            XmNbottomAttachment, XmATTACH_FORM,
            XmNcolumns,          20,
            XmNvalue,            init_text_string,
            NULL);
  XtAddCallback(ret, XmNlosingFocusCallback,     result_text, text); 
  XtAddCallback(ret, XmNactivateCallback,     XmProcessTraversal,
    XmTRAVERSE_NEXT_TAB_GROUP);
  return form;
}
/*-------- return text (char*) version, Horizontal label ----------------*/
Widget
  CreateLabeledTextForm3(parent, label_name, text)
Widget parent;
char *label_name;
char *text;
{
  static Widget ret, form, label;
  char init_text_string[120];

  strcpy(init_text_string,text); /* create initial text */

  form  = XtVaCreateWidget("form", 
            xmFormWidgetClass, parent,
            NULL);
  label = XtVaCreateManagedWidget(label_name, 
            xmLabelGadgetClass,  form,
            XmNleftAttachment,   XmATTACH_FORM,
            XmNtopAttachment,    XmATTACH_FORM,
            XmNbottomAttachment, XmATTACH_FORM,
            XmNalignment,        XmALIGNMENT_BEGINNING,
            NULL);
  ret   = XtVaCreateManagedWidget(NULL, 
            xmTextFieldWidgetClass,   form,
            XmNleftAttachment,   XmATTACH_WIDGET,
            XmNleftWidget,       label,
            XmNtopAttachment,    XmATTACH_FORM,
            XmNrightAttachment,  XmATTACH_FORM,
            XmNbottomAttachment, XmATTACH_FORM,
            XmNcolumns,          30,
            XmNvalue,            init_text_string,
            NULL);
  XtAddCallback(ret, XmNlosingFocusCallback,     result_text, text); 
  XtAddCallback(ret, XmNactivateCallback,     XmProcessTraversal,
    XmTRAVERSE_NEXT_TAB_GROUP);
  return form;
}
/***********************************************************/
/* callback toggle function                                */
/* The pointer of variable to be changed must be stored in */
/* the widget as XmNuserData.                              */
/***********************************************************/
void
  toggle_set(widget, n, state)
Widget widget;
int n;
XmToggleButtonCallbackStruct *state;
{
  int *value,temp;
  XtVaGetValues(widget, XmNuserData, &value, NULL);
  temp = *value;
  if (state->set) *value = n;
#ifdef DDEBUG
  fprintf(stderr,"%s : %d -> %d : <%s>\n",
              XtName(widget),temp, *value , state->set ? "on" : "off");
#endif
}
/***********************************************************/
/* callback for changing sensitivity/managemnt             */
/***********************************************************/
void
  SetUnmanage(w,umw)
Widget w,umw;
{
  XtUnmanageChild(umw);
}

void
  SetManage(w,mw)
Widget w,mw;
{
  XtManageChild(mw);
}

void
  SetUnsensitive(w,usw)
Widget w,usw;
{
  XtSetSensitive(usw,False);
}

void
  SetSensitive(w,sw)
Widget w,sw;
{
  XtSetSensitive(sw,True);
}
/************************************************************************/
/* Check file name selected by text entry or file dialog and store data.*/
/* If called from file selection dialog, it will back to dialog if the  */
/* file name is not appropriate or directory                            */
/************************************************************************/
void
  file_selected(w,text,cbs)
Widget w;
Widget text;
XmFileSelectionBoxCallbackStruct *cbs;
{
  char *fname,
       *pattern,
       *stat_file_name;
  struct stat s_buf;
  XmString xstr;
  XmTextPosition pos; /* cursor position */
    if(XtIsSubclass(w,xmTextFieldWidgetClass)) { /* called form text */  
    fname = XmTextFieldGetString(w);
  }
  else { /* called from FileSelectionDialog */
    /*------ some internal error ------*/
    if(!XmStringGetLtoR(cbs->value, XmSTRING_DEFAULT_CHARSET, &fname))
      return; 
    /*--- get search pattern ---*/
    XmStringGetLtoR(cbs->pattern, XmSTRING_DEFAULT_CHARSET, &pattern);
    /*------ if only filename has given, add full path ------*/
    if (*fname != '/') { 
      char *dir, *newfname;
      if(XmStringGetLtoR(cbs->dir, XmSTRING_DEFAULT_CHARSET, &dir)) {
        newfname = XtMalloc(strlen(dir) + 1 + strlen(fname) + 1);
        sprintf(newfname, "%s/%s", dir, fname);
        XtFree(fname);
        XtFree(dir);
        fname = newfname;
      }
    }
    /*------ file existance check ------*/
    if(stat(fname, &s_buf) == -1)  return;
    /*------ if dir has been selected ------*/
    if((s_buf.st_mode & S_IFMT) == S_IFDIR) { 
      sprintf(fname,"%s%s",fname,pattern); /* set pattern */
      xstr = XmStringCreateSimple(fname);
      XmFileSelectionDoSearch(w, xstr);
      return;
      XmStringFree(xstr);
    }
    /*------ copy string to the text field ------*/
    XmTextFieldSetString(text,fname);
    pos = XmTextFieldGetLastPosition(text);
    XmTextFieldSetInsertionPosition(text,pos);
    XtDestroyWidget(w);
  }
  XtVaGetValues(text, XmNuserData, &stat_file_name, NULL);
  strcpy(stat_file_name,fname);
  XtFree(fname);
#ifdef DEBUG
  fprintf(stderr, "selected file name :%s\n",stat_file_name);
#endif
  return;
}  

void
  browse_stat_file(w,text)
Widget w, text;
{
  Widget   dialog;
  Arg      args[1];
  XmString pattern;  

  extern void quit_dialog();
  extern void file_selected();
  /*------ set pattern ------*/
  pattern = XmStringCreateSimple(BROWSE_PATTERN_STR);
  XtSetArg(args[0], XmNpattern, pattern);
  dialog = XmCreateFileSelectionDialog(w, "file_browse", args, 1);
  XmStringFree(pattern);
  /*------ labeling ------*/
  XtVaSetValues(XtParent(dialog),
                  XmNtitle, "MPEGTool: Statistics file selection",
                  NULL);
  /*------ get text widget ------*/
  XtAddCallback(dialog, XmNokCallback, file_selected, text);
  XtAddCallback(dialog, XmNcancelCallback, quit_dialog, dialog);
  XtUnmanageChild(XmFileSelectionBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
  XtManageChild(dialog);
  XtPopup(XtParent(dialog), XtGrabNone);
}	







