//#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 {


//#Scenario:

    Parser::MapValue spread
    {
        "spread:",
        new Parser
    };
    
    Parser::MapValue iterations
    {
        "iterations:",
        new Parser
    };
    
    Parser::MapValue generator
    {
        "generator:",
        new Parser
    };
    
    Parser::MapValue seed
    {
        "seed:",
        new Parser
    };
    
    Parser::MapValue cases
    {
        "cases:",
        new Parser
    };
    
    Parser::MapValue death
    {
        "death:",
        new Parser
    };

//#Costs:

    Parser::MapValue diameters
    {
        "diameters:",
        new Parser
    };

    //#Discount:
        Parser::MapValue age
        {
            "age:",
            new Parser
        };

        Parser::MapValue proport
        {
            "proportion:", new Parser
        };

    Parser::MapValue biop           // only used for BC
    {
        "biop:", new Parser
    };
    
//BreastDensities:  - required  [ cf. densities/ ]
//
    Parser::MapValue breastDensities
    {
        "BreastDensities:",
        new Parser
        {
            { // map
                {"ageGroup:", new Parser},
            }
        }
    };


//#Modalities:

    // only within Mammo: (for which Mammo: therefore is optional):
        Parser::MapValue betaMap
        {
            "beta:",
            new Parser
        };

//x        Parser::MapValue systematicError
//x        {
//x            "systematicError:",
//x            new Parser
//x        };
//x
//x        Parser::MapValue m
//x        {
//x            "m:",
//x            new Parser
//x        };

    Parser::MapValue mammo
    {
        "Mammo:",
        new Parser
        {
            {
                {"costs:",              new Parser },
                {"dose:",               new Parser },
                {"specificity:",        new Parser },

                {"m:",                  new Parser },
                {"beta:",               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 },   // set by costs/costs1.cc
                {"dose:",           new Parser },
                {"sensitivity:",    new Parser },
                {"specificity:",    new Parser },
            }
        }
    };
    

//#Screening:
    Parser::MapValue roundMap
    {
        "round:",
        new Parser
    };
    
    Parser::MapValue attendanceRate
    {
        "attendanceRate:",
        new Parser
    };


//#Tumor:
    //# only within Beir7: (for which Beir7: therefore is optional):

//x    Parser::MapValue male
//x    {
//x        "male:",
//x        new Parser
//x    };
//x
//x    Parser::MapValue female
//x    {
//x        "female:",
//x        new Parser
//x    };


Parser::MapValue beir7
{
    "Beir7:",
    new Parser
    {
        { // map
            { "breast:",    new Parser },

            { "male:",      new Parser },
            { "female:",    new Parser },
        }
    }
};

//# only within Growth: (for which Growth: therefore is optional):

//x    Parser::MapValue start
//x    {
//x        "start:",
//x        new Parser
//x    };

//#DoublingTime: only used in Growth, therefore optional

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

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

    //#Incidence: with Tumor:     - optional

        Parser::MapValue Male
        {
            Globals::label(MALE),
            new Parser
            {
                {
                    {"riskTable:",    new Parser },
                    {"lifetimeRisk:", new Parser },
                    {"meanAge:",      new Parser },
                    {"stdDev:",       new Parser },
                }
            }
        };
        
        Parser::MapValue Female
        {
            Globals::label(FEMALE),
            new Parser
            {
                {
                    {"riskTable:",    new Parser },
                    {"lifetimeRisk:", new Parser },
                    {"meanAge:",      new Parser },
                    {"stdDev:",       new Parser },
                }
            }
        };
        
        Parser::MapValue Breast
        {
            Globals::label(BREAST),
            new Parser
            {
                {
                    {"probability:",  new Parser },
                    {"riskTable:",    new Parser },
                    {"lifetimeRisk:", new Parser },
                    {"meanAge:",      new Parser },
                    {"stdDev:",       new Parser },
                }
            }
        };
        
        Parser::MapValue Brca1
        {
            "BRCA1:",
            new Parser
            {
                {
                    {"probability:", new Parser },
                    {"riskTable:",    new Parser },
                    {"lifetimeRisk:", new Parser },
                    {"meanAge:", new Parser },
                    {"stdDev:", new Parser },
                }
            }
        };
        
        Parser::MapValue Brca2
        {
            "BRCA2:",
            new Parser
            {
                {
                    {"probability:", new Parser },
                    {"riskTable:",    new Parser },
                    {"lifetimeRisk:", new Parser },
                    {"meanAge:", new Parser },
                    {"stdDev:", new Parser },
                }
            }
        };
        

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

        //#S3:
            Parser::MapValue prob
            {
                "prob:",
                new Parser
            };

        Parser::MapValue bc
        {
            "bc:",
            new Parser
        };

} // anonymous namespace ends


Parser::Map Parser::s_map       // see the configuration file: these are the
{                               // configurations for the top-level keywords
                                // e.g., scenario here (above) and Scenario:
                                // in the configuration file
    spread,
    iterations,
    generator,
    seed,
    cases,
    death,

    biop,
    diameters,
    proport,
    age,

    breastDensities,

    betaMap,
//    systematicError,
//    m,

    mammo,
    tomo,
    mri,
    ct,

    roundMap,
    attendanceRate,

//    male,
//    female,
    beir7,

//    start,
    growth,

    Male,
    Female,
    Breast,
    Brca1,
    Brca2,
        
    type,
    bc,

    lung0,
    lung1,
    lung2,
    lung3,
    prob,

    { "Scenario:",      new Parser },
    { "Costs:",         new Parser },
    { "Discount:",      new Parser },
    { "Modalities:",    new Parser },
    { "Screening:",     new Parser },
    { "Tumor:",         new Parser },
    { "Incidence:",     new Parser },
    { "Survival:",      new Parser },
    { "S3:",            new Parser },
};






//  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
