// $Id: profile_interface.cpp,v 1.28 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 <iostream>

#include "constants.h"
#include "profile_interface.h"
#include "stringx.h"
#include "ui_id.h"
#include "ui_interface.h"
#include "ui_strings.h"
#include "ui_vars.h"
#include "ui_vars_forces.h"

using std::string;

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

uiGlobalProfileOn::uiGlobalProfileOn()
    : SetGetNoval(uistr::allProfilesOn)
{
}

uiGlobalProfileOn::~uiGlobalProfileOn()
{
}

void uiGlobalProfileOn::Set(UIVars& vars, UIId id,noval val)
{
    vars.forces.SetDoProfile(true);
}

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

uiGlobalProfileOff::uiGlobalProfileOff()
    : SetGetNoval(uistr::allProfilesOff)
{
}

uiGlobalProfileOff::~uiGlobalProfileOff()
{
}

void uiGlobalProfileOff::Set(UIVars& vars, UIId id,noval val)
{
    vars.forces.SetDoProfile(false);
}

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

uiGlobalProfilePercentile::uiGlobalProfilePercentile()
    : SetGetNoval(uistr::allProfilesPercentile)
{
}

uiGlobalProfilePercentile::~uiGlobalProfilePercentile()
{
}

void uiGlobalProfilePercentile::Set(UIVars& vars, UIId id,noval val)
{
    vars.forces.SetProfileType(profile_PERCENTILE);
}

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

uiGlobalProfileFixed::uiGlobalProfileFixed()
    : SetGetNoval(uistr::allProfilesFixed)
{
}

uiGlobalProfileFixed::~uiGlobalProfileFixed()
{
}

void uiGlobalProfileFixed::Set(UIVars& vars, UIId id,noval val)
{
    vars.forces.SetProfileType(profile_FIX);
}

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

uiProfileByID::uiProfileByID()
    : SetGetBool(uistr::profileByID)
{
}

uiProfileByID::~uiProfileByID()
{
}

string uiProfileByID::Description(UIVars& vars, UIId id)
{
    // EWFIX.P5 DIMENSIONS -- will change if we divide up 2-d params into 2-D storage
    return vars.GetParamNameWithConstraint(id.GetForceType(),id.GetIndex1());
}

bool uiProfileByID::Get(UIVars& vars, UIId id)
{
    force_type thisForce = id.GetForceType();
    long thisIndex = id.GetIndex1();
    return vars.forces.GetDoProfile(thisForce,thisIndex);
}

void uiProfileByID::Set(UIVars& vars, UIId id, bool val)
{
    force_type thisForce = id.GetForceType();
    long thisIndex = id.GetIndex1();
    vars.forces.SetDoProfile(val,thisForce,thisIndex);
}

string uiProfileByID::MakePrintString(UIVars& vars, bool val)
{
    if(val) return "Enabled";
    return "Disabled";
};

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

uiProfileByForce::uiProfileByForce()
    : SetGetProftype(uistr::profileByForce)
{
}

uiProfileByForce::~uiProfileByForce()
{
}

proftype uiProfileByForce::Get(UIVars& vars, UIId id)
{
    return vars.forces.GetProfileType(id.GetForceType());
}

void uiProfileByForce::Set(UIVars& vars, UIId id, proftype val)
{
    vars.forces.SetProfileType(val,id.GetForceType());
}

string uiProfileByForce::Description(UIVars& vars, UIId id)
{
    return uistr::profileByForce
        + vars.datapackplus.GetParamNameOfForce(id.GetForceType());
}

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

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

UIIdVec1d uiValidParamsForOneForce::Get(UIVars& vars, UIId id)
{
    force_type thisForce = id.GetForceType();
    long numPossibleParams = vars.forces.GetNumParameters(thisForce);
    UIIdVec1d validParams;
    for(long localId=0; localId < numPossibleParams; localId++)
    {
        if(vars.forces.GetParamValid(thisForce,localId))
        {
            if (vars.forces.GetParamUnique(thisForce, localId))
            {
                validParams.push_back(UIId(thisForce,localId));
            }
        }
    }
    return validParams;
}

uiValidParamsForOneForce::uiValidParamsForOneForce()
    : GetUIIdVec1d(uistr::validParamsForForce)
{
}

uiValidParamsForOneForce::~uiValidParamsForOneForce()
{
}

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

UIIdVec1d
uiValidForces::Get(UIVars& vars, UIId id)
{
    ForceTypeVec1d activeForces = vars.forces.GetActiveForces();
    ForceTypeVec1d::iterator iter;
    UIIdVec1d uiids;

    for(iter=activeForces.begin(); iter != activeForces.end(); iter++)
    {
        force_type ft = *iter;
        uiids.push_back(UIId(ft));
    }
    return uiids;
}

uiValidForces::uiValidForces()
    : GetUIIdVec1d(uistr::validForces)
{
}

uiValidForces::~uiValidForces()
{
}

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

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

uiForceProfilesOff::uiForceProfilesOff()
    : SetGetNoval(uistr::oneForceProfilesOff)
{
}

uiForceProfilesOff::~uiForceProfilesOff()
{
}

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

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

uiForceProfilesOn::uiForceProfilesOn()
    : SetGetNoval(uistr::oneForceProfilesOn)
{
}

uiForceProfilesOn::~uiForceProfilesOn()
{
}

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

proftype
uiForceProfileType::Get(UIVars& vars, UIId id)
{
    force_type ft = id.GetForceType();
    return vars.forces.GetProfileType(ft);
}

void
uiForceProfileType::Set(UIVars& vars, UIId id, proftype ptype)
{
    force_type ft = id.GetForceType();
    vars.forces.SetProfileType(ptype,ft);
}

uiForceProfileType::uiForceProfileType()
    : SetGetProftype(uistr::oneForceProfileType)
{
}

uiForceProfileType::~uiForceProfileType()
{
}

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

string
uiForceProfileType::NextToggleValue(UIVars& vars, UIId id)
{
    switch(Get(vars,id))
    {
        case profile_NONE:
            // Should never happen, but we could recover.
            // Let's assert in the debug case, but
            // fall through to recover for release
            assert(false);
        case profile_PERCENTILE:
            return ToString(profile_FIX);
            break;
        case profile_FIX:
            return ToString(profile_PERCENTILE);
            break;
    }
    throw implementation_error("uiForceProfileType::NextToggleValue bad switch case");
}

//____________________________________________________________________________________
