#ifndef ELEMENTFILEWRITER_H
#define ELEMENTFILEWRITER_H

#include "FileWriter.h"
#include "FiniteElemSpace.h"
#include "MatrixVector.h"
#include "MemoryManager.h"
#include "Mesh.h"

namespace AMDiS {

  /** \brief
   * Filewriter that make it possible to create mesh files, where the values
   * are not defined on DOFs, but instead are defined on the elements.
   *
   * It can be necessary to visualize data defined on elements, e.g. residual
   * error that is defined on elements and not on DOFs. This class takes as
   * input a mesh and a map, which defines for each element index a (double)
   * value, and outputs a TecPlot/AMDiS/VTK mesh.
   */
  class ElementFileWriter : public FileWriterInterface
  {
  public:
    MEMORY_MANAGED(ElementFileWriter);

    /// Constructor.
    ElementFileWriter(const std::string& name, 
		      const FiniteElemSpace *feSpace,
		      std::map<int, double> &vec);

    /// Implementation of FileWriterInterface::writeFiles().
    void writeFiles(AdaptInfo *adaptInfo, bool force,
		    int level = -1,
		    Flag traverseFlag = Mesh::CALL_LEAF_EL,
		    bool (*writeElem)(ElInfo*) = NULL);

    /// Simple writing procedure for one element map.
    static void writeFile(std::map<int, double> &vec,
			  const FiniteElemSpace *feSpace,
			  const std::string& filename);

  protected:
    /// Writes element data in tecplot format.
    void writeTecPlotValues(const std::string &filename);

    /// Writes element data in AMDiS format (1 file !).
    void writeMeshDatValues(const std::string &filename, double time);

    /// Writes element data in VTK format.
    void writeVtkValues(const std::string &filename);

  protected:
    /// Name.
    std::string name;

    /// Used filename prefix.
    std::string filename;

    /// TecPlot file extension.
    std::string tecplotExt;

    /// AMDiS mesh-data-file extension.
    std::string amdisMeshDatExt;

    /// VTK file extension.
    std::string vtkExt;

    /** \brief
     * 0: Don't write TecPlot files.
     * 1: Write TecPlot files. 
     */
    int writeTecPlotFormat;

    /** \brief
     * 0: Don't write AMDiS files.
     * 1: Write AMDiS files. 
     */
    int writeAMDiSFormat;

    /** \brief
     * 0: Don't write VTK files.
     * 1: Write VTK files. 
     */
    int writeVtkFormat;

    /** \brief
     * 0: Don't append time index to filename prefix.
     * 1: Append time index to filename prefix.
     */
    int appendIndex;

    /// Total length of appended time index.
    int indexLength;

    /// Number of decimals in time index.
    int indexDecimals;

    /// Timestep modulo: write only every tsModulo-th timestep! 
    int tsModulo;

    ///
    int timestepNumber;

    /// Mesh used for output.
    Mesh *mesh;

    /// fespace used for output.
    const FiniteElemSpace *feSpace;

    /// Vector that stores the solution.
    std::map<int, double> vec;
  };

}


#endif  // ELEMENTFILEWRITER_H