// $Id: lamarcmenuitems.cpp,v 1.36 2018/01/03 21:33:00 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 */


// the base menu is the NON-Interactive "menu"
// derived menus handele the different windowing systems
//  (- Curses)
//  - Scrolling ASCII console
//  (-graphical GUI etc)
// Peter Beerli

#include <string>

#include "local_build.h"

#include "datamodelmenu.h"
#include "forcesmenus.h"
#include "lamarcmenuitems.h"
#include "lamarc_strings.h"
#include "menuitem.h"
#include "menu_strings.h"
#include "newmenu.h"
#include "newmenuitems.h"
#include "outfilemenus.h"
#include "overviewmenus.h"
#include "priormenus.h"
#include "setmenuitem.h"
#include "togglemenuitem.h"
#include "treesummenus.h"
#include "ui_interface.h"
#include "ui_strings.h"
#include "ui_vars.h"

using namespace std;

///// SetMenuItemTempInterval

SetMenuItemTempInterval::SetMenuItemTempInterval(string k, UIInterface & myui)
    : SetMenuItemNoId(k,myui,uistr::tempInterval)
{
}

SetMenuItemTempInterval::~SetMenuItemTempInterval()
{
}

bool SetMenuItemTempInterval::IsVisible()
{
    long numChains = ui.doGetLong(uistr::heatedChainCount);
    return (numChains > 1);
}

///// SetMenuItemHapArranger

SetMenuItemHapArranger::SetMenuItemHapArranger(string k, UIInterface & myui)
    : SetMenuItemNoId(k,myui,uistr::hapArranger)
{
}

SetMenuItemHapArranger::~SetMenuItemHapArranger()
{
}

bool SetMenuItemHapArranger::IsVisible()
{
    return ui.doGetBool(uistr::canHapArrange);
}

///// SetMenuItemProbHapArranger

SetMenuItemProbHapArranger::SetMenuItemProbHapArranger(string k, UIInterface & myui)
    : SetMenuItemNoId(k,myui,uistr::probhapArranger)
{
}

SetMenuItemProbHapArranger::~SetMenuItemProbHapArranger()
{
}

bool SetMenuItemProbHapArranger::IsVisible()
{
    return ui.GetCurrentVars().chains.GetProbHapArrangerPossible();
}

///// SetMenuItemLocusArranger

SetMenuItemLocusArranger::SetMenuItemLocusArranger(string k, UIInterface & myui)
    : SetMenuItemNoId(k,myui,uistr::locusArranger)
{
}

SetMenuItemLocusArranger::~SetMenuItemLocusArranger()
{
}

bool
SetMenuItemLocusArranger::IsVisible()
{
    return ui.GetCurrentVars().traitmodels.AnyJumpingAnalyses();
}

///// SetMenuItemBayesArranger

SetMenuItemBayesArranger::SetMenuItemBayesArranger(string k, UIInterface & myui)
    : SetMenuItemNoId(k,myui,uistr::bayesArranger)
{
}

SetMenuItemBayesArranger::~SetMenuItemBayesArranger()
{
}

bool
SetMenuItemBayesArranger::IsVisible()
{
    return ui.doGetBool(uistr::bayesian);
}

///// SetMenuItemEpochArranger

SetMenuItemEpochArranger::SetMenuItemEpochArranger(string k, UIInterface & myui)
    : SetMenuItemNoId(k,myui,uistr::epochSizeArranger)
{
}

SetMenuItemEpochArranger::~SetMenuItemEpochArranger()
{
}

bool
SetMenuItemEpochArranger::IsVisible()
{
    return ui.GetCurrentVars().forces.GetForceLegal(force_DIVERGENCE);
}

///// SetMenuItemZilchArranger

SetMenuItemZilchArranger::SetMenuItemZilchArranger(string k, UIInterface & myui)
    : SetMenuItemNoId(k,myui,uistr::zilchArranger)
{
}

SetMenuItemZilchArranger::~SetMenuItemZilchArranger()
{
}

bool
SetMenuItemZilchArranger::IsVisible()
{
    return ui.GetCurrentVars().datapackplus.AnySimulation();
}

///// SetMenuItemCurveFilePrefix

SetMenuItemCurveFilePrefix::SetMenuItemCurveFilePrefix(string k, UIInterface & myui)
    : SetMenuItemNoId(k,myui,uistr::curveFilePrefix)
{
}

SetMenuItemCurveFilePrefix::~SetMenuItemCurveFilePrefix()
{
}

