// $Id: parsetreetodata.h,v 1.20 2018/01/03 21:33:06 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 PARSETREETODATA_H
#define PARSETREETODATA_H

#include <string>
#include "individual.h"     // for Individual
#include "tinyxml.h"
#include "locus.h"          // for TipData
#include "parsetreewalker.h"

/******************************************************************
 Walks the TinyXML parse tree generated by XmlParser (xml.h)
 and creates the DataPack.

 Based on a class by Jim Sloan, rewritten by Mary Kuhner, and
 then by Elizabeth Walkup
*********************************************************************/

class DataPack;
class Random;
class Region;
class UserTree;

class ParseTreeToData   : public ParseTreeWalker
{
  private:
    DataPack&               datapack;
    Region*                 m_pCurrRegion;
    long                    m_currpopulation;
    long                    m_currindno;
    Individual              m_currIndividual;
    TipData                 m_tipdata;
    std::auto_ptr<Random>   m_randomNameSource;
    force_type              m_migrationalForce;

    // purposely not implemented, this class is meant to be a singleton
    ParseTreeToData();
    ParseTreeToData(const ParseTreeToData&);
    ParseTreeToData& operator=(const ParseTreeToData&);

  protected:

    // for creating less-likely-to-crash names
    std::string XmlRandomLongAsString();

    // main line data reading routines
    void        DoFormat(TiXmlElement*);
    void        DoData(TiXmlElement*);
    void        DoRegion(TiXmlElement*, long regionId);
    void        DoPopulations(TiXmlElement*);
    void        DoPopulation(TiXmlElement*);
    void        DoPanel(TiXmlElement*, string popname);
    void        DoIndividual(TiXmlElement*);
    void        DoSamples(TiXmlElement *);
    void        DoStatus(TiXmlElement *);
    void        DoDisease(TiXmlElement *);
    void        DoDataBlocks(TiXmlElement *);
    void        DoGenotypeResolutions(TiXmlElement *);

    // auxillary map location information
    void        DoSpacing(TiXmlElement* );
    void        DoBlocks(TiXmlElement* );
    void        DoMapPosition(TiXmlElement* , long locus);
    void        DoLength(TiXmlElement* , long locus);
    void        DoLocations(TiXmlElement* , long locus);
    void        DoOffset(TiXmlElement* , long locus);

    // auxiliary data reading routines
    void        DoPhases(TiXmlElement* );  // DoSamples *must* be called first!
    void        DoEffectivePopSize(TiXmlElement* );

    // main line tree reading routines--currently called in DoRegions()
    UserTree*   DoTree(TiXmlElement* xmlllist);

    // diagnosis of migration versus divergence
    void        DiagnoseTagForMigrationalForce(TiXmlElement* rootElement);
    force_type  TagForMigrationalForce() const;

  public:
    ParseTreeToData(XmlParser&,DataPack&);
    virtual ~ParseTreeToData();
    void     ProcessFileData();  // processes datapack part of structures

    bool     CheckARGtree(vector<UIId> ids, bool batchmode); // checks input ARG trees are valid
    bool     DoARGtree();                                    // links up ARG trees to regions

};

LongVec1d::iterator FindValIn(long, LongVec1d&);

#endif // PARSETREETODATA_H

//____________________________________________________________________________________
