#ifndef __SCONTI_H
#include "sconti.h"
#endif

#ifndef __VEUML_H
#include "veuml.h"
#endif             

#ifndef __VEUML2_H
#include "veuml2.h"
#endif             

#ifndef __TCLIFOR_H
#include "tclifor.h"
#endif

#ifndef __CONFIG_H
#include "config.h"
#endif

#ifndef __VECONF_H
#include "veconf.h"
#endif

#define A_ANAMAG         0

const real TSconto::cento( "100" );

void TSconto::set( const TString& exp, bool signal  )
{
  TString work( exp );
  TString goodexp;
  TString num;
  
  // Elimina gli spazi molesti
  work.strip_spaces( );
  // Per ora nessun errore
  _errorpos = -1;
  
  int i = 0;
  _part = 1.0;
  const int wlen = work.len( );
  // Flag che indica se sono nella parte decimale di un numero
  bool dec = FALSE;
  // Flag che indica se si attende l'inizio di un numero
  bool startnum = TRUE;
  // Flag che indica se siamo all'inizio di un numero   
  while ( i < wlen && _errorpos < 0 )
  { 
    char c = work[ i++ ];     
    switch( c )
    {
    case '+': 
    case '-':
      // Se ero in in numero ...
      if( !startnum )
      {
        // Aggiunge il numero alla sequenza
        real newval( num );
        _part = _part * ( cento + newval ) / cento;
        if( newval >= 0 )
          goodexp << '+';
        goodexp << num;
      }
      // Inizia il nuovo numero
      num = ( c == '-' )?"-":"";  
      startnum = TRUE;
      dec = FALSE;
      break;         
    case '0':  
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      num << c;
      startnum = FALSE;
      break;
    case '.':
    case ',':
      // Se siamo già nella parte decimale ...
      if( dec )
      {
        // Segnala un errore
        _errorpos = i;
        break;
      }
      // Se occorreva un numero ci metto lo 0
      if( startnum )
        num << '0';
      // Interpreto la virgola come punto
      num << '.';
      dec = TRUE;       
      startnum = TRUE;
      break;
    default:
      _errorpos = i;
      break;         
    }
  }
  // Controlla la validità
  _valid = ( _errorpos < 0 );
  // Se richiesto segnala l'errore
  if( !_valid && signal )
    warning_box( "Espressione di sconto non valida. Errore sul carattere %d.", _errorpos + 1 );
  if( _valid )
  {
    // Aggiunge l'ultimo numero preso
    real lastval( num ); 
    _part = _part * ( cento + lastval ) / cento;
    if( lastval >= 0 )
      goodexp << '+';
    goodexp << num;
    // Assegna la nuova espressione formattata bene     
    _exp = goodexp;
  }
  else
  {
    // Azzera la sequenza di percentuali
    _part = 1.0;
  }
}

real TSconto::sconto( )
{ 
  CHECK(is_valid( ),"Tentativo di usare uno sconto non valido!" );
  return ( ( _part * cento ) - cento );
}


TSconto_riga::TSconto_riga( TCliFor& clifo, TMask * testa, TMask * riga ) : _condv( LF_CONDV ), _rcondv( LF_RCONDV ), _anamag( LF_ANAGR ), _sconti( LF_SCONTI ), _ditta( CONFIG_DITTA )
{
   _clifo = &clifo;
   _testa = testa;
   _riga = riga;
}
    
