// $Id: arrangervec.h,v 1.29 2018/01/03 21:33:03 mkkuhner Exp $

/*
Copyright 2002-2005 Mary K. Kuhner, Peter Beerli, and Joseph Felsenstein

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

/* Authors: Peter Beerli, Mary Kuhner, Jon Yamato and Joseph Felsenstein */


#ifndef ARRANGERVEC_H
#define ARRANGERVEC_H

#include <map>
#include <string>
#include <vector>

#include "arranger_types.h"
#include "vectorx.h"

//------------------------------------------------------------------------------------

// This class is a managed map of Arranger objects (objects which
// can carry out a single Markov Chain step).  Mapping is between
// the Arranger's type and the object itself.

// Written by Mary, Jon, and/or Elizabeth, probably around 11/22/2002

// Added ability to manage ForceParameters, needed by BayesArranger.
// Mary 2003/12/01

// NOTE:  If you run Bayesian Stationaries, the code here will silently
// transform all mention of the DropArranger to the DenovoArranger.
// As of May 17, 2010, it will do so for ALL stationaries or for just the
// Bayesian case, compile-time-selectable by defining ALL_ARRANGERS_DENOVO.

//------------------------------------------------------------------------------------

class Arranger;

typedef std::map<std::string, Arranger*> arrangermap;
typedef arrangermap::iterator arrangerit;
typedef arrangermap::const_iterator const_arrangerit;

class ArrangerVec
{
  private:
    ArrangerVec();          // undefined

    arrangermap arrangers;
    void                    CopyAllMembers(const ArrangerVec& cp);
    void                    Normalize();

  public:
    ArrangerVec(double dropTiming, double sizeTiming,
                double hapTiming, double probhapTiming,
                double bayesTiming,
                double locusTiming, double zilchTiming,
                double stairTiming, double epochsizeTiming,
                double epochnudgeTiming);
    ~ArrangerVec();
    ArrangerVec(const ArrangerVec& src);
    ArrangerVec& operator=(const ArrangerVec& src);

    double                 GetArrangerTiming(const std::string & atype) const;
    Arranger*              GetDenovoArranger() const;
    Arranger*              GetRandomArranger(double) const;
    StringVec1d            GetAllStringsForActiveArrangers() const;

    void                   ClearAll();

    void                   ZeroHapArranger();
    void                   ZeroProbHapArranger();
    void                   ZeroLocusArranger();
    void                   RestoreTiming();

    arrangerit             begin() { return arrangers.begin(); };
    arrangerit             end() { return arrangers.end(); };
    const_arrangerit       begin() const { return arrangers.begin(); };
    const_arrangerit       end() const { return arrangers.end(); };
    unsigned long          size() const;
    bool                   empty() const;

    void      PrintArrangers() const;
};

#endif  // ARRANGERVEC_H

//____________________________________________________________________________________
