#ifndef _EWOD_H_
#define _EWOD_H_

#include <deal.II/grid/grid_generator.h>
#include <deal.II/fe/fe_system.h>
#include <deal.II/base/conditional_ostream.h>
#include <deal.II/numerics/error_estimator.h>
#include <deal.II/grid/grid_refinement.h>
#include <deal.II/grid/grid_tools.h>

#include "Material.h"
#include "FileReader.h"
#include "Voltage.h"
#include "Charge.h"
#include "CHNSE.h"

/**
 * This class synchronizes all the other classes that are derived from Problem,
 * drives the solution process and produces output.
 */
template<int dim> class EWOD{
  public:
    /**
     * Read the data and initialize the subproblems.
     */
    EWOD( DataStorage<dim> &data );
    /**
     * Do the time marching.
     */
    void run();
    /** 
     * Clear data
     */
    ~EWOD();
  protected:
    const double t0, ///< Initial time.
                 T; ///< Final time
    Material_Parameters params; ///< Material parameters
    ConditionalOStream v_cout; ///< log stream
    Triangulation<dim> tri; ///< The triangulation where all the problems are defined.
    const double dt0; ///< Original time step.
    double dt; ///< Current time step.
    Voltage<dim> V; ///< The subproblem that defines the Voltage.
    Charge<dim> q; ///< The subproblem that defines the Charge.
    CHNSE<dim> chnse; ///< The subproblem that defines the Cahn Hilliard Navier Stokes problem.
    const unsigned plot, ///< How often we want to plot
                   max_refs, ///< The maximal number of refinements
                   initial_refs; ///< The initial number of refinements
  private:
    /**
     * Take the solution to all the subproblems and plot the results as a <code>*.vtk</code>
     * file.
     @param step : The current step. Used to name the file the results are written to
     */
    void Plot( const unsigned step );
    /**
     * Refine the mesh. If it is the first step load the initial data, if not
     * make sure that the solution is transfered to the new mesh.
     */
    void RefineMesh( const bool is_the_first_step = false );
    /**
     * Compute the new time step according to the rule
     * \f[
     *    \Delta t = \min 
     *     \left\{ \Delta t_0,  \frac{ h^{3/2} }{ \| \textbf{u} \|_{L^\infty} } \right\}
     * \f]
     */
      
    void set_dt();
};

#endif //_EWOD_H_