bool
SetMenuItemCurveFilePrefix::IsVisible()
{
    return (ui.doGetBool(uistr::bayesian) && ui.doGetBool(uistr::useCurveFiles));
}

///// SetMenuItemMapFilePrefix

SetMenuItemMapFilePrefix::SetMenuItemMapFilePrefix(string k, UIInterface & myui)
    : SetMenuItemNoId(k,myui,uistr::mapFilePrefix)
{
}

SetMenuItemMapFilePrefix::~SetMenuItemMapFilePrefix()
{
}

bool
SetMenuItemMapFilePrefix::IsVisible()
{
    return (ui.GetCurrentVars().traitmodels.GetNumMovableLoci() > 0);

}


///// SetMenuItemReclocFiles

SetMenuItemReclocFiles::SetMenuItemReclocFiles(string k, UIInterface & myui)
    : ToggleMenuItemNoId(k,myui,uistr::useReclocFiles)
{
}

SetMenuItemReclocFiles::~SetMenuItemReclocFiles()
{
}

bool
SetMenuItemReclocFiles::IsVisible()
{
    return (ui.doGetBool(uistr::recombination));
}

///// SetMenuItemReclocFilePrefix

SetMenuItemReclocFilePrefix::SetMenuItemReclocFilePrefix(string k, UIInterface & myui)
    : SetMenuItemNoId(k,myui,uistr::reclocFilePrefix)
{
}

SetMenuItemReclocFilePrefix::~SetMenuItemReclocFilePrefix()
{
}

bool
SetMenuItemReclocFilePrefix::IsVisible()
{
    return (ui.doGetBool(uistr::useReclocFiles) && ui.doGetBool(uistr::recombination));
}

///// SetMenuItemTraceFilePrefix

SetMenuItemTraceFilePrefix::SetMenuItemTraceFilePrefix(string k, UIInterface & myui)
    : SetMenuItemNoId(k,myui,uistr::traceFilePrefix)
{
}

SetMenuItemTraceFilePrefix::~SetMenuItemTraceFilePrefix()
{
}

bool
SetMenuItemTraceFilePrefix::IsVisible()
{
    return (ui.doGetBool(uistr::useTraceFiles));
}

///// SetMenuItemNewickTreeFilePrefix

SetMenuItemNewickTreeFilePrefix::SetMenuItemNewickTreeFilePrefix(string k, UIInterface & myui)
    : SetMenuItemNoId(k,myui,uistr::newickTreeFilePrefix)
{
}

SetMenuItemNewickTreeFilePrefix::~SetMenuItemNewickTreeFilePrefix()
{
}

bool
SetMenuItemNewickTreeFilePrefix::IsVisible()
{
    return (ui.doGetBool(uistr::useNewickTreeFiles));
}

///// ToggleMenuItemTempAdapt

ToggleMenuItemTempAdapt::ToggleMenuItemTempAdapt(string k, UIInterface & myui)
    : ToggleMenuItemNoId(k,myui,uistr::tempAdapt)
{
}

ToggleMenuItemTempAdapt::~ToggleMenuItemTempAdapt()
{
}

bool ToggleMenuItemTempAdapt::IsVisible()
{
    long numChains = ui.doGetLong(uistr::heatedChainCount);
    return (numChains > 1);
}

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

///// ToggleMenuItemUseCurveFiles

ToggleMenuItemUseCurveFiles::ToggleMenuItemUseCurveFiles(string k, UIInterface & myui)
    : ToggleMenuItemNoId(k,myui,uistr::useCurveFiles)
{
}

ToggleMenuItemUseCurveFiles::~ToggleMenuItemUseCurveFiles()
{
}

bool ToggleMenuItemUseCurveFiles::IsVisible()
{
    return ui.doGetBool(uistr::bayesian);
}

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

StrategyMenu::StrategyMenu (UIInterface & myui)
    : NewMenu (myui,lamarcmenu::strategyTitle,menustr::emptyString)
{
    AddMenuItem(new ToggleMenuItemNoId("P",ui,uistr::bayesian));
    AddMenuItem(new PriorSubMenuItem("B",ui));
    AddMenuItem(new SubMenuItem("R",ui,new RearrangeMenuCreator(ui)));
    AddMenuItem(new SubMenuItem("S",ui,new SearchMenuCreator(ui)));
    AddMenuItem(new HeatingSubMenuItem("M",ui));
}

StrategyMenu::~StrategyMenu()
{
}

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

ChainTemperatureMenuItemGroup::ChainTemperatureMenuItemGroup(UIInterface & myui)
    : SetMenuItemGroup(myui,uistr::heatedChain)
{
}

