#ifndef FITCONTEXT_H_
#define FITCONTEXT_H_
//_____________________________________________________________________________
///
/// \class FitContext
///
/// FitContext is the Context part of the State design pattern - 
/// it keeps all the info about current status of the fit.
///
/// \author Sergei avva@fnal.gov
///

#include "TVectorD.h"

#include "CandFitTrackSA/ConvergenceMaster.h"
#include "CandFitTrackSA/DataFT.h"
#include "CandFitTrackSA/FitResult.h"
#include "CandFitTrackSA/MatrixCalculator.h"

class AlgConfig;
class FitState;
class NtpFitSA;
class TrackEstimator;

class FitContext {

public:
    FitContext( const AlgConfig& algcfg,    const TrackContext& context, 
                TrackEstimator* estimator,  SwimSwimmer* swimmer         );
    ~FitContext();
    
    ///
    /// This is the basic iteration - it calls fState->Iterate
    ///
    void        Iterate();
    
    ///
    ///
    ///
    void        Print();
    void        PrintCurrentFit();
    
    ///
    /// get configurable parameters from AlgConfig 
    ///
    void        Config(const AlgConfig& ac);
    
    FitState*   GetState() const;
    void        SetState(const FitState* state);

    void        SetFitParams(const TVectorD& fit);
    void        SetLastGoodFitParams(const TVectorD& fit); 
    
    void        SetFromLastGoodFit(); 
    
    Float_t     GetPrange() { return fTrackContext.GetPrange(); };
    
    NtpFitSA    MakeNtpFitSA() const;        
    
    void        FillNtpFitSA(NtpFitSA& ntp) const;   
    void        FillNtpPlaneInfo(NtpFitSA& ntp) const;
    void        FillNtpBFieldCalib(NtpFitSA& ntp) const;
    void        FillNtpFitSR(NtpFitSA& ntp) const;

    const DataFT*   GetData() const { return &fData; };
    
    Double_t    GetCpu() const { return fCpu; };
    void        SetCpu(Double_t cpu) { fCpu = cpu; };
    
//private:

    ///
    /// track context
    ///
    const TrackContext&   fTrackContext;
    
    ///
    /// fitter state
    ///
    const FitState*       fState;
    
    ///
    /// Particle swimmer
    ///
    SwimSwimmer*          fSwimmer;
    
    ///
    /// Initial estimation of the track parameters 
    ///
    TrackEstimator*       fEstimator;
    
    ///
    /// data holder/manipulator 
    ///
    DataFT          fData;
    
    ///
    /// ConvergenceMaster
    ///
    ConvergenceMaster fConvergenceMaster;
    
    ///
    /// MatrixCalculator
    ///
    MatrixCalculator fMatCalc;
    
    Int_t           fNIterationsStep;
    Int_t           fNIterationsTotal;
    
    //Int_t          fNPlanesToFit;
    Int_t           fNPlanesFit;
         
    TVectorD        fCurrentFit;

    Int_t           fTimesConverged;
        
    FitResult       fLastGoodFit;

    Double_t        fDChi2;
    
    Int_t           fNTriesDiverges;
    
    Int_t           fNHitsInViewMin;
    
    Int_t           fNMaxIterations;
    
    Int_t           fNMaxDiverging;
    
    Double_t        fConvergenceCond;
    
    Double_t        fCpu;
};

#endif // FITCONTEXT_H_
