// $Id: ui_vars_datapackplus.h,v 1.24 2018/01/03 21:33:05 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 UI_VARS_DATAPACK_PLUS_H
#define UI_VARS_DATAPACK_PLUS_H

#include "datatype.h"
#include "ui_vars_component.h"
#include "vectorx.h"
#include "rangex.h"

class DataPack;

class UIVarsDataPackPlus : public UIVarsComponent
{
  private:
    // EWFIX.P5 REFACTOR: To make undo/redo work properly, the effective pop sizes
    // had to be moved into member variable m_effectivePopSizes, then synched
    // later (in Registry::InstallEffectivePopSizes(), by using call to
    // GetEffectivePopSizes()).  This is not ideal, but there's no great
    // solution.
    //
    // LS Response:  This (and many other things) would be fixed if we had a
    // phase-1 datapack and a phase-2 datapack.

    //LS NOTE:  non-const because of RevertAllMovingLoci() and nothing else:
    DataPack&            datapack;
    DoubleVec1d          m_effectivePopSizes;
    vector<deque<bool> > m_simulateData;

    UIVarsDataPackPlus();                           // undefined
    UIVarsDataPackPlus(const UIVarsDataPackPlus&);  // undefined
  public:
    // one might argue that the constructors should have
    // restricted access since only UIVars should
    // be creating these puppies.
    UIVarsDataPackPlus(UIVars * myUIVars,DataPack& dp);
    UIVarsDataPackPlus(UIVars * myUIVars,const UIVarsDataPackPlus&);
    virtual ~UIVarsDataPackPlus();

    // data size info
    long            GetMaxLoci() const;
    long            GetNumRegions() const;
    long            GetNumLoci(long region) const;
    long            GetNCrossPartitions() const;
    long            GetNPartitionsByForceType(force_type ft) const;
    double          GetEffectivePopSize(long region) const;
    bool            GetSimulateData(long region, long locus) const;
    DoubleVec1d     GetEffectivePopSizes() const { return m_effectivePopSizes;};
    long            GetNumIndividualsWithMultipleHaplotypes(long region, string lname) const;


    // LS DEBUG:  This should move into the converter eventually.  Probably.
    void            SetEffectivePopSize(long region, double size);
    void            SetSimulateData(long region, long locus, bool sim);

    // Revert the datapack to phase 1 again
    void            RevertAllMovingLoci();

    // data type info
    bool            CanHapArrange() const;
    bool            HasSomeNucleotideData() const;
    bool            HasSomeMsatData() const;
    bool            HasSomeKAlleleData() const;

    // names
    string          GetCrossPartitionName(long index) const;
    StringVec1d     GetCrossPartitionNames() const;
    string          GetForcePartitionName(force_type ftype, long index) const;
    StringVec1d     GetForcePartitionNames(force_type ftype) const;
    string          GetLocusName(long regionIndex, long locusIndex) const;
    long            GetLocusIndex(long regionIndex, string locusName) const;
    bool            HasLocus(long regionIndex, string locusName) const;
    string          GetRegionName(long index) const;
    string          GetSimpleRegionName(long index) const;
    string          GetParamName(force_type ftype, long index, bool doLongName=true) const;

    // not actually dependent on data
    string          GetParamNameOfForce(force_type ftype) const;

    //
    data_type       GetDataType(long regionId, long locusId) const;
    bool            IsMovable(long regionId, long locusId) const;
    string          GetName(long regionId, long locusId) const;
    rangeset        GetRange(long regionId, long locusId) const;
    rangepair       GetRegionSiteSpan(long regionId) const;
    long            GetNumSites(long region) const;
    long            GetNumSites(long region, long locus) const;
    StringVec2d     GetUniqueAlleles(long region, long locus) const;
    std::set<long>  GetPloidies(long region) const;

    //For Phenotypes, which need them for Haplotypes.
    const Locus* GetConstLocusPointer(long region, long locus) const;

    //Divergence
    string GetAncestorName(long index1) const;
    string GetDescendentNames(long index1) const;

    bool            AnySimulation() const;
    bool            AnyRelativeHaplotypes() const;
    bool            AnySNPDataWithDefaultLocations() const;
};

#endif  // UI_VARS_DATAPACK_PLUS_H

//____________________________________________________________________________________
