/*****************************************************************************
#   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    "ntide.h"
#include    "consedParameters.h"


unsigned char Ntide::ucGetBaseUpperOrLowerSetQualityThreshold_ = 200; // something impossible
char Ntide::cGetBaseUpperOrLowerLookup_[ 256 ][ 100 ];


char    Ntide :: cGetBaseUpperOrLower() const {

   setGetBaseUpperOrLowerLookupTableIfNecessary();

   return( cGetBaseUpperOrLowerLookup_[ cBase_ ][ ucQual_ ] );
}


char    Ntide :: cGetBaseUpperOrLowerUnsafe() const {

   return( cGetBaseUpperOrLowerLookup_[ cBase_ ][ ucQual_ ] );
}


// This had to be moved here from ntide.h to fix a bug in the sgi
// compiler.  If it were in ntide.h, then there were cases (such as
// calling up traces) in which the operator= would be called but the
// if (&nt != this) branch would not be taken and thus the guts of the
// ntide would not be copied.  In particular, this would happen when
// reshape is called by insertAt.  Thus there would be a whole bunch
// of ntides that have 0 for point position and have null for the
// base.  The user would notice this as follows: if inserting a column
// of pads, the aligned reads screen would become uniformly grey.  If
// changing to n's to the right end and then undo'ing, the traces
// window would become grey.  This only occurred in the sgi version.
// See more explanation in ntide.h

Ntide& Ntide :: operator= (const Ntide& nt) {
   if (&nt != this) {
      cBase_ = nt.cBase_;
      ucQual_ = nt.ucQual_;
   }
   return *this;
}




void Ntide :: setGetBaseUpperOrLowerLookupTableIfNecessary() {


   if ( ucGetBaseUpperOrLowerSetQualityThreshold_ ==
        pCP->nQualityThresholdForLowConsensusQuality_ ) return;


   ucGetBaseUpperOrLowerSetQualityThreshold_ = 
      pCP->nQualityThresholdForLowConsensusQuality_;
   
   int nQuality;
   for( nQuality = 0; 
        nQuality <= pCP->nQualityThresholdForLowConsensusQuality_;
        ++nQuality ) {

      for( int nChar = 0; nChar < nGetBaseUpperOrLowerLookupFirstSubscript; 
           ++nChar ) {

         unsigned char ucChar = nChar;

         // users want to see x's always lowercase, regardless of quality,
         // according to Pat Feb 2000
         if ( ucChar == 'x' || ucChar == 'X' ) {
            cGetBaseUpperOrLowerLookup_[ ucChar][ nQuality ] = 'x';
         }
         else if ( isalpha( ucChar ) ) {
            cGetBaseUpperOrLowerLookup_[ ucChar ][ nQuality ] = tolower( ucChar );
         }
         else
            cGetBaseUpperOrLowerLookup_[ ucChar ][ nQuality ] = ucChar;

      }
      

   }


   // This cannot be changed.  The Genome Centers are used to this being
   // ">"--not ">=".  That is, the threshold for low consensus quality
   // is itself a low consensus quality value.  DG 3/26/98


   for( nQuality = pCP->nQualityThresholdForLowConsensusQuality_ + 1;
        nQuality < nGetBaseUpperOrLowerLookupSecondSubscript; ++nQuality ) {


      for( int nChar = 0; nChar < nGetBaseUpperOrLowerLookupFirstSubscript; ++nChar ) {

         unsigned char ucChar = nChar;


         // users want to see x's always lowercase, regardless of quality,
         // according to Pat Feb 2000

         if ( ucChar == 'x' || ucChar == 'X' ) {
            cGetBaseUpperOrLowerLookup_[ ucChar ][ nQuality ] = 'x';
         }
         else if ( isalpha( ucChar ) ) {

            cGetBaseUpperOrLowerLookup_[ ucChar ][ nQuality ] = toupper( ucChar );
         }
         else
            cGetBaseUpperOrLowerLookup_[ ucChar ][ nQuality ] = ucChar;

      }
   }


   
   nQuality = ucQualityLowEdited;
   {
      for( int nChar = 0; nChar < nGetBaseUpperOrLowerLookupFirstSubscript; ++nChar ) {

         unsigned char ucChar = nChar;


         // users want to see x's always lowercase, regardless of quality,
         // according to Pat Feb 2000

         if ( ucChar == 'x' || ucChar == 'X' ) {
            cGetBaseUpperOrLowerLookup_[ ucChar ][ nQuality ] = 'x';
         }
         else if ( isalpha( ucChar ) ) {

            cGetBaseUpperOrLowerLookup_[ ucChar ][ nQuality ] = tolower( ucChar );
         }
         else
            cGetBaseUpperOrLowerLookup_[ ucChar ][ nQuality ] = ucChar;

      }
   }

   nQuality = ucQualityHighEdited;
   {
      for( int nChar = 0; nChar < nGetBaseUpperOrLowerLookupFirstSubscript; ++nChar ) {

         unsigned char ucChar = nChar;

         // users want to see x's always lowercase, regardless of quality,
         // according to Pat Feb 2000

         if ( ucChar == 'x' || ucChar == 'X' ) {
            cGetBaseUpperOrLowerLookup_[ ucChar ][ nQuality ] = 'x';
         }
         else if ( isalpha( ucChar ) ) {

            cGetBaseUpperOrLowerLookup_[ ucChar ][ nQuality ] = toupper( ucChar );
         }
         else
            cGetBaseUpperOrLowerLookup_[ ucChar ][ nQuality ] = ucChar;

      }
   }
}