// $Id: partition.h,v 1.11 2018/01/03 21:33:04 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 PARTITION_H
#define PARTITION_H

#include <map>
#include <vector>
#include <string>
#include "vectorx.h"
#include "defaults.h"                   // for force_type definition

class TimeSize;

class XPartition
{
  private:
    LongVec1d m_membership;             // branch membership match
    vector<XPartition*> m_partners;     // related xpartitions
    bool m_hasparam;

    // way to find jointed stick? can't be pointer due to tree copying
    // way to find appropiate theta and g (if any)
  public:
    XPartition() {};
    ~XPartition();

    bool HasParam() const { return m_hasparam; };

    void SetHasParam(bool val) { m_hasparam = val; };

};

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

class Partition
{

  private:
    vector<XPartition*> m_xparts;       // non-owning
    string m_forcename;                 // what force are we part of?

  public:
    Partition(const string& fname) : m_forcename(fname) {};
    ~Partition() {};

};

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

typedef std::map<force_type,StringVec1d> PartitionNames;

class PartitionSummary
{
  private:
    vector<Partition> m_partitions;
    vector<XPartition> m_xpartitions;

    PartitionNames m_partnames;
    StringVec1d m_outputpopnames; // in the single population case
    // save the MIG partition names here
    LongVec1d m_finalcount; // this is set by SetFinalPartitionCounts()

  public:
    // we accept the default ctor, copy-ctor and dtor

    long AddPartition(const string& forcename, const string& partname);

    long GetNPartitions(const string& forcename) const;
    string GetPartitionName(const string& forcename, long index) const;
    long GetPartitionNumber(const string& forcename, const string& name) const;
    StringVec1d GetAllPartitionNames(force_type) const;
    StringVec1d GetAllCrossPartitionNames() const;

    // this function is provided to interface with tipdata objects
    // it's also used by GetAllCrossPartitionNames which needs to pass
    // false as an argument (it cares about partition forces with only
    // one partition.
    std::vector<std::map<string,string> >
    GetCrossPartitionIds(bool ignoresinglepop = true) const;

    // This function will return 0 if the membership vector is empty.
    // It does this to interface with the BranchBuffer and Branch::ScoreEvent.
    long GetCrossPartitionIndex(const LongVec1d& membership) const;
    LongVec1d GetBranchMembership(long xpartindex) const;
    std::map<string,string> GetTipId(long xpartindex) const;

    long GetNPartitionForces() const;
    long GetNCrossPartitions() const;
    long GetNPartitions(unsigned long index) const;
    LongVec1d GetAllNPartitions() const;

    // called by ForceSummary::SummarizeData
    void SetFinalPartitionCounts(LongVec1d pcounts);
};

#endif // PARTITION_H

//____________________________________________________________________________________
