#ifndef POTENTIALSOLVER_H
#define POTENTIALSOLVER_H

#include <dolfin.h>

#include "Potential.h"
#include "PotentialProblem.h"
#include "FormArray.h"
#include "SigmaBoard.h"

using namespace dolfin;

class ElectrodePotential : public Function
{
public:
    ElectrodePotential(Mesh& mesh) : Function(mesh), potential(50) {}

    void eval(real* values, const real* x) const
    {
        values[0] = potential;
    }

    real getPotential() const {return potential;}
    void setPotential(const real p) {potential = p;}

private:
    real potential;
};

class PotentialSolver
{
public:
    PotentialSolver (PotentialProblem* problem);
    virtual ~PotentialSolver ();

    void init(Function* T);
    void solve();
    void save();

    Function* getPhi() const {return Phi;}
    real getPowerTolerance() const {return powerTolerance;}
    void setPowerTolerance(const real t) {powerTolerance = t;}
    real getPotential() const {return electrodePotential->getPotential();}
    void setPotential(const real p) {electrodePotential->setPotential(p);}
    real getSigmaBoard() const {return sigmaBoard->getSigma();}
    void setSigmaBoard(const real s) {sigmaBoard->setSigma(s);}
    real getMinSigmaBoard() const {return minSigmaBoard;}
    void setMinSigmaBoard(const real s) {minSigmaBoard = s;}
    real getMaxSigmaBoard() const {return maxSigmaBoard;}
    void setMaxSigmaBoard(const real s) {maxSigmaBoard = s;}

    void matchInitialPower();

private:
    PotentialProblem* problem;

    Function* Phi;
    PotentialBilinearForm* a;
    PotentialLinearForm* L;
    FormArray forms;
    Assembler* assembler;
    PotentialFunctional* M;
    LinearPDE* pde;
    MeshFunction<uint>* domains;
    File* file_Phi;

    Array<BoundaryCondition*> bcs;

    ElectrodePotential* electrodePotential;
    SigmaBoard* sigmaBoard;
    real powerTolerance;
    real minSigmaBoard;
    real maxSigmaBoard;
    real domainPower;
};

#endif /* end of include guard: POTENTIALSOLVER_H */
