//_____________________________________________________________________________
///
/// \class FitStateInitial
///
///
///
/// \author Sergei avva@fnal.gov
///

#include <string>

#include "MessageService/MsgService.h"

#include "CandFitTrackSA/ConstFT.h"
#include "CandFitTrackSA/FitContext.h"
#include "CandFitTrackSA/FitStateFactory.h"
#include "CandFitTrackSA/FitStateInitial.h"
#include "CandFitTrackSA/TrackEstimator.h"

CVSID("$Id: FitStateInitial.cxx,v 1.2 2006/02/04 21:47:35 avva Exp $");

using namespace ConstFT;

// The ID of class Line
static const std::string INITIAL_FIT_STATE = "Initial";

// Create an anonymous namespace
// to make the function invisible from other modules
namespace {

FitState* CreateInitialFS() { return new FitStateInitial; }

// register block
bool registered = FitStateFactory::Instance().RegisterFitState(
                                        INITIAL_FIT_STATE, CreateInitialFS);
}  // namespace


///
/// Name() - return name of the state 
///
const std::string& FitStateInitial::Name() const
{
    return INITIAL_FIT_STATE;
}    


void FitStateInitial::Iterate(FitContext& context) const
{
    // apply the maximum mask that still leaves 
    // enough hits ( > fNHitsInViewMin ) to fit in
    // both U and V
    context.fData.SetUHitUse( context.fConvergenceMaster.GetMaskUCur() );
    context.fData.SetVHitUse( context.fConvergenceMaster.GetMaskVCur() );

    // get an inital rough estimate of the track parameters
    context.fCurrentFit = context.fEstimator->EstimateTrackParams(context);

    //
    context.SetLastGoodFitParams(context.fCurrentFit);
    
    // set initial number of planes to fit
    // context.fNPlanesToFit = context.fConvergenceMaster.GetNPlanesCur();
    
    // set input track parameters     
    context.fNPlanesFit = context.fData.SetInitial(context.fCurrentFit, 
                context.fConvergenceMaster.GetNPlanesCur(), *context.fSwimmer);
                                    //context.fNPlanesToFit, *context.fSwimmer);
                                        
    // bad failure - stop iterations
    if ( context.fNPlanesFit < context.fConvergenceMaster.GetNPlanesMin() ){
        context.SetState(FitStateFactory::Instance().GetFitState("Final"));
        context.Print();
        MSG("FitTrackSA",Msg::kInfo) << "Switched from Initial to Final\n";
        return;        
    }
        
    // perform iteration
    context.fMatCalc.Solve(context.fData);
    context.fCurrentFit = context.fMatCalc.GetTrackOut();
    
    //context.SetLastGoodFitParams(context.fCurrentFit);
    //context.fLastGoodFit.SetNPlanes(context.fNPlanesFit);
    
    context.SetState(FitStateFactory::Instance().GetFitState("Iterating"));
    context.Print();
    MSG("FitTrackSA",Msg::kInfo) << "Switched from Initial to Iterating\n";
    return;

}

