// $Id: prior_interface.cpp,v 1.14 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 */


#include <cassert>

#include "local_build.h"                // for definition of LAMARC_NEW_FEATURE_RELATIVE_SAMPLING

#include "prior_interface.h"
#include "ui_strings.h"
#include "ui_vars.h"

using std::string;

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

uiParameterUseDefaultPrior::uiParameterUseDefaultPrior()
    : SetGetBool(uistr::priorUseDefault)
{
}

uiParameterUseDefaultPrior::~uiParameterUseDefaultPrior()
{
}

bool uiParameterUseDefaultPrior::Get(UIVars& vars, UIId id)
{
    return vars.forces.GetUseDefaultPrior(id.GetForceType(), id.GetIndex1());
}

void uiParameterUseDefaultPrior::Set(UIVars& vars, UIId id, bool val)
{
    vars.forces.SetUseDefaultPrior(val, id.GetForceType(), id.GetIndex1());
}

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

uiParameterPriorType::uiParameterPriorType()
    : SetGetPriorType(uistr::priorType)
{
}

uiParameterPriorType::~uiParameterPriorType()
{
}

priortype uiParameterPriorType::Get(UIVars& vars, UIId id)
{
    return vars.forces.GetPriorType(id.GetForceType(), id.GetIndex1());
}

void uiParameterPriorType::Set(UIVars& vars, UIId id, priortype val)
{
    vars.forces.SetPriorType(val, id.GetForceType(), id.GetIndex1());
}

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

uiParameterLowerBound::uiParameterLowerBound()
    : SetGetDouble(uistr::priorLowerBound)
{
}

uiParameterLowerBound::~uiParameterLowerBound()
{
}

double uiParameterLowerBound::Get(UIVars& vars, UIId id)
{
    return vars.forces.GetLowerBound(id.GetForceType(), id.GetIndex1());
}

void uiParameterLowerBound::Set(UIVars& vars, UIId id, double val)
{
    vars.forces.SetLowerBound(val, id.GetForceType(), id.GetIndex1());
}

string uiParameterLowerBound::Min(UIVars& vars, UIId id)
{
    switch(id.GetForceType())
    {
        case force_COAL:
            return ToString(defaults::minboundTheta);
            break;
        case force_MIG:
            return ToString(defaults::minboundMig);
            break;
        case force_DIVMIG:
            return ToString(defaults::minboundDivMig);
            break;
        case force_DIVERGENCE:
            return ToString(defaults::minboundEpoch);
            break;
        case force_DISEASE:
            return ToString(defaults::minboundDisease);
            break;
        case force_REC:
            return ToString(defaults::minboundRec);
            break;
        case force_GROW:
        case force_EXPGROWSTICK:
            return ToString(defaults::minboundGrowth);
            break;
        case force_LOGSELECTSTICK:
        case force_LOGISTICSELECTION:
            return ToString(defaults::minboundLSelect);
            break;
        case force_REGION_GAMMA:
        {
            string msg = "uiParameterLowerBound::Min() attempted to set the lower ";
            msg += "bound for the prior on the alpha parameter of the gamma \"force.\"";
            msg += "Unfortunately the gamma can\'t be used for Bayesian analyses, ";
            msg += "only likelihood analyses.";
            throw implementation_error(msg);
        }
        break;
        case force_NONE:
            assert(false);
            return ToString(defaults::minboundTheta);
            break;
    }
    assert(false); //uncaught force type;
    return ToString(defaults::minboundTheta);
}

string uiParameterLowerBound::Max(UIVars& vars, UIId id)
{
    return ToString(vars.forces.GetUpperBound(id.GetForceType(), id.GetIndex1()));
}

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

uiParameterUpperBound::uiParameterUpperBound()
    : SetGetDouble(uistr::priorUpperBound)
{
}

uiParameterUpperBound::~uiParameterUpperBound()
{
}

double uiParameterUpperBound::Get(UIVars& vars, UIId id)
{
    return vars.forces.GetUpperBound(id.GetForceType(), id.GetIndex1());
}

void uiParameterUpperBound::Set(UIVars& vars, UIId id, double val)
{
    vars.forces.SetUpperBound(val, id.GetForceType(), id.GetIndex1());
}