ChainTemperatureMenuItemGroup::~ChainTemperatureMenuItemGroup()
{
}

vector<UIId> ChainTemperatureMenuItemGroup::GetVisibleIds()
{
    vector<UIId> temperatureIds;
    long nTemps = ui.doGetLong(uistr::heatedChainCount);
    if (nTemps > 1)
    {
        for(long i=0; i < nTemps; i++)
        {
            temperatureIds.push_back(UIId(i));
        }
    }
    return temperatureIds;
}

string ChainTemperatureMenuItemGroup::GetText(UIId id)
{
    return uistr::heatedChain + ToString(id.GetIndex1() + 1);
}

HeatingMenu::HeatingMenu (UIInterface & myui )
    : NewMenu (myui,lamarcmenu::heatingTitle,lamarcmenu::heatingInfo)
{
    AddMenuItem(new SetMenuItemNoId("S",ui,uistr::heatedChainCount));
    AddMenuItem(new ToggleMenuItemTempAdapt(string("A"),ui));
    AddMenuItem(new SetMenuItemTempInterval("I",ui));
    AddMenuItem(new ChainTemperatureMenuItemGroup(ui));
}

HeatingMenu::~HeatingMenu ()
{
}

HeatingSubMenuItem::HeatingSubMenuItem(string mykey, UIInterface& myui)
    : SubMenuItem(mykey,myui,new HeatingMenuCreator(myui))
{
}

HeatingSubMenuItem::~HeatingSubMenuItem()
{
}

string
HeatingSubMenuItem::GetVariableText()
{
    long temps = ui.doGetLong(uistr::heatedChainCount,GetId());
    if(temps < 2)
    {
        return "none";
    }
    else
    {
        return ToString(temps)+" chains";
    }
}

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

PriorSubMenuItem::PriorSubMenuItem(string mykey, UIInterface& myui)
    : SubMenuItem(mykey,myui,new PriorMenuCreator(myui))
{
}

PriorSubMenuItem::~PriorSubMenuItem()
{
}

bool PriorSubMenuItem::IsVisible()
{
    return ui.doGetBool(uistr::bayesian);
}

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

RearrangeMenu::RearrangeMenu (UIInterface & myui )
    : NewMenu (myui,lamarcmenu::rearrangeTitle,lamarcmenu::rearrangeInfo)

{
    AddMenuItem(new SetMenuItemNoId("T",ui,uistr::dropArranger));
    AddMenuItem(new SetMenuItemNoId("S",ui,uistr::sizeArranger));
    AddMenuItem(new SetMenuItemHapArranger("H",ui));
    AddMenuItem(new SetMenuItemProbHapArranger("M",ui));
    AddMenuItem(new SetMenuItemBayesArranger("B",ui));
    AddMenuItem(new SetMenuItemEpochArranger("E",ui));
    AddMenuItem(new SetMenuItemLocusArranger("L",ui));
    AddMenuItem(new SetMenuItemZilchArranger("N",ui));
}

RearrangeMenu::~RearrangeMenu ()
{
}

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

SearchMenu::SearchMenu (UIInterface & myui )
    : NewMenu (myui,lamarcmenu::searchTitle,menustr::emptyString)
{
    AddMenuItem(new SetMenuItemNoId("R",ui,uistr::replicates));
    AddMenuItem(new BlankMenuItem());
    AddMenuItem(new OutputOnlyMenuItem("Initial Chains"));
    AddMenuItem(new SetMenuItemNoId("1",ui,uistr::initialChains));
    AddMenuItem(new SetMenuItemNumSamples("2",ui,uistr::initialSamples));
    AddMenuItem(new SetMenuItemNoId("3",ui,uistr::initialInterval));
    AddMenuItem(new SetMenuItemNoId("4",ui,uistr::initialDiscard));
    AddMenuItem(new DividerMenuItem());
    AddMenuItem(new OutputOnlyMenuItem("Final Chains"));
    AddMenuItem(new SetMenuItemNoId("5",ui,uistr::finalChains));
    AddMenuItem(new SetMenuItemNumSamples("6",ui,uistr::finalSamples));
    AddMenuItem(new SetMenuItemNoId("7",ui,uistr::finalInterval));
    AddMenuItem(new SetMenuItemNoId("8",ui,uistr::finalDiscard));
}

SearchMenu::~SearchMenu ()
{
}

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

