/*****************************************************************************
#   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.
#
#*****************************************************************************/
#include    <Xm/ToggleB.h>
#include    <Xm/Form.h>
#include    <Xm/MainW.h>
#include    <Xm/RowColumn.h>
#include    <Xm/TextF.h>
#include    <Xm/Label.h>
#include    <Xm/Xm.h>
#include    <Xm/PushB.h>
#include    "guiSetGeneralPreferences.h"
#include    "assert.h"
#include    "quality.h"
#include    "consedParameters.h"
#include    "guiapp.h"
#include    <stdio.h>
#include    <stdlib.h>
#include    "rwcstring.h"
#include    "rwcregexp.h"
#include    "bIsNumericMaybeWithWhitespace.h"
#include    "numutil.h"
#include    "handleWindowManagerDelete2.h"
#include    "consed.h"
#include    <Xm/ScrolledW.h>
#include    "popupErrorMessage.h"
#include    "hp_exception_kludge.h"


static const int nRightPositionOfLabels = 70;
static const int nLeftPositionOfFields = 80;




#define createLineForIntegerConsedParameter( basename2, label2 ) \
createFormAndLabel( basename2, label2 ); \
 \
sprintf( szTemp, "%d", \
         consedParameters::pGetConsedParameters()->n ## basename2 ## _ ); \
 \
createTextField( basename2, szTemp );




#define createFormAndLabel( basename, labell ) \
 \
xm = XmStringCreateLtoR( labell, XmFONTLIST_DEFAULT_TAG ); \
  \
Widget wid ## basename ## Form = XtVaCreateManagedWidget( "form", \
              xmFormWidgetClass, \
              widRowCol, \
              XmNshadowThickness, 0, \
              NULL ); \
 \
 \
Widget wid ## basename ## Label = XtVaCreateManagedWidget( labell, \
              xmLabelWidgetClass, \
              wid ## basename ## Form, \
              XmNtopAttachment, XmATTACH_FORM, \
              XmNbottomAttachment, XmATTACH_FORM, \
              XmNleftAttachment, XmATTACH_FORM, \
              XmNrightAttachment, XmATTACH_POSITION, \
              XmNrightPosition, nRightPositionOfLabels, \
              XmNalignment, XmALIGNMENT_END, \
              XmNlabelString, xm, \
              NULL ); \
 \
XmStringFree( xm ); 



//   createFormAndLabel( QualityThresholdForLowConsensusQuality,
//                       "Threshold for Low Consensus Quality (highest low)" );
//
//
//
//    Widget widQualityThresholdForLowConsensusQualityForm = XtVaCreateManagedWidget( "form",
//         xmFormWidgetClass,
//         widRowCol,
//         XmNshadowThickness, 0,
//         NULL );

//    Widget widQualityThresholdForLowConsensusQualityLabel = XtVaCreateManagedWidget( 
//         "Threshold for Low Consensus Quality (highest low)",
//         xmLabelWidgetClass,
//         widQualityThresholdForLowConsensusQualityForm,
//         XmNtopAttachment, XmATTACH_FORM,
//         XmNbottomAttachment, XmATTACH_FORM,
//         XmNleftAttachment, XmATTACH_FORM,
//         XmNrightAttachment, XmATTACH_POSITION,
//         XmNrightPosition, nRightPositionOfLabels,
//         XmNalignment, XmALIGNMENT_END,
//         NULL );


#define createTextField( basename, szValue ) \
   wid ## basename ## _ = XtVaCreateManagedWidget( \
   #basename ,  \
   xmTextFieldWidgetClass, \
   wid ## basename ## Form, \
   XmNtraversalOn, True, \
   XmNtopAttachment, XmATTACH_FORM, \
   XmNbottomAttachment, XmATTACH_FORM, \
   XmNleftAttachment, XmATTACH_POSITION, \
   XmNleftPosition, nLeftPositionOfFields, \
   XmNrightAttachment, XmATTACH_FORM, \
   XmNvalue, szValue, \
   XmNcolumns, (short) 8, \
   NULL ); \
 \
   XtAddCallback( wid ## basename ## _, \
                  XmNactivateCallback, \
                  (XtCallbackProc) XmProcessTraversal, \
                  (XtPointer) XmTRAVERSE_NEXT_TAB_GROUP );


// The above macro takes:



//    createTextField( QualityThresholdForLowConsensusQuality, 
//                     szQualityThresholdForLowConsensusQuality );

// and makes:

//    widQualityThresholdForLowConsensusQuality_ = XtVaCreateManagedWidget(
//         "low consensus quality threshold",
//         xmTextFieldWidgetClass,
//         widQualityThresholdForLowConsensusQualityForm,
//         XmNtraversalOn, True,
//         XmNtopAttachment, XmATTACH_FORM,
//         XmNbottomAttachment, XmATTACH_FORM,
//         XmNleftAttachment, XmATTACH_POSITION,
//         XmNleftPosition, nLeftPositionOfFields,
//         XmNrightAttachment, XmATTACH_FORM,
//         XmNvalue, szQualityThresholdForLowConsensusQuality,
//         XmNcolumns, (short) 8,
//         NULL );