string uiParameterUpperBound::Min(UIVars& vars, UIId id)
{
    return ToString(vars.forces.GetLowerBound(id.GetForceType(), id.GetIndex1()));
}

string uiParameterUpperBound::Max(UIVars& vars, UIId id)
{
    switch(id.GetForceType())
    {
        case force_COAL:
            return ToString(defaults::maxboundTheta);
            break;
        case force_DIVMIG:
            return ToString(defaults::maxboundDivMig);
            break;
        case force_DIVERGENCE:
            return ToString(defaults::maxboundEpoch);
            break;
        case force_MIG:
            return ToString(defaults::maxboundMig);
            break;
        case force_DISEASE:
            return ToString(defaults::maxboundDisease);
            break;
        case force_REC:
            return ToString(defaults::maxboundRec);
            break;
        case force_GROW:
        case force_EXPGROWSTICK:
            return ToString(defaults::maxboundGrowth);
            break;
        case force_LOGSELECTSTICK:
        case force_LOGISTICSELECTION:
            return ToString(defaults::maxboundLSelect);
            break;
        case force_REGION_GAMMA:
        {
            string msg = "uiParameterUpperBound::Max() attempted to set the upper ";
            msg += "bound for the prior on the alpha parameter of the gamma \"force.\"";
            msg += "Unfortunately the gamma can\'t be used for Bayesian analyses, ";
            msg += "only likelihood analyses.";
            throw implementation_error(msg);
        }
        break;
        case force_NONE:
            assert(false);
            return ToString(defaults::maxboundTheta);
            break;
    }
    assert(false); //uncaught force type;
    return ToString(defaults::maxboundTheta);
}

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

#ifdef LAMARC_NEW_FEATURE_RELATIVE_SAMPLING
uiParameterRelativeSampling::uiParameterRelativeSampling()
    : SetGetLong(uistr::relativeSampleRate)
{
}

uiParameterRelativeSampling::~uiParameterRelativeSampling()
{
}

long uiParameterRelativeSampling::Get(UIVars& vars, UIId id)
{
    return vars.forces.GetRelativeSampling(id.GetForceType(), id.GetIndex1());
}

void uiParameterRelativeSampling::Set(UIVars& vars, UIId id, long val)
{
    vars.forces.SetRelativeSampling(val, id.GetForceType(), id.GetIndex1());
}
#endif

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

uiPriorByForce::uiPriorByForce()
    : SetGetNoval(uistr::priorByForce)
{
}

uiPriorByForce::~uiPriorByForce()
{
}

string uiPriorByForce::Description(UIVars& vars, UIId id)
{
    string retVal = SetGetNoval::Description(vars,id);
    retVal += vars.datapackplus.GetParamNameOfForce(id.GetForceType());
    return retVal;
}

string uiPriorByForce::GetPrintString(UIVars& vars, UIId id)
{
    return vars.forces.GetPriorTypeSummaryDescription(id.GetForceType());
}

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

uiPriorById::uiPriorById()
    : SetGetNoval(uistr::priorByID)
{
}

uiPriorById::~uiPriorById()
{
}

string uiPriorById::Description(UIVars& vars, UIId id)
{
    return vars.GetParamNameWithConstraint(id.GetForceType(),id.GetIndex1());
}

string uiPriorById::GetPrintString(UIVars& vars, UIId id)
{
    return vars.forces.GetPriorTypeSummaryDescription(id.GetForceType(), id.GetIndex1());
}

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

uiUseDefaultPriorsForForce::uiUseDefaultPriorsForForce()
    : SetGetNoval(uistr::useDefaultPriorsForForce)
{
}

uiUseDefaultPriorsForForce::~uiUseDefaultPriorsForForce()
{
}

void uiUseDefaultPriorsForForce::Set(UIVars& vars, UIId id, noval val)
{
    force_type ft = id.GetForceType();
    vars.forces.SetUseDefaultPriorsForForce(ft);
}

string uiUseDefaultPriorsForForce::Description(UIVars& vars, UIId id)
{
    string retVal = SetGetNoval::Description(vars,id);
    retVal += vars.datapackplus.GetParamNameOfForce(id.GetForceType());
    return retVal;
}

//____________________________________________________________________________________