bool TSconto_riga::cerca_condv( int tiporicerca )
{
  TString s1 = _anamag.get( "CODART" );
  TString s2 = riga( ).get( FS_CODART );  
  if( s1 != s2 )
  {
    _anamag.setkey( 1 );
    _anamag.zero( );
    _anamag.put( "CODART", riga( ).get( FS_CODART ) );
    int ret = _anamag.read( );
    CHECK( ret == NOERR, "Articolo non trovato in anagrafica di magazzino!" );        
  }
  if( tiporicerca == A_ANAMAG )
    // Se ricercavo per anagrafica, ho già finito
    return TRUE;  
  if( _ditta.get_bool( "GES", "ve", tiporicerca ) )
  {
    // Se è attiva la gestione contratti ...
    _condv.setkey( 1 );
    _condv.zero( );
    switch( tiporicerca )
    {
      case A_CONTRATTI:
        _condv.put( "TIPO", "C" );
        _condv.blank( "CATVEN" );
        if( _ditta.get_bool( "GESSCONCC", "ve" ) )
        {
          // Se in ditta è abilitata la gestione del cliente in chiave 
          // al contratto, lo carico con gioia      
          _condv.put( "TIPOCF", clifo( ).tipocf( ) );
          _condv.put( "CODCF", clifo( ).codcf( ) );     
        }
        else
        {
          _condv.blank( "TIPOCF" );
          _condv.blank( "CODCF" );     
        }
        _condv.put( "COD", testa( ).get( F_CODCONT ) );
        break;
      case A_LISTINI:  
        _condv.put( "TIPO", "L" );
        if( _ditta.get_bool( "GESLISCV", "ve" ) )
        {
          // Se in ditta è abilitata la gestione del cliente in chiave 
          // al contratto, lo carico con gioia      
          _condv.put( "TIPOCF", clifo( ).tipocf( ) );
          _condv.put( "CODCF", clifo( ).codcf( ) );     
        }
        else
        {
          _condv.blank( "TIPOCF" );
          _condv.blank( "CODCF" );     
        }
        _condv.blank( "CATVEN" );
        _condv.put( "COD", testa( ).get( F_CODLIST ) );
        break;
      case A_OFFERTE:
        _condv.put( "TIPO", "O" );
        _condv.blank( "CATVEN" );
        _condv.blank( "TIPOCF" );
        _condv.blank( "CODCF" );     
        _condv.put( "COD", testa( ).get( F_CODCAMP ) );
        break;
    }
    if( _condv.read( ) == NOERR )
    { 
      _rcondv.setkey( 2 );
      _rcondv.zero( );
      _rcondv.put( "TIPO", _condv.get( "TIPO" ) );
      _rcondv.put( "CATVEN", _condv.get( "CATVEN" ) );
      _rcondv.put( "TIPOCF", _condv.get( "TIPOCF" ) );
      _rcondv.put( "CODCF", _condv.get( "CODCF" ) );
      if( _condv.get_bool( "GESTUM" ) )
      {
        _rcondv.put( "UM", riga( ).get( FS_UMQTA ) );
      }
      else
      {
        _rcondv.blank( "UM" );
      }
      if( _condv.get_bool( "GESTSCA" ) )
      {
        _rcondv.put( "QLIM", riga( ).get( FS_QTA ) );
      }
      else
      {
        _rcondv.blank( "QLIM" );
      }
      const TString16 seqricrighe( _condv.get( "SEQRIC" ) );
      for( int i = 0; i < seqricrighe.len( ); i ++ )
      {
        
        char ricerca = seqricrighe[ i ];
        _rcondv.put( "TIPORIGA", ricerca );
        switch( ricerca )
        {
          case 'A':
            _rcondv.put( "CODRIGA", _anamag.get( "CODART" ) );
            if( _rcondv.read( ) == NOERR ) return TRUE;
            break;
          case 'R':
            _rcondv.put( "CODRIGA", _anamag.get( "RAGGFIS" ) );
            if( _rcondv.read( ) == NOERR ) return TRUE;
            break;
          case 'G':
            _rcondv.put( "CODRIGA", _anamag.get( "GRMERC1" ) );
            if( _rcondv.read( ) == NOERR ) return TRUE;
            _rcondv.put( "CODRIGA", _anamag.get( "GRMERC2" ) );
            if( _rcondv.read( ) == NOERR ) return TRUE;
            _rcondv.put( "CODRIGA", _anamag.get( "GRMERC3" ) );
            if( _rcondv.read( ) == NOERR ) return TRUE;              
            break;
          default:
             CHECK( FALSE, "Tipo di ricerca righe non valido!" );
        }        
      }
      // Ricerca fallita
      return FALSE;      
    }
    else
      // Ricerca fallita
      return FALSE;
  }
  else
    // La ricerca non è gestita, impossibile trovarlo ...
    return FALSE;
}
    
// Probabilmente dovrebbe lavorare sulla maschera, ma per ora la lasciamo così
void TSconto_riga::calcola( )
{
  char gestione = _ditta.get_char( "GESSCORIGA", "ve" );
  bool trovato = TRUE;
  switch( gestione )
  {
    case 'N':
      // Sconti di riga non gestiti
      set( "" );
      break;
    case 'L':
      // Percentuale su contratti/offerte/listini/anagrafica
      trovato = cerca_condv( A_CONTRATTI );
      if( !trovato ) trovato = cerca_condv( A_OFFERTE );
      if( !trovato ) trovato = cerca_condv( A_LISTINI );
      if( !trovato )
        set( _rcondv.get( "SCONTO" ) );
      else
      {         
        if( cerca_condv( A_ANAMAG ) )
          set( _anamag.get( "SCONTO" ) );
        else
          CHECK( FALSE, "Sconto non trovato!( 1 )" );
      }
      break;
    case 'A':
      // Posiziono l'anagrafica
      cerca_condv( A_ANAMAG );
      _sconti.setkey( 1 );
      _sconti.put( "TIPO", "R" );
      _sconti.put( "CODART", _anamag.get( "CODART" ) );
      if( _ditta.get_bool( "GESSCORIGACV", "ve" ) )
      {
        _sconti.put( "CODCAT", clifo( ).get( LF_CFVEN, "SCONTO" ) );
      }
      if( _ditta.get_bool( "GESSCORIGAUM", "ve" ) )
      {
        _sconti.put( "UM", riga( ).get( FS_UMQTA ) );
      }
      if( _sconti.read( ) == NOERR )
        // Bravo, hai vinto una bambolina
        set( _sconti.get( "SCONTO" ) );
      else
        CHECK( FALSE, "Sconto non trovato!( 2 )" );
      break; 
    case 'C':
      set( clifo( ).get( LF_CFVEN, "SCONTO" ) );        
  }
}
