/*****************************************************************************
#   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    "guiReorderContigs.h"
#include    "handleWindowManagerDelete2.h"
#include    <Xm/Form.h>
#include    <Xm/Label.h>
#include    <Xm/Xm.h>
#include    <Xm/PushB.h>
#include    <Xm/ToggleB.h>
#include    <Xm/TextF.h>
#include    "consed.h"
#include    "hp_exception_kludge.h"
#include    "guiapp.h"
#include    <Xm/List.h>
#include    <Xm/RowColumn.h>
#include    "popupErrorMessage2.h"
#include    "editAddConsensusTag.h"
#include    "editDeleteConsensusTag.h"
#include    "contigEndPair.h"
#include    "bGuiGetAnswerYesNo.h"
#include    "assemblyView.h"



static void cbAddContigEndPair( Widget wid,
                                XtPointer pClientData,
                                XtPointer pCallData ) {
   TRY_CATCH_WRAPPER( 
      guiReorderContigs* pGuiReorderContigs = (guiReorderContigs*) pClientData;
      pGuiReorderContigs->userPushedAdd();
   );
}

static void cbDeleteContigEndPair( Widget wid,
                                   XtPointer pClientData,
                                   XtPointer pCallData ) {
   TRY_CATCH_WRAPPER(
      guiReorderContigs* pGuiReorderContigs = (guiReorderContigs*) pClientData;
      pGuiReorderContigs->userPushedDelete();
   )
}


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

   TRY_CATCH_WRAPPER(
      guiReorderContigs* pGuiReorderContigs = (guiReorderContigs*) pClientData;
      delete pGuiReorderContigs;
                    );

}






void guiReorderContigs :: createWindow() {


   Assembly* pAssembly = ConsEd::pGetAssembly();

   widPopupShell_ = XtVaCreatePopupShell(
      "Reorder Contigs",
      topLevelShellWidgetClass,
      GAPP->widGetTopLevel(),
      XmNtransient, False,
      XmNdeleteResponse, XmDO_NOTHING,
      NULL );

   handleWindowManagerDelete2( widPopupShell_, cbUserPushedDismiss, this );

   Widget widForm = XtVaCreateManagedWidget(
      "form",
      xmFormWidgetClass,
      widPopupShell_,
      NULL );

   Widget widAddLineForm = XtVaCreateManagedWidget(
      "addLineForm",
      xmFormWidgetClass,
      widForm,
      XmNtopAttachment, XmATTACH_FORM,
      XmNleftAttachment, XmATTACH_FORM,
      XmNleftOffset, 10,
      XmNrightAttachment, XmATTACH_FORM,
      XmNrightOffset, 10,
      NULL );
   
   Widget widAbove = widAddLineForm;


   Widget widLabel1 = XtVaCreateManagedWidget(
      "Contig:",
      xmLabelWidgetClass,
      widAddLineForm,
      XmNbottomAttachment, XmATTACH_FORM,
      XmNleftAttachment, XmATTACH_FORM,
      XmNtopAttachment, XmATTACH_FORM,
      NULL );

   widContig1_ = XtVaCreateManagedWidget(
      "contig1",    
      xmTextFieldWidgetClass,
      widAddLineForm,
      XmNbottomAttachment, XmATTACH_FORM,
      XmNtopAttachment, XmATTACH_FORM,
      XmNleftAttachment, XmATTACH_WIDGET,
      XmNleftWidget, widLabel1,
      XmNcolumns, 7,
      NULL );

   Widget widEnd1RadioBox = XmCreateRadioBox( widAddLineForm,
                                              "radio1",
                                              NULL,
                                              0 );

   
   XtVaSetValues( widEnd1RadioBox,
                  XmNtopAttachment, XmATTACH_FORM,
                  XmNbottomAttachment, XmATTACH_FORM,
                  XmNleftAttachment, XmATTACH_WIDGET,
                  XmNleftWidget, widContig1_,
                  XmNorientation, XmHORIZONTAL,
                  NULL );

   XtManageChild( widEnd1RadioBox );

   widLeftEndContig1_ = XtVaCreateManagedWidget(
      "Left End",
      xmToggleButtonWidgetClass,
      widEnd1RadioBox,
      XmNset, True, // default
      NULL );

   Widget widRightEndContig1 = XtVaCreateManagedWidget(
      "Right End",
      xmToggleButtonWidgetClass,
      widEnd1RadioBox,
      XmNset, False, // default
      NULL );

   Widget widLabel2 = XtVaCreateManagedWidget(
      "connected to Contig:",
      xmLabelWidgetClass,
      widAddLineForm,
      XmNbottomAttachment, XmATTACH_FORM,
      XmNtopAttachment, XmATTACH_FORM,
      XmNleftAttachment, XmATTACH_WIDGET,
      XmNleftWidget, widEnd1RadioBox,
      NULL );

   widContig2_ = XtVaCreateManagedWidget(
      "contig2",
      xmTextFieldWidgetClass,
      widAddLineForm,
      XmNbottomAttachment, XmATTACH_FORM,
      XmNtopAttachment, XmATTACH_FORM,
      XmNleftAttachment, XmATTACH_WIDGET,
      XmNleftWidget, widLabel2,
      XmNcolumns, 7,
      NULL );

   Widget widEnd2RadioBox = XmCreateRadioBox( widAddLineForm,
                                              "radio2",
                                              NULL,
                                              0 );

   XtVaSetValues( widEnd2RadioBox,
                  XmNtopAttachment, XmATTACH_FORM,
                  XmNbottomAttachment, XmATTACH_FORM,
                  XmNleftAttachment, XmATTACH_WIDGET,
                  XmNleftWidget, widContig2_,
                  XmNorientation, XmHORIZONTAL,
                  XmNshadowThickness, 0,
                  XmNborderWidth, 0,
                  XmNmarginWidth, 0,
                  NULL );

   widLeftEndContig2_ = XtVaCreateManagedWidget(
      "Left End",
      xmToggleButtonWidgetClass,
      widEnd2RadioBox,
      XmNset, True, // default
      NULL );

   Widget widRightEndContig2 = XtVaCreateManagedWidget(
      "Right End",
      xmToggleButtonWidgetClass,
      widEnd2RadioBox,
      XmNset, False, // default
      NULL );

   XtManageChild( widEnd2RadioBox );


   Widget widAddContigEndPair = XtVaCreateManagedWidget(
      "Add and Restart Assembly View",
      xmPushButtonWidgetClass,
      widForm,
      XmNtopAttachment, XmATTACH_WIDGET,
      XmNtopWidget, widAbove,
      XmNleftAttachment, XmATTACH_POSITION,
      XmNleftPosition, 40,
      NULL );

   widAbove = widAddContigEndPair;

   XtAddCallback( widAddContigEndPair,
                  XmNactivateCallback,
                  cbAddContigEndPair,
                  this );
   
   // start from bottom up

   widDismiss_ = XtVaCreateManagedWidget(
      "Dismiss",
      xmPushButtonWidgetClass,
      widForm,
      XmNbottomAttachment, XmATTACH_FORM,
      XmNbottomOffset, 10,
      XmNleftAttachment, XmATTACH_POSITION,
      XmNleftPosition, 40,
      NULL );

   XtAddCallback( widDismiss_,
                  XmNactivateCallback,
                  cbUserPushedDismiss,
                  this );

   Widget widBelow = widDismiss_;

   Widget widDeleteContigEndPair = XtVaCreateManagedWidget(
      "Delete Selected and Restart Assembly View",
      xmPushButtonWidgetClass,
      widForm,
      XmNbottomAttachment, XmATTACH_WIDGET,
      XmNbottomWidget, widBelow,
      XmNbottomOffset, 20,
      XmNleftAttachment, XmATTACH_POSITION,
      XmNleftPosition, 40,
      NULL );

   XtAddCallback( widDeleteContigEndPair,
                  XmNactivateCallback,
                  cbDeleteContigEndPair,
                  this );

   widBelow = widDeleteContigEndPair;


   int nArgs = 0;
   Arg aArg[500];

   XtSetArg( aArg[nArgs], XmNselectionPolicy, XmSINGLE_SELECT ); ++nArgs;
   XtSetArg( aArg[nArgs], XmNtopAttachment, XmATTACH_WIDGET ); ++nArgs;
   XtSetArg( aArg[nArgs], XmNtopWidget, widAbove ); ++nArgs;
   XtSetArg( aArg[nArgs], XmNbottomAttachment, XmATTACH_WIDGET ); ++nArgs;
   XtSetArg( aArg[nArgs], XmNbottomWidget, widBelow ); ++nArgs;
   XtSetArg( aArg[nArgs], XmNvisibleItemCount, 3 ); ++nArgs;
   XtSetArg( aArg[nArgs], XmNleftAttachment, XmATTACH_FORM ); ++nArgs;
   XtSetArg( aArg[nArgs], XmNrightAttachment, XmATTACH_FORM ); ++nArgs;


   widContigEndPairList_ = XmCreateScrolledList( widForm,
                                            "list",
                                            aArg,
                                            nArgs );

   XtManageChild( widContigEndPairList_ );
      
      
   XtPopup( widPopupShell_, XtGrabNone );

   setExistingUserDefinedContigEndPairs();
}



void guiReorderContigs :: restartAssemblyView() {

   // save this on the stack, in case the memory is freed up by the dtor
   assemblyView* pASV = pAssemblyView_;

   // not needed because assemblyView dtor will delete us
   // delete this;

   delete pASV;

   ConsEd::pGetConsEd()->pAssemblyView_ =
      new assemblyView( );
   ConsEd::pGetConsEd()->pAssemblyView_->createWindow( 
                               ConsEd::pGetAssembly() );
   
}


guiReorderContigs :: ~guiReorderContigs() {

   XtPopdown( widPopupShell_ );

   XtDestroyWidget( widPopupShell_ );

   if ( pAssemblyView_ ) {
      pAssemblyView_->pGuiReorderContigs_ = NULL;
   }
}


void guiReorderContigs :: userPushedAdd() {

   RWCString soContig0 = XmTextFieldGetString( widContig1_ );
   RWCString soContig1 = XmTextFieldGetString( widContig2_ );

   int nContigEnd[2];
   nContigEnd[0] =
      ( XmToggleButtonGetState( widLeftEndContig1_ ) == True ) ?
      nLeftGap : nRightGap;
   
   nContigEnd[1] =
      ( XmToggleButtonGetState( widLeftEndContig2_ ) == True ) ?
      nLeftGap : nRightGap;

   // check that soContig0 and soContig1 are both legitimate

   Contig* pContig[2];
   Assembly* pAssembly = ConsEd::pGetAssembly();


   int nContig;
   for( nContig = 0; nContig <= 1; ++nContig ) {

      RWCString& soContig = ( nContig == 0 ? soContig0 : soContig1 );

      pContig[ nContig ] = pAssembly->pGetContigByVariousNames( soContig );

      if ( ! pContig[ nContig ] ) {
         popupErrorMessage2( widPopupShell_, "contig %s does not exist--please change this name",
                             soContig.data() );
         return;
      }
   }


   // let's see if it contradicts some existing contigEndPair.  In
   // case the user has added a number of user-defined contigEndPairs
   // at once before pushing "RestartAssemblyView", we should also check that it
   // doesn't conflict with some previously-added contigEndPair

   bool bError = false;
   RWCString soErrorMessage;


   RWTPtrOrderedVector<contigEndPair> aUserDefinedContigEndPairs;

   pAssembly->getUserDefinedContigEndPairs( aUserDefinedContigEndPairs );

   int nContigEndPair;
   for( nContigEndPair = 0; 
        nContigEndPair < aUserDefinedContigEndPairs.length();
        ++nContigEndPair ) {
      contigEndPair* pCEP = aUserDefinedContigEndPairs[ nContigEndPair ];

      for( int nContigEnd1 = 0; nContigEnd1 <= 1; ++nContigEnd1 ) {
         for( int nContigEnd2 = 0; nContigEnd2 <= 1; ++nContigEnd2 ) {

            if ( ( pCEP->pContig_[ nContigEnd1 ] == pContig[ nContigEnd2 ] &&
                   pCEP->nWhichEnd_[ nContigEnd1] == nContigEnd[ nContigEnd2 ] ) ) {
               bError = true;
               soErrorMessage += "Problem:  there is already a user-defined contigEndPair making the connection: ";
               soErrorMessage += pCEP->soGetDescription();
               soErrorMessage += " ";
            }
         }
      }
   }




   for( nContig = 0; nContig <= 1; ++nContig ) {
      int nOtherEnd = ( nContig == 0 ? 1 : 0 );
      Contig* pMyContig = pContig[ nContig ];
      int nWhichEnd = nContigEnd[ nContig ];
      
      // pContig, nWhichEnd is connected to 
      // pContig[ nOtherEnd], nContigEnd[ nOtherEnd ]

      // Let's see if pContig, nWhichEnd is connected to some
      // other contig or if it is connected to the same contig,
      // but a different end of it.

      // We find the contig-end that this contig-end is connected to
      // by looking in the Contig object: 

      // It is connected to contig pContig->pContig_[ nWhichEnd ], 
      // end: pContig->nWhichEnd_[ nWhichEnd ]
      
      // is the contig already connected to anything?  If not,
      // there is no inconsistency.
      if ( pMyContig->pContig_[ nWhichEnd ] ) {

         if ( pMyContig->pContig_[ nWhichEnd ] != 
              pContig[ nOtherEnd ] ) {
   
            bError = true;
            contigEndPair* pCEP = pMyContig->pCEP_[ nWhichEnd ];


            if ( pCEP ) {
               soErrorMessage += "Problem:  ";
               if ( pCEP->bUserDefined_ ) {
                  soErrorMessage += "there is already a user-defined contigEndPair making the connection: ";
                  soErrorMessage += pCEP->soGetDescription();
                  soErrorMessage += " ";
               }
               else {
                  soErrorMessage += "there are ";
                  soErrorMessage += RWCString( (long) pCEP->nNumberOfForwardReversePairs_ );
                  soErrorMessage += " forward/reverse pairs supporting the following connection: ";
                  soErrorMessage += pCEP->soGetDescription();
                  soErrorMessage += " ";
               }
            }
            else {
               soErrorMessage += "there is already a connection between ";
               soErrorMessage += szWhichGap( nWhichEnd );
               soErrorMessage += " of ";
               soErrorMessage += pMyContig->soGetName();
               soErrorMessage += " and ";
               soErrorMessage += 
                  szWhichGap( pMyContig->nWhichEnd_[ nWhichEnd ] );
               soErrorMessage += " of ";
               soErrorMessage += pMyContig->pContig_[ nWhichEnd ]->soGetName();
               soErrorMessage += " This link was probably inferred from fwd/rev pair links between other contigs and not directly via fwd/rev pairs between these 2 contig ends. ";
            }
         }
         else if ( pMyContig->nWhichEnd_[ nWhichEnd ] !=
                   nContigEnd[ nOtherEnd ] ) {
   
            bError = true;
            contigEndPair* pCEP = pMyContig->pCEP_[ nWhichEnd ];
            if ( pCEP ) {
               soErrorMessage += "Problem: ";
               if ( pCEP->bUserDefined_ ) {
                  soErrorMessage += "there is already a user-defined contigEndPair making the connection: ";
                  soErrorMessage += pCEP->soGetDescription();
                  soErrorMessage += " Perhaps you meant a different end.";
               }
               // note Sept 2004:  I don't understand why there is an
               // error message only in the case of a user-defined
               // contigEndPair here.  Why not also if there are
               // fwd/rev pairs?
            }
            else {
               soErrorMessage += "Problem: there is already a connection between ";
               soErrorMessage += szWhichGap( nWhichEnd );
               soErrorMessage += " of ";
               soErrorMessage += pMyContig->soGetName();
               soErrorMessage += " and ";
               soErrorMessage += 
                  szWhichGap( pMyContig->nWhichEnd_[ nWhichEnd ] );
               soErrorMessage += " of ";
               soErrorMessage += pMyContig->pContig_[ nWhichEnd ]->soGetName();
               soErrorMessage += " This link was probably inferred from fwd/rev pair links between other contigs and not directly via fwd/rev pairs between these 2 contig ends.";
            }
         }
      } //   if ( pMyContig->pContig_[ nwhichEnd ] ) {
   }


   if ( bError ) {
      contigEndPair cep2( pContig[0],
                          pContig[1],
                          nContigEnd[0],
                          nContigEnd[1] );

      soErrorMessage += " Are you sure you want to make contig-end pair ";
      soErrorMessage += cep2.soGetDescription();
      soErrorMessage += " ?";
      if ( !bGuiGetAnswerYesNo( soErrorMessage ) ) {
         return;
      }
   }



   // put contigEndPair tags on these ends of these contigs

   // I'm not so sure--shouldn't this be added when the user pushes
   // "apply" ?  It could check which already exist and add the ones
   // that don't.  But if they are added here, that wouldn't be
   // necessary--it just adds the one the user has asked to add.  So
   // maybe this is the way to go.  What does "apply" do then?  I
   // guess it would re-create the contig map.  If assembly view is
   // up, it would pop it down and up again.


   RWCString soContigEndPairID = pAssembly->soGetNextContigEndPairID();

   // must figure out where to put this tag.

   int nConsPos[2];
   tag* pTags[2];
   for( nContig = 0; nContig <= 1; ++nContig ) {
      nConsPos[ nContig ] = 
         pContig[ nContig ]->nGetGoodPlaceForContigEndPairTag( nContigEnd[ nContig ] );
      
      // put the tag on the contig

      tag* pTag = new tag( NULL, // LocatedFragment
                           pContig[ nContig ],
                           "contigEndPair",
                           nConsPos[ nContig ],
                           nConsPos[ nContig ],
                           false, // bNoTrans
                           "", // soComment
                           soConsed, // "consed"
                           soEmptyString, // current date/time
                           false ); // bNoTrans
      // save to record in cep
      pTags[ nContig ] = pTag;

      int nUnpaddedStart = 
         pContig[ nContig ]->nUnpaddedIndex( nConsPos[ nContig ] );


      RWCString soBases;
      pContig[ nContig ]->getPartOfUnpaddedConsensus( 
         nUnpaddedStart,
         10,
         soBases,
         ( nContigEnd[ nContig ] == nLeftGap ? true : false ), // bComplemented
         ( nContigEnd[ nContig ] == nLeftGap ? false : true ) ); // bTowardsIncreasingUnpaddedPositions

      pTag->soMiscData_ = soContigEndPairID;
      pTag->soMiscData_ += "\n";
      pTag->soMiscData_ += ( nContigEnd[ nContig ] == nLeftGap ?
                            "<-gap" : "gap->" );
      pTag->soMiscData_ += "\n";
      pTag->soMiscData_ += soBases;

      EditAction* pEditAction = new editAddConsensusTag( pTag );
      ConsEd::pGetConsEd()->doEditAction( pEditAction,
                                          true ); // bWriteToEditHistoryFile

   }


   // check that the new tag will be correctly interpreted as a contigEndPair

   aUserDefinedContigEndPairs.clearAndDestroy();
   pAssembly->getUserDefinedContigEndPairs( 
                                       aUserDefinedContigEndPairs );

   // here is the contigEndPair we are looking for
   contigEndPair cep( pContig[0],
                      pContig[1],
                      nContigEnd[0],
                      nContigEnd[1] );

   cep.recordTags( pTags[0], pTags[1] );
   cep.bUserDefined_ = true;

   // look for it

   bool bFound = false;
   for( nContigEndPair = 0; 
        nContigEndPair < aUserDefinedContigEndPairs.length();
        ++nContigEndPair ) {
      if ( cep == *aUserDefinedContigEndPairs[ nContigEndPair ] ) {
         bFound = true;
         break;
      }
   }
   
   if ( !bFound ) {
      // what shall we do?  Cry?  Warn the user, at least.

      RWCString soError = "Sorry--for some reason, I can't find the contigEndPair you just made.  This may be a bug.";
      popupErrorMessage2( widPopupShell_, soError.data() );
      return;
   }

   RWCString soDescription = cep.soGetDescription();
   
   XmString xms = XmStringCreateLocalized( soDescription.data() );

   XmListAddItem( widContigEndPairList_, xms, 0 );

   XmStringFree( xms );

   aContigEndPairs_.insert( cep );

   restartAssemblyView();
}





void guiReorderContigs :: setExistingUserDefinedContigEndPairs() {

   RWTPtrOrderedVector<contigEndPair> aUserDefinedContigEndPairs;

   ConsEd::pGetAssembly()->getUserDefinedContigEndPairs( 
                               aUserDefinedContigEndPairs );

   // in case there is any item left and the list is going to 
   // length zero, in which case it will not be reset
   XmListDeleteAllItems( widContigEndPairList_ );

   if ( aUserDefinedContigEndPairs.length() == 0 )
      return;

   XmStringTable ppXtString = 
      (XmStringTable) XtMalloc( aUserDefinedContigEndPairs.length() *
                                sizeof( XmString ) );

   aContigEndPairs_.clear();
   aContigEndPairs_.resize( aUserDefinedContigEndPairs.length() );


   int nContigEndPair;
   for( nContigEndPair = 0; 
        nContigEndPair < aUserDefinedContigEndPairs.length();
        ++nContigEndPair ) {

      contigEndPair* pContigEndPair = 
         aUserDefinedContigEndPairs[ nContigEndPair ];
      
      RWCString soDescription = pContigEndPair->soGetDescription();

      
      ppXtString[ nContigEndPair ] = 
         XmStringCreateLocalized( soDescription.data() );

      aContigEndPairs_.insert( *pContigEndPair );
   }

   XtVaSetValues( widContigEndPairList_,
                  XmNitems, ppXtString, 
                  XmNitemCount, aUserDefinedContigEndPairs.length(),
                  NULL );

   // free all the memory used for the array of XmString

   for( nContigEndPair = 0; 
        nContigEndPair < aUserDefinedContigEndPairs.length();
        ++nContigEndPair ) {

      XmStringFree( ppXtString[ nContigEndPair ] );
   }


   XtFree( (char*) ppXtString );

   aUserDefinedContigEndPairs.clearAndDestroy();
}


void guiReorderContigs :: userPushedDelete() {

   int* pPositionList;
   int nNumberOfSelectedItems = 0;
   if ( !XmListGetSelectedPos( widContigEndPairList_,
                               &pPositionList,
                               &nNumberOfSelectedItems ) ||
        nNumberOfSelectedItems == 0 ) {

      popupErrorMessage2( widPopupShell_, "First select the contig end pair and then click \"Delete Selected\"" );
      return;
   }

   assert( nNumberOfSelectedItems == 1 );
   int nZeroBasedIndex = pPositionList[0] - 1;

   contigEndPair& cep = aContigEndPairs_[ nZeroBasedIndex ];

   for( int nTag = 0; nTag <= 1; ++nTag ) {
      tag* pTag = cep.pTag_[ nTag ];

      EditAction* pEditAction = new editDeleteConsensusTag( pTag );
      ConsEd::pGetConsEd()->doEditAction( pEditAction,
                                          true ); // write to edit history file

   }


   restartAssemblyView();
}


void guiReorderContigs :: raiseWindow() {

   XtMapWidget( widPopupShell_ );
   
   XRaiseWindow(
                XtDisplay( widPopupShell_ ),
                XtWindow( widPopupShell_ )
                );

}