/*****************************************************************************
#   Copyright (C) 1994-2008 by David Gordon.
#   All rights reserved.                           
#                                                                           
#   This software is part of a beta-test version of the Consed/Autofinish
#   package.  It should not be redistributed or
#   used for any commercial purpose, including commercially funded
#   sequencing, without written permission from the author and the
#   University of Washington.
#   
#   This software is provided ``AS IS'' and any express or implied
#   warranties, including, but not limited to, the implied warranties of
#   merchantability and fitness for a particular purpose, are disclaimed.
#   In no event shall the authors or the University of Washington be
#   liable for any direct, indirect, incidental, special, exemplary, or
#   consequential damages (including, but not limited to, procurement of
#   substitute goods or services; loss of use, data, or profits; or
#   business interruption) however caused and on any theory of liability,
#   whether in contract, strict liability, or tort (including negligence
#   or otherwise) arising in any way out of the use of this software, even
#   if advised of the possibility of such damage.
#
#   Building Consed from source is error prone and not simple which is
#   why I provide executables.  Due to time limitations I cannot
#   provide any assistance in building Consed.  Even if you do not
#   modify the source, you may introduce errors due to using a
#   different version of the compiler, a different version of motif,
#   different versions of other libraries than I used, etc.  For this
#   reason, if you discover Consed bugs, I can only offer help with
#   those bugs if you first reproduce those bugs with an executable
#   provided by me--not an executable you have built.
# 
#   Modifying Consed is also difficult.  Although Consed is modular,
#   some modules are used by many other modules.  Thus making a change
#   in one place can have unforeseen effects on many other features.
#   It may takes months for you to notice these other side-effects
#   which may not seen connected at all.  It is not feasable for me to
#   provide help with modifying Consed sources because of the
#   potentially huge amount of time involved.
#
#*****************************************************************************/
//
// fileselector.cpp
//
// implementation for the FileSelector object
//
// chrisa 24-Jan-95
//




#include <Xm/Xm.h>
#include <Xm/SelectioB.h>
#include <Xm/FileSB.h>
#include <Xm/MainW.h>
#include <Xm/Form.h>
#include <Xm/Label.h>
#include <stdio.h>
#include <stdarg.h>

#include "sysdepend.h"
#include "messageAndFileSelector.h"
#include "guiapp.h"
#include "handleWindowManagerDelete.h"
#include "hp_exception_kludge.h"


messageAndFileSelector::messageAndFileSelector( 
                                           const char* szDirMask,
                                           const char* szFileName,
                                           const char *szMessage ) {




   Arg aArg[100];
   int nArgs;

   widPopupShell_ = XtVaCreatePopupShell("consed",
                                  topLevelShellWidgetClass,
                                  GuiApp::pGetGuiApp()->widGetTopLevel(),
                                  XmNdeleteResponse, XmDO_NOTHING,
                                  NULL );

   handleWindowManagerDelete( widPopupShell_ );

   
   // the immediate child of the application shell is a
   // main window
   Widget widMainWin = 
     XtVaCreateManagedWidget("mainwin", 
                             xmMainWindowWidgetClass, widPopupShell_,
                             XmNancestorSensitive, True,  
                             NULL );

   //
   // create the form widget
   //
   nArgs = 0;
   XtSetArg(aArg[nArgs],XmNshadowThickness,0); nArgs++;
   XtSetArg(aArg[nArgs],XmNborderWidth,0); nArgs++;
   Widget widForm = XmCreateForm(widMainWin,
                           "form",
                           aArg,
                           nArgs);
   XtManageChild(widForm);



   // don't pop it up--first add everything

   XmString xmsMessage = XmStringCreateLtoR( (char *) szMessage, XmFONTLIST_DEFAULT_TAG  );

   Widget widMessage = XtVaCreateManagedWidget("Fragment List",
                   xmLabelWidgetClass,
                   widForm,
                   XmNtopAttachment, XmATTACH_FORM,
                   XmNtopOffset, 20,
                   XmNleftAttachment, XmATTACH_FORM,
                   XmNleftOffset, 20,
                   XmNlabelString, xmsMessage,
                   XmNalignment, XmALIGNMENT_BEGINNING,                                               
                   NULL );

   XmStringFree( xmsMessage );

   

   nArgs = 0;
   XtSetArg(aArg[nArgs], XmNtopAttachment, XmATTACH_WIDGET); nArgs++;
   XtSetArg(aArg[nArgs], XmNtopWidget, widMessage ); nArgs++;
   XtSetArg(aArg[nArgs], XmNleftAttachment, XmATTACH_FORM); nArgs++;
   XtSetArg(aArg[nArgs], XmNrightAttachment, XmATTACH_FORM); nArgs++;
   XtSetArg(aArg[nArgs], XmNbottomAttachment, XmATTACH_FORM ); nArgs++;
   XtSetArg(aArg[nArgs], XmNtopOffset,20); nArgs++;
   XtSetArg(aArg[nArgs], XmNleftOffset,4); nArgs++;
   XtSetArg(aArg[nArgs], XmNrightOffset,4); nArgs++;
   XtSetArg(aArg[nArgs], XmNcursorPositionVisible, False); nArgs++;
   widFileSelectionBox_ = XmCreateFileSelectionBox( widForm,
                                        "FileDialog",
                                        aArg, 
                                        nArgs);

   XtManageChild( widFileSelectionBox_ );

   // no help button
   XtUnmanageChild(XmSelectionBoxGetChild(widFileSelectionBox_, XmDIALOG_HELP_BUTTON));

   // ok button callback
   XtAddCallback(widFileSelectionBox_, 
		XmNokCallback,
		(XtCallbackProc )fsbCbOk,
		this);

   // cancel button callback
   XtAddCallback(widFileSelectionBox_, 
 		XmNcancelCallback,
 		(XtCallbackProc )fsbCbCancel,
		this);

   assert ( szDirMask);


   setDirMask(szDirMask);        // set directory mask
}


