/*****************************************************************************
#   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    "guiapp.h"
#include    "consed.h"
#include    "assembly.h"
#include    <iostream.h>
#include    "consedParameters.h"
#include    "choose_contig.h"
#include    "printAutoFinishMiscInfo.h"
#include    "universalPrimerAutoFinishExpTagsSortedByTemplateName.h"
#include    "openAutoFinishOutputFiles.h"
#include    "fileDefines.h"
#include    "listOfLibraries.h"
#include    "pickCombinationsOfPCRPrimers.h"
#include    "maybeTerminateIfAnotherReadWriteConsed.h"
#include    "printMemory.h"
#include    "autoFinishPCR.h"


void terminateIfNoPhdDir();

void autoFinish(const RWCString& soAceFileToOpen,
                int argc,
                char* argv[],
                const bool bContigSpecified,
                const RWCString& soContig,
                const RWCString& soID,
                const bool bDoExperiments,
                const bool bJustCheckAutoFinishReads,
                const FileName& soFilenamesFile ) {



   consedParameters::pGetConsedParameters()->bWillDoExperiments_ = 
      bDoExperiments;

   
   
   // create the GuiApp object which contains and manages
   // the toplevel widget, display and resource info, etc.
   // there is now a global pointer to this sole instance,
   // set in the ctor, accessible as GuiApp::pGetGuiApp()

   // remove this
   // GuiApp guiAppGlobalInstance("consed", argc, argv);

   consedParameters::pGetConsedParameters()->bOKToUseGui_ = false;

   // create the ConsEd object, which owns and manages the
   // Assembly data structure(s) as well as the lists of
   // currently existing ContigWin and Teditor objects.
   // there is now a global pointer to this sole instance,
   // set in the ctor, accessible as ConsEd::global()
   ConsEd* pConsed = new ConsEd();

   maybeTerminateIfAnotherReadWriteConsed();

   openAutoFinishOutputFiles( soAceFileToOpen, soFilenamesFile );

   // this uses the autofinish output files to report the error
   // so it must have openAutoFinishOutputFile before it
   terminateIfNoPhdDir();


   printAutoFinishMiscInfo( soAceFileToOpen, soID );

   pCP->processDoNotFinishTagTypes();
   pCP->processDoNotExtendTagTypes();

   // I want to read the list of libraries before reading the ace file
   // to make debugging by the user easier
   pCP->pListOfLibraries_ = new listOfLibraries();
   pCP->pListOfLibraries_->aLibraries_.soName_ = 
      "pCP->pListOfLibraries_->aLibraries_ in autoFinish.cpp";

   pCP->pListOfLibraries_->parseLibraryFile();


   // tried moving this to above to before openAutoFinishOutputFiles 
   // so that, if
   // the user specifies a bogus ace file, such as -ace -ace, 
   // we don't create several zero-length files that have filenames
   // that the shell can't handle.  However, if I do that, then any
   // error encountered by openAssemblyFile will try to write to
   // pAO and give a segmentation fault

   // this does "new Assembly"
   ConsEd::pGetConsEd()->openAssemblyFile( soAceFileToOpen );

   printMemory( "after opening ace file" );


   // set up arrays that will have the cumulative number of errors
   // that would be solved by a read of that type.  Types are
   // 1) dye primer top strand
   // 2) dye primer bottom strand
   // 3) dye terminator top strand
   // 4) dye terminator bottom strand
   // arrays should start 500 bases before the contig and end 500 after the contig

   Assembly* pAssembly = ConsEd::pGetAssembly();


   pAssembly->setContigMatchTablesInAllContigs();
   pAssembly->setAllPaddedPositionsArrays();

   pAssembly->setAutoFinishDebugUniversalPrimersFile();
   pAssembly->setAutoFinishDebugCustomPrimersFile();


   // this must be called before setContigTemplateArrays because it uses
   // the model read length (at present, Jan, 2000)
   pAssembly->createModelRead();


   // this is needed by the code that writes out the autoFinishExp tags
   // and by setContigTemplateArrays to check if fwd/rev pairs
   // from different contigs are consistent
   // now this is in setContigTemplateArrays
   //pAssembly->setAllContigHighQualitySegments();


   pAssembly->setContigTemplateArrays();


   pAssembly->pAllChosenExperiments_ = new mbtPtrOrderedVector<experiment>;

   pAssembly->pForwardUniversalPrimerAutoFinishExpTags_ =
      new universalPrimerAutoFinishExpTagsSortedByTemplateName( 
          pAssembly->nGetNumberOfForwardUniversalPrimerAutoFinishExpTags()
                                                                );
   
   pAssembly->pForwardUniversalPrimerAutoFinishExpTags_->fillThyself( true );


   pAssembly->pReverseUniversalPrimerAutoFinishExpTags_ =
      new universalPrimerAutoFinishExpTagsSortedByTemplateName(
          pAssembly->nGetNumberOfReverseUniversalPrimerAutoFinishExpTags()
                                                               );

   pAssembly->pReverseUniversalPrimerAutoFinishExpTags_->fillThyself( false );

   // these are needed by checkAutoFinishReads
   pAssembly->setAllUnpaddedErrorProbabilitiesAndMore();
   pAssembly->setAllFindSingleSubcloneBases();


   pAssembly->checkAutoFinishReads();

   if ( bJustCheckAutoFinishReads) return;

   printMemory( "about to start considering experiments" );

   if (!bContigSpecified ) {

      for ( int nContig = 0; nContig < pAssembly->nNumContigs(); 
            nContig++) {
         Contig*   pContig = pAssembly->pGetContig( nContig );


         if ( !pContig->bIAmARealContig() ) continue;

         cerr << "working on contig: " << pContig->soGetName() << "..." << 
            " (last contig is " << 
            pAssembly->pGetContig( pAssembly->nNumContigs() - 1 )->soGetName() 
              << " )" << endl;

         pContig->batchFindFinishingReads();
      } //  for ( nContig = 0; nContig < pAssembly->nNumContigs(); 

      if ( pCP->bAutoFinishCloseGaps_ && pCP->bAutoFinishAllowPCR_ ) {
         autoFinishPCR();
      }

      if ( consedParameters::pGetConsedParameters()->nAutoFinishNumberOfCloningSitesFound_ > 2 ) {
         fprintf( pAO, "Warning: there were %d cloning sites found",
                 consedParameters::pGetConsedParameters()->nAutoFinishNumberOfCloningSitesFound_ );
      }
   }  
   else {
      Contig* pContig = pAssembly->pGetContigByName( soContig );
      if (!pContig ) {
         cerr << "Could not find contig " << soContig << endl;
         exit( 1 );
      }

      pContig->batchFindFinishingReads();
      
   } //    if (!bContigSpecified ) {


   if ( pCP->bWillDoExperiments_ ) {
      // currently the adjustUnpaddedErrorProbabilitiesArray 
      // changes the pUnpaddedErrorProbabilities_ array

      pAssembly->setAllUnpaddedErrorProbabilitiesAndMore();

      // first save copy of ace file 
      pAssembly->saveACopyOfAceFileToBack();

      pAssembly->tagAceFileWithExperiments();

      if ( pCP->bAutoFinishTagOligosWhenDoExperiments_ )
         pAssembly->tagAceFileWithOligosForExperiments();

   }


   pAssembly->createExpSummaryFiles();


   // close autofinish output file
   fclose( pAO );



   cerr << "output in " << pCP->filAutoFinishFullOutput_ << endl;

}