//#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 },
        }
    }
};

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 mamDose
{
    "Dose:",
    new Parser
    {
        {
            {"bi-rad:",   new Parser },
        }
    }
};

Parser::MapValue mamM
{
    "M:",
    new Parser
    {
        {
            {"bi-rad:",   new Parser },
        }
    }
};

Parser::MapValue mamBeta
{
    "Beta:",
    new Parser
    {
        {
            {"nr:",   new Parser },
        }
    }
};

Parser::MapValue mamSpecificity
{
    "Specificity:",
    new Parser
    {
        {
            {"ageGroup:",   new Parser },
        }
    }
};

Parser::MapValue mammo
{
    "Mammo:",
    new Parser
    {
        {
            {"costs:",            new Parser },
            {"systematicError:",  new Parser },
            mamDose, 
            mamM,
            mamBeta,
            mamSpecificity,
        }
    }
};

Parser::MapValue tomDose
{
    "Dose:",
    new Parser
    {
        {
            {"bi-rad:",   new Parser },
        }
    }
};

Parser::MapValue tomSensitivity
{
    "Sensitivity:",
    new Parser
    {
        {
            {"bi-rad:",   new Parser },
        }
    }
};

Parser::MapValue tomSpecificity
{
    "Specificity:",
    new Parser
    {
        {
            {"ageGroup:",   new Parser },
        }
    }
};


Parser::MapValue tomo
{
    "Tomo:",
    new Parser
    {
        {
            {"costs:",          new Parser },
            tomDose,
            tomSpecificity,
            tomSensitivity,
        }
    }
};

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

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


Parser::MapValue incNormal
{
    "Normal:",
    new Parser
    {
        {
            {"probability:",  new Parser },
            {"lifetimeRisk:", new Parser },
            {"meanAge:",      new Parser },
            {"stdDev:",       new Parser },
        }
    }
};

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

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

Parser::MapValue tumIncidence
{
    "Incidence:",
    new Parser
    {
        {
            incNormal,
            incBrca1,
            incBrca2,
        }
    }
};

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

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

Parser::MapValue tumSurvival
{
    "Survival:",
    new Parser
    {
        {
            {"type:", new Parser },
        }
    }
};

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

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
{
    scenario,
    costs,
    screening,
    breastDensities,
    modalities,
    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
