//#define XERR
#include "parser.ih"

    // In the configuration file specifications are just lines. Each keyword
    // must therefore be searched via a unique path. So searching for
    // e.g., { 'costs:' } returns multiple hits, but searching for
    // { 'Scenario:', 'costs:' } returns only one hit

    // Named MapValues must be used only once. E.g., for Mammo 'Dose' is
    // specified by mdose, for Tomo it is specified by tdose.
    // final "named" keys are always unique and can be specified at MapValue
    // specifications.

    // see also the description at the end of this file


namespace {


Parser::MapValue scenario
{
    "Scenario:",
    new Parser
    {
        { // map
            {"spread:",     new Parser },
            {"iterations:", new Parser },
            {"generator:",  new Parser },
            {"seed:",       new Parser },
            {"cases:",      new Parser },
            {"death:",      new Parser },
        }
    }
};

Parser::MapValue screening
{
    "Screening:",
    new Parser
    {
        { // map
            {"round:",              new Parser },
            {"attendanceRate:",     new Parser },
        }
    }
};

Parser::MapValue breastDensities
{
    "BreastDensities:",
    new Parser
    {
        { // map
            {"ageGroup:", new Parser},
        }
    }
};

Parser::MapValue mammo
{
    "Mammo:",
    new Parser
    {
        {
            {"beta:",               new Parser },
            {"costs:",              new Parser },
            {"dose:",               new Parser },
            {"m:",                  new Parser },
            {"specificity:",        new Parser },
            {"systematicError:",    new Parser },
        }
    }
};

Parser::MapValue tomo
{
    "Tomo:",
    new Parser
    {
        {
            {"costs:",          new Parser },
            {"dose:",           new Parser },
            {"sensitivity:",    new Parser },
            {"specificity:",    new Parser },
        }
    }
};

Parser::MapValue mri
{
    "MRI:",
    new Parser
    {
        {
            {"costs:",          new Parser },
            {"sensitivity:",    new Parser },
            {"specificity:",    new Parser },
        }
    }
};

Parser::MapValue ct
{
    "CT:",
    new Parser
    {
        {
            {"costs:",          new Parser },
            {"dose:",           new Parser },
            {"sensitivity:",    new Parser },
            {"specificity:",    new Parser },
        }
    }
};

Parser::MapValue modalities
{
    "Modalities:",
    new Parser
    {
        { // map
            mammo,
            tomo,
            mri,
            ct
        }
    }
};

Parser::MapValue incMale
{
    Globals::label(MALE),
    new Parser
    {
        {
            {"riskTable:",    new Parser },
            {"lifetimeRisk:", new Parser },
            {"meanAge:",      new Parser },
            {"stdDev:",       new Parser },
        }
    }
};

Parser::MapValue incFemale
{
    Globals::label(FEMALE),
    new Parser
    {
        {
            {"riskTable:",    new Parser },
            {"lifetimeRisk:", new Parser },
            {"meanAge:",      new Parser },
            {"stdDev:",       new Parser },
        }
    }
};

Parser::MapValue incBreast
{
    Globals::label(BREAST),
    new Parser
    {
        {
            {"probability:",  new Parser },
            {"riskTable:",    new Parser },
            {"lifetimeRisk:", new Parser },
            {"meanAge:",      new Parser },
            {"stdDev:",       new Parser },
        }
    }
};

Parser::MapValue incBrca1
{
    "BRCA1:",
    new Parser
    {
        {
            {"probability:", new Parser },
            {"riskTable:",    new Parser },
            {"lifetimeRisk:", new Parser },
            {"meanAge:", new Parser },
            {"stdDev:", new Parser },
        }
    }
};

Parser::MapValue incBrca2
{
    "BRCA2:",
    new Parser
    {
        {
            {"probability:", new Parser },
            {"riskTable:",    new Parser },
            {"lifetimeRisk:", new Parser },
            {"meanAge:", new Parser },
            {"stdDev:", new Parser },
        }
    }
};

Parser::MapValue tumIncidence
{
    "Incidence:",
    new Parser
    {
        {
            incMale,
            incFemale,
            incBreast,
            incBrca1,
            incBrca2,
        }
    }
};

Parser::MapValue groDoublingTime
{
    "DoublingTime:",
    new Parser
    {
        {
            {"ageGroup:", new Parser},
            {"lung:",     new Parser},
        }
    }
};

Parser::MapValue tumGrowth
{
    "Growth:",
    new Parser
    {
        {
            {"start:",  new Parser },
            {"breast:", new Parser },
            {"lung:",   new Parser },
            groDoublingTime,
        }
    }
};

Parser::MapValue tumSurvival
{
    "Survival:",
    new Parser
    {
        {
            {"type:",   new Parser },
            {"lung0:",  new Parser },
            {"lung1:",  new Parser },
            {"lung2:",  new Parser },
            {"lung3:",  new Parser },
        }
    }
};

Parser::MapValue s3
{
    "S3:",
    new Parser
    {
        {
            {"prob:", new Parser },
        }
    }
};

Parser::MapValue tumBeir7
{
    "Beir7:",
    new Parser
    {
        { // map
            { "breast:",    new Parser },
            { "male:",      new Parser },
            { "female:",    new Parser },
        }
    }
};

Parser::MapValue tumor
{
    "Tumor:",
    new Parser
    {
        { // map
            tumIncidence,
            tumGrowth,
            tumBeir7,
            { "beir7:",     new Parser },
            tumSurvival,
            s3,
            { "bc:",        new Parser },
        }
    }
};

Parser::MapValue cosDiscount
{
    "Discount:",
    new Parser
    {
        { // map
            {"age:",        new Parser },
            {"proportion:", new Parser },
        }
    }
};

Parser::MapValue costs
{
    "Costs:",
    new Parser
    {
        {
            {"biop:",       new Parser },
            {"diameters:",  new Parser },
            cosDiscount,
        }
    }
};

} // namespace

