// $Id: setgetmachine.h,v 1.31 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: Mary Kuhner, Jon Yamato, and Joseph Felsenstein */


#ifndef SETGETMACHINE_H
#define SETGETMACHINE_H

#include <string>
#include <map>

#include "constants.h"
#include "datatype.h"
#include "setget.h"
#include "vectorx.h"

class UIVars;

using std::string;

class SetGetMachine
{
  private:
    // a map from strings in uistr class to SetGet objects that
    // can set and get those variables
    std::map<string,SetGet*> setters;

  protected:
    // encapsulates process of adding a SetGet* object to the
    // map above
    virtual void addSetter(SetGet *);
    void Init();// set up data-dependent structures

  public:
    SetGetMachine();
    virtual ~SetGetMachine();

    // get the value of "variable", indexed by "id" where appropriate
    bool        doGetBool           (string variable,UIVars& vars, UIId id);
    data_type   doGetDataType       (string variable,UIVars& vars, UIId id);
    double      doGetDouble         (string variable,UIVars& vars, UIId id);
    DoubleVec1d doGetDoubleVec1d    (string variable,UIVars& vars, UIId id);
    force_type  doGetForceType      (string variable,UIVars& vars, UIId id);
    ForceTypeVec1d doGetForceTypeVec1d (string variable,UIVars& vars, UIId id);
    long        doGetLong           (string variable,UIVars& vars, UIId id);
    LongVec1d   doGetLongVec1d      (string variable,UIVars& vars, UIId id);
    method_type doGetMethodType     (string variable,UIVars& vars, UIId id);
    model_type  doGetModelType      (string variable,UIVars& vars, UIId id);
    proftype    doGetProftype       (string variable,UIVars& vars, UIId id);
    string      doGetString         (string variable,UIVars& vars, UIId id);
    StringVec1d doGetStringVec1d    (string variable,UIVars& vars, UIId id);
    verbosity_type doGetVerbosityType  (string variable,UIVars& vars, UIId id);
    UIIdVec1d   doGetUIIdVec1d      (string variable,UIVars& vars, UIId id);
    UIIdVec2d   doGetUIIdVec2d      (string variable,UIVars& vars, UIId id);

    // set the id'th instance of variable to value "val"
    void                doSet               (string variable,UIVars& vars, UIId id, string val);

    // advance the id'th instance of variable to the next value
    void        doToggle            (string variable,UIVars& vars, UIId id);

    // get a string for printing
    // the value of "variable", indexed by "id" where appropriate
    string      doGetPrintString    (string variable,UIVars& vars, UIId id);

    // get a string describing what a variable is
    string      doGetDescription    (string variable,UIVars& vars, UIId id);

    // is the associated value consistent with the model
    bool        doGetConsistency    (string variable,UIVars& vars, UIId id);

    //get a string for the min/max enterable values.
    string      doGetMin       (std::string variable, UIVars& vars, UIId id);
    string      doGetMax       (std::string variable, UIVars& vars, UIId id);

};

template<class T> T doGet(
    string variable,
    UIVars& vars,
    UIId id,
    std::map<string,SetGet*> & setters)
{
    SetGet * getter = setters[variable];
    GetTemplate<T> * tGetter =
        dynamic_cast<GetTemplate<T>*>(getter);
    if(tGetter == NULL)
    {
        string err = "SetGetMachine found no match for variable\n\""
            + variable + "\"\n"
            + "\tDid you remember to add a setter object in SetGetMachine::Init()?\n";
        implementation_error e(err);
        throw e;
    }
    return tGetter->Get(vars,id);
};

#endif // SETGETMACHINE_H

//____________________________________________________________________________________