//    XtAddCallback( widQualityThresholdForLowConsensusQuality_, 
//                   XmNactivateCallback,
//                   (XtCallbackProc )XmProcessTraversal, 
//                   (XtPointer) XmTRAVERSE_NEXT_TAB_GROUP );



#define createLineWithBooleanConsedParameter( basename, szLabel, szTrueButtonLabel, szFalseButtonLabel ) \
 \
    Widget wid ## basename ## Form = XtVaCreateManagedWidget(  \
        "form", \
        xmFormWidgetClass, \
        widRowCol, \
        XmNshadowThickness, 0, \
        NULL ); \
 \
    xm = XmStringCreateLtoR( szLabel, XmFONTLIST_DEFAULT_TAG ); \
  \
    Widget wid ## basename ## Label = XtVaCreateManagedWidget(  \
        szLabel, \
        xmLabelWidgetClass, \
        wid ## basename ## Form, \
        XmNtopAttachment, XmATTACH_FORM, \
        XmNbottomAttachment, XmATTACH_FORM, \
        XmNleftAttachment, XmATTACH_FORM, \
        XmNrightAttachment, XmATTACH_POSITION, \
        XmNrightPosition, 60, \
        XmNalignment, XmALIGNMENT_END, \
        XmNlabelString, xm, \
        NULL ); \
 \
    XmStringFree( xm ); \
 \
    Widget wid ## basename ## RadioBox = XmCreateRadioBox( \
        wid ## basename ## Form, \
        "radio", \
        NULL , \
        0 ); \
 \
    XtVaSetValues( \
        wid ## basename ## RadioBox, \
        XmNtraversalOn, True, \
        XmNtopAttachment, XmATTACH_FORM, \
        XmNbottomAttachment, XmATTACH_FORM, \
        XmNleftAttachment, XmATTACH_POSITION, \
        XmNleftPosition, 70, \
        XmNrightAttachment, XmATTACH_FORM, \
        XmNorientation, XmHORIZONTAL, \
        XmNshadowThickness, 0, \
        XmNborderWidth, 0, \
        XmNmarginWidth, 0, \
        NULL ); \
 \
    bool b ## basename =  \
        consedParameters::pGetConsedParameters()->b ## basename ## _; \
 \
    wid ## basename ## True_ = XtVaCreateManagedWidget( \
        szTrueButtonLabel, \
        xmToggleButtonWidgetClass, \
        wid ## basename ## RadioBox, \
        XmNset, b ## basename, \
        NULL ); \
 \
    Widget wid ## basename ## False = XtVaCreateManagedWidget( \
        szFalseButtonLabel, \
        xmToggleButtonWidgetClass, \
        wid ## basename ## RadioBox, \
        XmNset, !b ## basename, \
        NULL ); \
 \
    XtManageChild( wid ## basename ## RadioBox );
                                                        





//    createLineWithBooleanConsedParameter( CountPads, "Count *'s", "True", "False" );

// makes:

   /////////////////////
   //
   // whether to count *'s or not

//    Widget widCountPadsForm = XtVaCreateManagedWidget(
//       "form",
//       xmFormWidgetClass,
//       widRowCol,
//       XmNshadowThickness, 0,
//       NULL );

//    Widget widCountPadsLabel = XtVaCreateManagedWidget(
//       "Count *'s",
//       xmLabelWidgetClass,
//       widCountPadsForm,
//       XmNtopAttachment, XmATTACH_FORM,
//       XmNbottomAttachment, XmATTACH_FORM,
//       XmNleftAttachment, XmATTACH_FORM,
//       XmNrightAttachment, XmATTACH_POSITION,
//       XmNrightPosition, 60,
//       XmNalignment, XmALIGNMENT_END,
//       NULL );

//    Widget widCountPadsRadioBox = XmCreateRadioBox(
//       widCountPadsForm,
//       "radio",
//       NULL,
//       0 );

//    XtVaSetValues(
//       widCountPadsRadioBox,
//       XmNtraversalOn, True,
//       XmNtopAttachment, XmATTACH_FORM,  
//       XmNbottomAttachment, XmATTACH_FORM,
//       XmNleftAttachment, XmATTACH_POSITION,
//       XmNleftPosition, 70,
//       XmNrightAttachment, XmATTACH_FORM,
//       XmNorientation, XmHORIZONTAL,
//       XmNshadowThickness, 0,
//       XmNborderWidth, 0,
//       XmNmarginWidth, 0,
//       NULL );

//    bool bCountPads = consedParameters::pGetConsedParameters()->bCountPads_;

//    widCountPadsTrue_ = XtVaCreateManagedWidget(
//       "True",
//       xmToggleButtonWidgetClass,
//       widCountPadsRadioBox,
//       XmNset, bCountPads,
//       NULL );

//    Widget widCountPadsFalse = XtVaCreateManagedWidget(
//       "False",
//       xmToggleButtonWidgetClass,
//       widCountPadsRadioBox,
//       XmNset, !bCountPads,
//       NULL );

//    XtManageChild( widCountPadsRadioBox );





static void CancelButtonCb(Widget wid,
                    XtPointer clientData,
                    XtPointer pCallData ) {

   guiSetGeneralPreferences* pGuiSetGeneralPreferences = 
      (guiSetGeneralPreferences* )clientData;

   TRY_CATCH_WRAPPER(
   delete pGuiSetGeneralPreferences;
   );
}




static void cbLightBackgroundPushButton(
                 Widget wid,
                 XtPointer pClientData,
                 XtPointer pCallData ) {

   TRY_CATCH_WRAPPER(
                     GuiApp::pGetGuiApp()->changeDefaultToLightBackground();
   );

}








guiSetGeneralPreferences :: guiSetGeneralPreferences() {

   int nArgs;
   Arg aArg[50];


   widPopupShell_ = XtVaCreatePopupShell("General Preferences",
                             topLevelShellWidgetClass,
                             GuiApp::pGetGuiApp()->widGetTopLevel(),
                             XmNtitle, "General Preferences",
                             XmNnoResize, False,
                             XmNautoUnmanage, False,
                             XmNtransient, False,
                             XmNdeleteResponse, XmDO_NOTHING,
                             NULL );
   

   handleWindowManagerDelete2( widPopupShell_, CancelButtonCb, this );


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


   widOKButton_ = XtVaCreateManagedWidget( "Apply & Dismiss",
        xmPushButtonWidgetClass,
        widForm,
       XmNbottomAttachment, XmATTACH_FORM,
       XmNbottomOffset, 10,                                           
       XmNtraversalOn, False,
       XmNleftAttachment, XmATTACH_FORM,
       XmNleftOffset, 10,
       NULL );                                                 


   XtAddCallback(widOKButton_,
                 XmNactivateCallback, 
                 (XtCallbackProc )OKButtonCb,
                 this);


   widApplyButton_ = XtVaCreateManagedWidget( 
       "Apply",
       xmPushButtonWidgetClass,
       widForm,
       XmNbottomAttachment, XmATTACH_FORM,
       XmNbottomOffset, 10,                                           
       XmNtraversalOn, False,
       XmNleftAttachment, XmATTACH_WIDGET,
       XmNleftWidget, widOKButton_,                                       
       XmNleftOffset, 10,
       NULL );                                                 


   XtAddCallback(widApplyButton_,
                 XmNactivateCallback, 
                 (XtCallbackProc )ApplyButtonCb,
                 this);


   widCancelButton_ = XtVaCreateManagedWidget( 
       "Cancel",
       xmPushButtonWidgetClass,
       widForm,
       XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
       XmNtopWidget, widOKButton_,
       XmNbottomAttachment, XmATTACH_FORM,
       XmNbottomOffset, 10,                                           
       XmNtraversalOn, False,
       XmNleftAttachment, XmATTACH_WIDGET,
       XmNleftWidget, widApplyButton_,
       XmNleftOffset, 10,
       NULL );                                                 


   XtAddCallback(widCancelButton_,
                 XmNactivateCallback, 
                 (XtCallbackProc )CancelButtonCb,
                 this);


   Widget widScrolledWindow = XtVaCreateManagedWidget(
                                        "scrolled",
                                        xmScrolledWindowWidgetClass,
                                        widForm,
                                        XmNtopAttachment, XmATTACH_FORM,
                                        XmNleftAttachment, XmATTACH_FORM,
                                        XmNrightAttachment, XmATTACH_FORM,
                                        XmNbottomAttachment, XmATTACH_WIDGET,
                                        XmNbottomWidget, widOKButton_,
                                        XmNbottomOffset, 20,
                                        XmNscrollingPolicy, XmAUTOMATIC,
                                        XmNscrollBarDisplayPolicy, XmSTATIC,
                                        NULL );



   Widget widRowCol = XtVaCreateManagedWidget( 
                                        "rowcol", 
                                        xmRowColumnWidgetClass,
                                        widScrolledWindow,
                                        XmNorientation, XmVERTICAL,
                                        XmNnumColumns, 1,
                                        XmNpacking, XmPACK_COLUMN,
                                        NULL );


   XmScrolledWindowSetAreas( widScrolledWindow,
                             (Widget) NULL,
                             (Widget) NULL,
                             widRowCol );


   // needed by the #define macros
   char szTemp[200];
   XmString xm;


   createLineForIntegerConsedParameter( QualityThresholdForLowConsensusQuality,
                       "Threshold for Low Consensus Quality (highest low)" );


   // threshold for high quality discrepancies

   createLineForIntegerConsedParameter( QualityThresholdForFindingHighQualityDiscrepancies,
          "Threshold for High Quality Discrepancy (lowest high)" );
                              

   

   // tag color per cent of base


   createLineForIntegerConsedParameter(TagColorPerCentOfBase,
                                       "Tag Color Per Cent Of Base" );



   // vertical magnification

   createLineForIntegerConsedParameter( VerticalTraceMagnification, 
                                        "Vertical Trace Magnification" );


   // bAutomaticallyScaleTraces_

   createLineWithBooleanConsedParameter( AutomaticallyScaleTraces, "Automatically scale traces", "Yes", "No" );


   /////////////////

   // maximum number of traces shown


   createLineForIntegerConsedParameter( MaximumNumberOfTracesShown,
                                        "Max Number of Traces Shown" );


   /////////////////
   //
   // nTracesWindowInitialPixelWidth_

   createLineForIntegerConsedParameter( TracesWindowInitialPixelWidth,
					"Initial Width of Trace Window in Pixels" );

   //////////////////
   //
   // nTracesWindowInitialPixelHeight_

   createLineForIntegerConsedParameter( TracesWindowInitialPixelHeight,
					"Initial Height of Trace Area in Pixels" );




   //////////////////////
   //
   // whether to write ace format 1 (old) or format 2 (new)




   Widget widWriteThisAceFormatForm = XtVaCreateManagedWidget(
                                    "form",
                                    xmFormWidgetClass,
                                    widRowCol,
                                    XmNshadowThickness, 0,
                                    NULL );

   Widget widWriteThisAceFormat = XtVaCreateManagedWidget(
             "Write This Ace Format",
             xmLabelWidgetClass,
             widWriteThisAceFormatForm,
             XmNtopAttachment, XmATTACH_FORM,
             XmNbottomAttachment, XmATTACH_FORM,
             XmNleftAttachment, XmATTACH_FORM,
             XmNrightAttachment, XmATTACH_POSITION,
             XmNrightPosition, 60,
             XmNalignment, XmALIGNMENT_END,
             NULL );

   Widget widWriteThisAceFormatRadioBox = XmCreateRadioBox(
      widWriteThisAceFormatForm,
      "radio",
      NULL,
      0 );

   XtVaSetValues(
      widWriteThisAceFormatRadioBox,
      XmNtraversalOn, True,
        XmNtopAttachment, XmATTACH_FORM,
        XmNbottomAttachment, XmATTACH_FORM,
        XmNleftAttachment, XmATTACH_POSITION,
        XmNleftPosition, 70,
        XmNrightAttachment, XmATTACH_FORM,
        XmNorientation, XmHORIZONTAL,
        XmNshadowThickness, 0,
        XmNborderWidth, 0,
        XmNmarginWidth, 0,
        NULL );

   bool bWriteAceFormat1 =
      ( consedParameters::pGetConsedParameters()->nWriteThisAceFormat_ == 1 ) ?
      true : false;

   widWriteAceFormat1_ = XtVaCreateManagedWidget(
      "old",
      xmToggleButtonWidgetClass,
      widWriteThisAceFormatRadioBox,
      XmNset, bWriteAceFormat1,
      NULL );

   Widget widWriteAceFormat2 = XtVaCreateManagedWidget(
      "new",
      xmToggleButtonWidgetClass,
      widWriteThisAceFormatRadioBox,
      XmNset, !bWriteAceFormat1,
      NULL );

   XtManageChild( widWriteThisAceFormatRadioBox );

   /////////////////////
   //
   // whether to count *'s or not

   createLineWithBooleanConsedParameter( CountPads, "Count *'s", "Yes", "No" );

   
   createLineWithBooleanConsedParameter( ShowReadsAlphabetically,
                                         "Display reads sorted alphabetically\nor by strand/left read end",
                                         "alpha",
                                         "strand" );


   /////////////////
   //
   // nIgnoreHighQualityDiscrepanciesThisManyBasesFromEndOfAlignedRegion_;

   createLineForIntegerConsedParameter( IgnoreHighQualityDiscrepanciesThisManyBasesFromEndOfAlignedRegion,
                                 "Ignore high quality discrepancies this\nmany bases from end of aligned region" );


   /////////////////
   //
   // nIgnoreUnalignedHighQualitySegmentsShorterThanThis_


   createLineForIntegerConsedParameter( 
         IgnoreUnalignedHighQualitySegmentsShorterThanThis,
         "Ignore unaligned high quality\nsegments shorter than this (counts pads)" );
                                        

   
   /////////////////
   //
   // nCompareContigsAlignsThisManyBasesMax_

       
   createLineForIntegerConsedParameter(
         CompareContigsAlignsThisManyBasesMax,
         "Compare Contigs aligns this many bases max\n(2x bigger number means 4x longer alignment time)" );

   
   ////////////////////////
   //
   // nWhenMakingFakeReadToJoinContigsAddThisManyBasesOnEitherSideOfAlignedRegion_

   createLineForIntegerConsedParameter( 
         WhenMakingFakeReadToJoinContigsAddThisManyBasesOnEitherSideOfAlignedRegion,
         "How many bases should joining read extend\nbefore and after the aligned region" );


   //////////////////////
   //
   // nDebugging_

   createLineForIntegerConsedParameter(
         Debugging,
         "leave 0" );


   createLineWithBooleanConsedParameter( ShowABIBasesInTraceWindow, "Show ABI Bases in Trace Window", "Yes", "No" );

   createLineWithBooleanConsedParameter( DumpCoreIfBoundsError, "Dump Core If Bounds Error", "Yes", "No" );


   createLineWithBooleanConsedParameter( CompareContigsUseBandedRatherThanFullSmithWaterman, "CompareContigs Use Banded (Not Full) S/W", "Yes", "No" );

   createLineForIntegerConsedParameter( CompareContigsBandSize,
                                         "compare contigs band size" );

   // change default background colors to light for making slides

   Widget widLightBackgroundForm = XtVaCreateManagedWidget(
      "form",
      xmFormWidgetClass,
      widRowCol,
      XmNshadowThickness, 0,
      NULL );

   xm = XmStringCreateLtoR( "Make light background in Aligned Reads Windows and Traces Windows.\n(Does not affect existing windows.)\n(You must restart consed if you want to change back.)",
                            XmFONTLIST_DEFAULT_TAG ); 

   Widget widLightBackgroundLabel = XtVaCreateManagedWidget(
      "label",
      xmLabelWidgetClass,
      widLightBackgroundForm,
      XmNtopAttachment, XmATTACH_FORM,
      XmNbottomAttachment, XmATTACH_FORM,
      XmNleftAttachment, XmATTACH_FORM,
      XmNrightAttachment, XmATTACH_POSITION,
      XmNrightPosition, nRightPositionOfLabels,
      XmNalignment, XmALIGNMENT_END,
      XmNlabelString, xm,
      NULL );

   Widget widLightBackgroundPushButton = XtVaCreateManagedWidget(
      "Do it now",
      xmPushButtonWidgetClass,
      widLightBackgroundForm,
      XmNtopAttachment, XmATTACH_FORM,
      XmNbottomAttachment, XmATTACH_FORM,
      XmNleftAttachment, XmATTACH_POSITION,
      XmNleftPosition, nLeftPositionOfFields,
      XmNrightAttachment, XmATTACH_FORM,
      NULL );

   XtAddCallback( widLightBackgroundPushButton,
                  XmNactivateCallback, 
                  (XtCallbackProc )cbLightBackgroundPushButton,
                  this);


   createLineForIntegerConsedParameter(
         AlignedReadsWindowMaxCharsForReadNames,
         "Max Chars For Read Names in Aligned Reads Window" );

   // these values have been set empirically.
   // If you don't set them, then the scrolled window is set very tiny.

   int nSize1 = strlen( "Threshold for Low Consensus Quality (highest low)" );
   int nSize2 = strlen( "Threshold for Navigate/High Quality Discrepancy" );

   int nSizeOfLabel = MAX( nSize1, nSize2 );

   int nWidthOfPopup = nSizeOfLabel * 100 / nRightPositionOfLabels;


   XtVaSetValues(  
          widScrolledWindow,
          XmNwidth, (Dimension) (GuiApp::pGetGuiApp()->nGetFontWidth() * ( nWidthOfPopup + 10)),
          XmNheight, (Dimension) (GuiApp::pGetGuiApp()->nGetFontHeight()* 40 ),
          NULL );




   XtPopup( widPopupShell_, XtGrabNone );

}


void OKButtonCb(Widget wid,
                         XtPointer clientData,
                         XmAnyCallbackStruct* cbs) {

   guiSetGeneralPreferences* pGuiSetGeneralPreferences = 
      (guiSetGeneralPreferences* )clientData;

   TRY_CATCH_WRAPPER(
   assert( wid == pGuiSetGeneralPreferences->widOKButton_ );

   pGuiSetGeneralPreferences->userPushedOKButton();
   );
}




void ApplyButtonCb(Widget wid,
                         XtPointer clientData,
                         XmAnyCallbackStruct* cbs) {

   guiSetGeneralPreferences* pGuiSetGeneralPreferences = 
      (guiSetGeneralPreferences* )clientData;

   TRY_CATCH_WRAPPER(
   assert( wid == pGuiSetGeneralPreferences->widApplyButton_ );

   pGuiSetGeneralPreferences->userPushedApplyButton();
   );
}




void guiSetGeneralPreferences :: userPushedOKButton() {

   if ( !bApplyNewPreferences() )
      return;

   delete this;
}



void guiSetGeneralPreferences :: userPushedApplyButton() {

   bApplyNewPreferences();
}   



bool guiSetGeneralPreferences :: bApplyNewPreferences() {

   // set quality threshold for low consensus quality

   char* szValue = XmTextFieldGetString( widQualityThresholdForLowConsensusQuality_ );

   RWCString soValue( szValue );
   XtFree( szValue );

   int nPerhapsQualityThreshold;
   if (!bIsNumericMaybeWithWhitespace( soValue, nPerhapsQualityThreshold ) ) {
      GuiApp::popupErrorMessage( 
             "quality threshold for low consensus quality must be numeric" );
      return( false );
   }

   if (!  (ucQualityMin <= nPerhapsQualityThreshold &&
           nPerhapsQualityThreshold <= ucQualityMax ) ) {
      char szError[200];
      sprintf( szError, 
               "quality threshold for low consensus quality must be between %d and %d ",
               ucQualityMin, ucQualityMax );
      GuiApp::popupErrorMessage( szError );
      return( false );
   }

   consedParameters::pGetConsedParameters()->nQualityThresholdForLowConsensusQuality_  = nPerhapsQualityThreshold;

   // set quality threshold for high quality discrepancies

   szValue = XmTextFieldGetString( widQualityThresholdForFindingHighQualityDiscrepancies_ );

   soValue = szValue;
   XtFree( szValue );

   if (!bIsNumericMaybeWithWhitespace( soValue, nPerhapsQualityThreshold ) ) {
      GuiApp::popupErrorMessage( "quality threshold must be numeric" );
      return( false );
   }

   if (!  (ucQualityMin <= nPerhapsQualityThreshold &&
           nPerhapsQualityThreshold <= ucQualityMax ) ) {
      char szError[200];
      sprintf( szError, "quality must be between %d and %d ",
               ucQualityMin, ucQualityMax );
      GuiApp::popupErrorMessage( szError );
      return( false );
   }

   consedParameters::pGetConsedParameters()->nQualityThresholdForFindingHighQualityDiscrepancies_  = nPerhapsQualityThreshold;


   // nTagColorPerCentOfBase_


   szValue = XmTextFieldGetString( widTagColorPerCentOfBase_ );

   soValue = szValue;
   XtFree( szValue );


   int nTagColorPerCentOfBase;
   if (!bIsNumericMaybeWithWhitespace( soValue, nTagColorPerCentOfBase )) {
      GuiApp::popupErrorMessage( "tag color per cent of base must be numeric" );
      return( false );
   }

   if ( nTagColorPerCentOfBase < 0 || 100 < nTagColorPerCentOfBase ) {
      GuiApp::popupErrorMessage( "tag color per cent of base must be between 0 and 100" );
      return( false );
   }

   consedParameters::pGetConsedParameters()->nTagColorPerCentOfBase_ = 
      nTagColorPerCentOfBase;

   // set vertical trace magnification


   szValue = XmTextFieldGetString( widVerticalTraceMagnification_ );

   soValue = szValue;
   XtFree( szValue );


   szValue = XmTextFieldGetString( widVerticalTraceMagnification_ );

   soValue = szValue;
   XtFree( szValue );

   int nVerticalTraceMagnification;
   if (!bIsNumericMaybeWithWhitespace( soValue, nVerticalTraceMagnification )) {
      GuiApp::popupErrorMessage( "vertical trace magnification must be numeric" );
      return( false );
   }


   int nOldValue = 
      consedParameters::pGetConsedParameters()->nVerticalTraceMagnification_;

   if ( nOldValue != nVerticalTraceMagnification ) {
      consedParameters::pGetConsedParameters()->nVerticalTraceMagnification_ =
         nVerticalTraceMagnification;

      ConsEd::pGetConsEd()->refreshAllContigWinsAndAllTeditors();
   }


   // bAutomaticallyScaleTraces_

   bool bOldValue = pCP->bAutomaticallyScaleTraces_;
   pCP->bAutomaticallyScaleTraces_ = 
      ( XmToggleButtonGetState(widAutomaticallyScaleTracesTrue_ ) == True );

   if ( bOldValue != pCP->bAutomaticallyScaleTraces_ ) {
      ConsEd::pGetConsEd()->refreshAllContigWinsAndAllTeditors();
   }



   // nMaximumNumberOfTracesShown

   szValue = XmTextFieldGetString( widMaximumNumberOfTracesShown_ );

   soValue = szValue;
   XtFree( szValue );


   int nMaximumNumberOfTracesShown;
   if (!bIsNumericMaybeWithWhitespace( soValue, nMaximumNumberOfTracesShown )) {
      GuiApp::popupErrorMessage( "maximum number of traces shown must be numeric" );
      return( false );
   }

   if ( nMaximumNumberOfTracesShown < 1 ) {
      GuiApp::popupErrorMessage( "maximum number of traces shown must be greater than 0" );
      return( false );
   }

   consedParameters::pGetConsedParameters()->nMaximumNumberOfTracesShown_ = 
      nMaximumNumberOfTracesShown;



   // nTracesWindowInitialPixelWidth_

   szValue = XmTextFieldGetString( widTracesWindowInitialPixelWidth_ );

   soValue = szValue;
   XtFree( szValue );

   int nTracesWindowInitialPixelWidth;
   if ( !bIsNumericMaybeWithWhitespace( soValue, nTracesWindowInitialPixelWidth ) ) {
     popupErrorMessage( "Initial Width of Trace Window in Pixels must be numeric" );
     return( false );
   }
     
   if ( nTracesWindowInitialPixelWidth <= 0 ) {
     popupErrorMessage( "Initial Width of Trace Window in Pixels must be positive" );
     return( false );
   }

   consedParameters::pGetConsedParameters()->nTracesWindowInitialPixelWidth_ =
     nTracesWindowInitialPixelWidth;


   //  nTracesWindowInitialPixelHeight_
   
   szValue = XmTextFieldGetString( widTracesWindowInitialPixelHeight_ );

   soValue = szValue;
   XtFree( szValue );

   int nTracesWindowInitialPixelHeight;
   if ( !bIsNumericMaybeWithWhitespace( soValue, nTracesWindowInitialPixelHeight ) ) {
     popupErrorMessage( "Initial Height of Trace Area in Pixels must be numeric" );
     return( false );
   }

   if ( nTracesWindowInitialPixelHeight <= 0 ) {
     popupErrorMessage( "Initial Height of Trace Area in Pixels must be positive" );
     return( false );
   }

   consedParameters::pGetConsedParameters()->nTracesWindowInitialPixelHeight_ =
     nTracesWindowInitialPixelHeight;


   // nWriteThisAceFormat_

   consedParameters::pGetConsedParameters()->nWriteThisAceFormat_ =
      ( XmToggleButtonGetState( widWriteAceFormat1_ ) == True ) ? 1 : 2;



   // count pads true
   bOldValue = consedParameters::pGetConsedParameters()->bCountPads_;

   consedParameters::pGetConsedParameters()->bCountPads_ =
      XmToggleButtonGetState( widCountPadsTrue_ );

   if ( bOldValue != consedParameters::pGetConsedParameters()->bCountPads_ ) {
      ConsEd::pGetConsEd()->refreshAllContigWinsAndAllTeditors();
   }

   // bShowReadsAlphabetically_ true

   bOldValue = consedParameters::pGetConsedParameters()->bShowReadsAlphabetically_;

   consedParameters::pGetConsedParameters()->bShowReadsAlphabetically_ =
      XmToggleButtonGetState( widShowReadsAlphabeticallyTrue_ );

   if ( bOldValue != consedParameters::pGetConsedParameters()->bShowReadsAlphabetically_ ) {
      // then get a new contigview that has the reads ordered by that number
      ConsEd::pGetConsEd()->getNewContigViewsForAllContigWins();
      // the redisplay
      ConsEd::pGetConsEd()->refreshAllContigWinsAndAllTeditors();
   }


   // IgnoreHighQualityDiscrepanciesThisManyBasesFromEndOfAlignedRegion

   szValue = XmTextFieldGetString( widIgnoreHighQualityDiscrepanciesThisManyBasesFromEndOfAlignedRegion_ );
   soValue = szValue;
   XtFree( szValue );


   int nIgnoreHighQualityDiscrepanciesThisManyBasesFromEndOfAlignedRegion;

   if ( !bIsNumericMaybeWithWhitespace( soValue, nIgnoreHighQualityDiscrepanciesThisManyBasesFromEndOfAlignedRegion )) {
      GuiApp::popupErrorMessage( " nIgnoreHighQualityDiscrepanciesThisManyBasesFromEndOfAlignedRegion must be numeric" );
      return( false );
   }

   if ( nIgnoreHighQualityDiscrepanciesThisManyBasesFromEndOfAlignedRegion < 0 ) {
      GuiApp::popupErrorMessage( "nIgnoreHighQualityDiscrepanciesThisManyBasesFromEndOfAlignedRegion cannot be negative" );
      return( false );
   }

   
   consedParameters::pGetConsedParameters()->nIgnoreHighQualityDiscrepanciesThisManyBasesFromEndOfAlignedRegion_ =
      nIgnoreHighQualityDiscrepanciesThisManyBasesFromEndOfAlignedRegion ;



   // IgnoreUnalignedHighQualitySegmentsShorterThanThis


   szValue = XmTextFieldGetString( widIgnoreUnalignedHighQualitySegmentsShorterThanThis_ );
   soValue = szValue;
   XtFree( szValue );


   int nIgnoreUnalignedHighQualitySegmentsShorterThanThis;

   if ( !bIsNumericMaybeWithWhitespace( soValue, nIgnoreUnalignedHighQualitySegmentsShorterThanThis )) {
      GuiApp::popupErrorMessage( "nIgnoreUnalignedHighQualitySegmentsShorterThanThis must be numeric" );
      return( false );
   }

   consedParameters::pGetConsedParameters()->nIgnoreUnalignedHighQualitySegmentsShorterThanThis_ 
      = nIgnoreUnalignedHighQualitySegmentsShorterThanThis;




   // nCompareContigsAlignsThisManyBasesMax

   szValue = XmTextFieldGetString( widCompareContigsAlignsThisManyBasesMax_ );

   soValue = szValue;
   XtFree( szValue );


   int nCompareContigsAlignsThisManyBasesMax;

   if ( !bIsNumericMaybeWithWhitespace( soValue, nCompareContigsAlignsThisManyBasesMax ) ) {
      GuiApp::popupErrorMessage( "nCompareContigsAlignsThisManyBasesMax must be numeric" );
      return( false );
   }

   consedParameters::pGetConsedParameters()->nCompareContigsAlignsThisManyBasesMax_
      = nCompareContigsAlignsThisManyBasesMax;
                                    

   // nWhenMakingFakeReadToJoinContigsAddThisManyBasesOnEitherSideOfAlignedRegion_

   szValue = XmTextFieldGetString( widWhenMakingFakeReadToJoinContigsAddThisManyBasesOnEitherSideOfAlignedRegion_ );

   soValue = szValue;
   XtFree( szValue );


   int nWhenMakingFakeReadToJoinContigsAddThisManyBasesOnEitherSideOfAlignedRegion;

   if ( !bIsNumericMaybeWithWhitespace( soValue, nWhenMakingFakeReadToJoinContigsAddThisManyBasesOnEitherSideOfAlignedRegion ) ) {
      GuiApp::popupErrorMessage( "nWhenMakingFakeReadToJoinContigsAddThisManyBasesOnEitherSideOfAlignedRegion must be numeric" );
      return( false );
   }

   consedParameters::pGetConsedParameters()->nWhenMakingFakeReadToJoinContigsAddThisManyBasesOnEitherSideOfAlignedRegion_ =
       nWhenMakingFakeReadToJoinContigsAddThisManyBasesOnEitherSideOfAlignedRegion;


   // nDebugging_

   szValue = XmTextFieldGetString( widDebugging_ );

   soValue = szValue;
   XtFree( szValue );

   int nDebugging;
   
   if ( !bIsNumericMaybeWithWhitespace( soValue, nDebugging ) ) {
      GuiApp::popupErrorMessage( "nDebugging must be numeric" );
      return( false );
   }

   consedParameters::pGetConsedParameters()->nDebugging_ =
      nDebugging;



   // bShowABIBasesInTraceWindow_
   
   bOldValue = consedParameters::pGetConsedParameters()->bShowABIBasesInTraceWindow_;

   consedParameters::pGetConsedParameters()->bShowABIBasesInTraceWindow_ =
     XmToggleButtonGetState( widShowABIBasesInTraceWindowTrue_ );


   // bDumpCoreIfBoundsError_

   pCP->bDumpCoreIfBoundsError_ = 
      ( XmToggleButtonGetState( widDumpCoreIfBoundsErrorTrue_ ) == True ) ? true : false;


   // bCompareContigsUseBandedRatherThanFullSmithWaterman_

   pCP->bCompareContigsUseBandedRatherThanFullSmithWaterman_ =
      ( XmToggleButtonGetState( widCompareContigsUseBandedRatherThanFullSmithWatermanTrue_ ) == True ) ? true : false;


   // nCompareContigsBandSize_

   szValue = XmTextFieldGetString( widCompareContigsBandSize_ );
   soValue = szValue;
   XtFree( szValue );

   int nCompareContigsBandSize;
   if ( !bIsNumericMaybeWithWhitespace( soValue, nCompareContigsBandSize ) ) {
      popupErrorMessage( "consed.compareContigsBandSize must be numeric" );
      return( false );
   }

   if ( nCompareContigsBandSize < 0 ) {
      popupErrorMessage( "consed.compareContigsBandSize must be positive" );
      return( false );
   }

   pCP->nCompareContigsBandSize_ = nCompareContigsBandSize;


   //  nAlignedReadsWindowMaxCharsForReadNames_

   nOldValue = pCP->nAlignedReadsWindowMaxCharsForReadNames_;
   szValue = XmTextFieldGetString( widAlignedReadsWindowMaxCharsForReadNames_ );
   soValue = szValue;
   XtFree( szValue );

   int nPerhapsAlignedReadsWindowMaxCharsForReadNames;
   if ( !bIsNumericMaybeWithWhitespace( 
              soValue, 
              nPerhapsAlignedReadsWindowMaxCharsForReadNames ) ) {
      popupErrorMessage("AlignedReadsWindowMaxCharsForReadNames must be numeric" );
      return( false );
   }

   if ( nPerhapsAlignedReadsWindowMaxCharsForReadNames <= 0 ) {
      popupErrorMessage( "AlignedReadsWindowMaxCharsForReadNames must be positive" );
      return( false );
   }


   pCP->nAlignedReadsWindowMaxCharsForReadNames_ =  
      nPerhapsAlignedReadsWindowMaxCharsForReadNames;


   if ( pCP->nAlignedReadsWindowMaxCharsForReadNames_ !=
        nOldValue ) {

      // actually don't need to refresh trace windows, just
      // aligned reads windows
      ConsEd::pGetConsEd()->refreshAllContigWinsAndAllTeditors();
   }


   return( true );
}