Parser::Map Parser::s_map       // see the configuration file: these are the
{                               // configurations for the top-level keywords
    scenario,                   // e.g., scenario here (above) and Scenario:
    costs,                      // in the configuration file
    breastDensities,
    modalities,
    screening,
    tumor,
};


//  By convention, keywords of lines mererly containing the keyword
//  start with capitals, and those followed by actual parameter values
//  start with lower-case letters
//
//  MapValue definitions ending in 'new Parser' match one or more
//  configuration lines which are handled by the objects for which
//  the configuration line is intended.
//
//  Parser specifications merely consisting of identifiers refer to
//  separately defined specifications
//
//  E.g.,
//
//      Parser::MapValue modalities
//      {
//          "Modalities:",
//          new Parser
//          {
//              {
//                  mammo,
//                  tomo,
//                  mri
//              }
//          }
//      };
//
//  specifies Modalities: as a keyword, followed by the definitions of mammo,
//  tomo, and mri. The 'tomo' MapValue is
//
//      Parser::MapValue tomo
//      {
//          "Tomo:",
//          new Parser
//          {
//              {
//                  {"costs:",          new Parser },
//                  dose,
//                  ...
//              }
//          }
//      };
//
//  and so 'costs:' is followed by >= 1 parameter values, but 'dose' is
//  specified separately:
//
//      Parser::MapValue dose
//      {
//          "Dose:",
//          new Parser
//          {
//              {
//                  {"bi-rad:",   new Parser },
//              }
//          }
//      };
//
//  The keyword 'Dose:' is on a line by itself, followed by lines starting
//  with 'bi-rad:' containing parameter specifications.
//
//  What the parameter specifications are is determined by the objects parsing
//  the configuration lines. E.g., ageGroup: is specified as
//          ageGroup:   0 - 40:     .961        .005   Normal
//  but also as:
//          ageGroup:    0  - 40:    .05    .30    .48    .17