// sets the directory mask for the motif file selection box
void messageAndFileSelector::setDirMask(const char* szDirMask) {
  assert(szDirMask);  // bug spray

  Arg aArg[10];
  int nArgs = 0;

  XmString xmsDirMask = XmStringCreateSimple((char* )szDirMask );
  XtSetArg( aArg[nArgs], XmNdirMask, xmsDirMask ); nArgs++;
  XtSetValues(widFileSelectionBox_, aArg, nArgs);

  XmStringFree(xmsDirMask);
}


// sets the complete specification of the file path i.e. the default
// file selected if the user just presses OK
void messageAndFileSelector::setDirSpec(const char* szDirSpec) {
  Arg aArg[10];
  int nArgs = 0;

  XmString xmsDirSpec = XmStringCreateSimple((char* )szDirSpec);
  XtSetArg( aArg[nArgs], XmNdirSpec, xmsDirSpec ); nArgs++;
  XtSetValues(widFileSelectionBox_, aArg, nArgs);

  XmStringFree(xmsDirSpec);
}


// sets the title string and saves callback pointer before managing
FileName messageAndFileSelector:: filePopupAndGetFilename() {

   // clear the file path member
   soFullFilePath_ = "";

   // pop it all up
   XtPopup( widPopupShell_, XtGrabNone );


   // Do not allow the program to continue until the user has seen and
   // acknowledged this message.
   bBlockApplication_ = true;  // xt callback must clear

   XEvent xevent;
   while( bBlockApplication_ ) {
      XtAppNextEvent( GuiApp::pGetGuiApp()->ctxGetAppContext(), &xevent);
      XtDispatchEvent( &xevent);
   }


   // return whatever the callback did or didn't leave
   // in the private member data
   return soFullFilePath_;
}

void fsbCbOk(Widget wid,
             messageAndFileSelector* pFS,
             XmFileSelectionBoxCallbackStruct* cbs) {


   TRY_CATCH_WRAPPER(

                     char* szFilePath;
                     assert (XmStringGetLtoR(cbs->value, 
                                             XmSTRING_DEFAULT_CHARSET, 
                                             &szFilePath));

                     XtPopdown( pFS->widPopupShell_ );

                     // save in member data whatever we got
                     pFS->soFullFilePath_ = szFilePath ;

                     // unblock
                     pFS->bBlockApplication_ = false;

                     );
}

void fsbCbCancel(Widget wid,
		 messageAndFileSelector* pFS,
		 XmFileSelectionBoxCallbackStruct* cbs) {

  XtPopdown( pFS->widPopupShell_ );

  // unblock
  pFS->bBlockApplication_ = false;
}


// dtor destroys motif widget
messageAndFileSelector :: ~messageAndFileSelector() { 
// bug in X destroy method causes a seg fault on SunOS

//   XtDestroyWidget(widPopupShell_); 
}