ResultMenu::ResultMenu (UIInterface & myui )
    : NewMenu (myui,lamarcmenu::resultTitle,menustr::emptyString)
{
    AddMenuItem(new ToggleMenuItemNoId(string("V"),ui,uistr::progress));
    AddMenuItem(new OutfileSubMenuItem(string("O"),ui));
    AddMenuItem(new SetMenuItemNoId("M",ui,uistr::xmlOutFileName));
    AddMenuItem(new TreeSumOutSubMenuItem(string("W"),ui));
    AddMenuItem(new TreeSumInSubMenuItem(string("R"),ui));
    AddMenuItem(new ToggleMenuItemUseCurveFiles(string("B"),ui));
    AddMenuItem(new SetMenuItemCurveFilePrefix("C",ui));
    AddMenuItem(new SetMenuItemMapFilePrefix("I",ui));
    AddMenuItem(new SetMenuItemReclocFiles("L",ui));
    AddMenuItem(new SetMenuItemReclocFilePrefix("F",ui));
    AddMenuItem(new ToggleMenuItemNoId("A",ui,uistr::useTraceFiles));
    AddMenuItem(new SetMenuItemTraceFilePrefix("T",ui));
    AddMenuItem(new ToggleMenuItemNoId("K",ui,uistr::useNewickTreeFiles));
    AddMenuItem(new SetMenuItemNewickTreeFilePrefix("N",ui));
    AddMenuItem(new SetMenuItemNoId("X",ui,uistr::xmlReportFileName));
    AddMenuItem(new SetMenuItemNoId("P",ui,uistr::profileprefix));
#ifdef LAMARC_QA_TREE_DUMP
    AddMenuItem(new ToggleMenuItemNoId("G",ui,uistr::useArgFiles));
    AddMenuItem(new SetMenuItemNoId(string("H"),ui,uistr::argFilePrefix));
    AddMenuItem(new ToggleMenuItemNoId("Z",ui,uistr::manyArgFiles));
#endif // LAMARC_QA_TREE_DUMP
}

ResultMenu::~ResultMenu ()
{
}

OverviewMenu::OverviewMenu (UIInterface & myui )
    : NewMenu (myui,lamarcmenu::overviewTitle)
{
    AddMenuItem(new SubMenuItem(string("D"),ui,new DataOverviewMenuCreator(ui)));
    AddMenuItem(new SubMenuItem(string("A"),ui,new ForceOverviewMenuCreator(ui)));
    AddMenuItem(new SubMenuItemBayesPriors(string("B"),ui));
    AddMenuItem(new SubMenuItemTraitMappingOverview(string("M"), ui));
    AddMenuItem(new SubMenuItem(string("S"),ui,new SearchOverviewMenuCreator(ui)));
    AddMenuItem(new SubMenuItem(string("F"),ui,new FileOverviewMenuCreator(ui)));
    AddMenuItem(new SubMenuItem(string("R"),ui,new ResultsOverviewMenuCreator(ui)));
}

OverviewMenu::~OverviewMenu()
{
}

SubMenuItemBayesPriors::SubMenuItemBayesPriors(string myKey, UIInterface& myui)
    : SubMenuItem(myKey, myui, new BayesianPriorsOverviewMenuCreator(myui))
{
}

SubMenuItemBayesPriors::~SubMenuItemBayesPriors()
{
}

bool SubMenuItemBayesPriors::IsVisible()
{
    return ui.doGetBool(uistr::bayesian);
}

SubMenuItemTraitMappingOverview::SubMenuItemTraitMappingOverview(string myKey, UIInterface& myui)
    : SubMenuItem(myKey, myui, new TraitMappingOverviewMenuCreator(myui))
{
}

SubMenuItemTraitMappingOverview::~SubMenuItemTraitMappingOverview()
{
}

bool SubMenuItemTraitMappingOverview::IsVisible()
{
    return (ui.GetCurrentVars().traitmodels.GetNumMovableLoci() > 0);
}

SetMenuItemNumSamples::SetMenuItemNumSamples(string myKey, UIInterface& myui, string myMenuKey)
    : SetMenuItemNoId(myKey, myui, myMenuKey)
{
}

SetMenuItemNumSamples::~SetMenuItemNumSamples()
{
}

string SetMenuItemNumSamples::GetText()
{
    if (ui.GetCurrentVars().chains.GetDoBayesianAnalysis())
    {
        if (menuKey == uistr::initialSamples)
        {
            return uistr::initialSamplesBayes;
        }
        else if (menuKey == uistr::finalSamples)
        {
            return uistr::finalSamplesBayes;
        }
    }
    return SetMenuItemNoId::GetText();
}

//____________________________________________________________________________________
