#ifndef _FILE_READER_H_
#define _FILE_READER_H_

#include <deal.II/base/parameter_handler.h>
#include <deal.II/base/point.h>
#include <fstream>
#include <iostream>

#include "Material.h"

using namespace dealii;

/**
 * We store here all the parameters from the parameter file
 * so that they can be read into the main program
 */
template<int dim> class DataStorage{
  public:
    double t_0, ///< Initial time
           T;  ///< Final time
    TestCase testcase; ///< The test case
    std::pair<double, double> epsilon, ///< permitivity
                              K, ///< conductivity
                              M, ///< mobility
                              rho, ///< density
                              beta, ///< slip coefficient
                              eta; ///< viscosity
    double lambda, ///< charge
           gamma, ///< surface tension
           theta_s, ///< static contact angle
           delta, ///< interface thickness
           alpha, ///< surface transport parameter
           epsilon_plate; ///< permitivity of the plates
    Point<dim> pl, ///< The bottom-left corner of the box the fluid occupies
               pu; ///< The top-right corner of the box the fluid occupies
    double width; ///< The width of the plates
    double dt; ///< the time-step size
    unsigned volt_deg, ///< The polynomial degree of the voltage
             ph_deg, ///< The polynomial degree of the phase field
             pres_deg, ///< The polynomial degree of the pressure space. Velocity is +1
             n_of_initial_refines, ///< number of initial refinements of the mesh
             n_of_extra_refines; ///< number of extra refinements near the interface
    unsigned volt_update_prec, ///< How often the preconditioner in Voltage needs to be reinitialized
             volt_smoother_sweeps; ///< Number of smoothings for the Voltage preconditioner
    double volt_eps, ///< Tolerance in Voltage.
           volt_aggregation_threshold; ///< Aggregation threshold in Voltage
    unsigned charge_update_prec, ///< How often the preconditioner needs to be reinitialized in Charge
             charge_smoother_sweeps; ///< The number of smoothings for the Charge preconditioner
    double charge_eps, ///< Tolerance in Charge
           charge_aggregation_threshold; ///< Aggregation threshold in Charge
    unsigned vel_Krylov_size, ///< The dimension of the Krylov subspace in Velocity
             vel_update_prec, ///< How often the preconditioner needs to be reinitialized in Velocity
             vel_smoother_sweeps; ///< The number of smoothings for the Velocity preconditioner
    double vel_eps, ///< Tolerance in Velocity
           vel_aggregation_threshold; ///< Aggregation threshold in Velocity
    unsigned penalty_smoother_sweeps; ///< The number of smoothings for the Pressure preconditioner
    double penalty_eps, ///< Tolerance in Pressure
           penalty_aggregation_threshold; ///< Aggregation threshold in Pressure
    bool verbose; ///< Verbosity
    unsigned output; ///< Frequency of the outputted data
    /**
     * Create the parameter file entries
     */
    DataStorage();
    /**
     * Does nothing
     */
    ~DataStorage();
    /**
     * Read data from the specified path
     */
    void read_data ( char *filename );
    /**
     * Prints to the console the format of the parameter file together with its default values
     */
    void print_usage();
  protected:
    ParameterHandler prm; ///< The parameter handler
};

#endif //_FILE_READER_H_
