/*
 * Copyright University of Reims Champagne-Ardenne
 * Authors and Contributors: Akilan RAJAMANI, Corentin LEFEBVRE, Johanna KLEIN,
 *                           Emmanuel PLUOT, Gaetan RUBEZ, Hassan KHARTABIL,
 *                           Jean-Charles BOISSON and Eric HENON
 * (24/07/2017)
 * jean-charles.boisson@univ-reims.fr, eric.henon@univ-reims.fr
 *
 * This software is a computer program whose purpose is to
 * detect and quantify interactions from electron density
 * obtained either internally from promolecular density or
 * calculated from an input wave function input file. It also
 * prepares for the visualization of isosurfaces representing
 * several descriptors (dg) coming from the IGM methodology.
 *
 * This software is governed by the CeCILL-C license under French law and
 * abiding by the rules of distribution of free software.  You can  use,
 * modify and/ or redistribute the software under the terms of the CeCILL-C
 * license as circulated by CEA, CNRS and INRIA at the following URL
 * "http://www.cecill.info".
 *
 * As a counterpart to the access to the source code and  rights to copy,
 * modify and redistribute granted by the license, users are provided only
 * with a limited warranty  and the software's author,  the holder of the
 * economic rights,  and the successive licensors  have only  limited
 * liability.
 *
 * In this respect, the user's attention is drawn to the risks associated
 * with loading,  using,  modifying and/or developing or reproducing the
 * software by the user in light of its specific status of free software,
 * that may mean  that it is complicated to manipulate,  and  that  also
 * therefore means  that it is reserved for developers  and  experienced
 * professionals having in-depth computer knowledge. Users are therefore
 * encouraged to load and test the software's suitability as regards their
 * requirements in conditions enabling the security of their systems and/or
 * data to be ensured and,  more generally, to use and operate it in the
 * same conditions as regards security.
 *
 * The fact that you are presently reading this means that you have had
 * knowledge of the CeCILL-C license and that you accept its terms.
 *
 * */

/**
 * @file Results.h
 * @brief Manage the results of the application
 * @author Emmanuel */

#ifndef _RESULTS_H_
#define _RESULTS_H_

#ifndef No_OpenMP
#include<omp.h>
#endif

// STL
#include <algorithm>

// LOCAL
#include <ProgData.h>


// PROMOLECULAR MODE
/**
 * @brief Class designed to store all results that can be used as output by the program */
class Results
{
 private :
  
  // Non delta related values

  //! Number of atom focused
  int nbAtom;

  //! Full number of iteration in the main loop
  int fullSize;
		
  // Cube values

  //! Promolecular cube to store deltag INTRA
  double * cubedeltaGIntra;

  //! Promolecular cube to store deltag INTER
  double * cubedeltaGInter;

  //! Promolecular cube to store deltag INTRA with basis change
  double * cubedeltaGIntraFC;

  //! Promolecular cube to store deltag INTER with basis change
  double * cubedeltaGInterFC;


  //! TO DOCUMENT
  double * cubeRho;

  //! TO DOCUMENT
  double * cubeRDG;
		
  // NCI plot handling

  //! TO DOCUMENT
  bool * intermolecularCheck;

  //! result of the dgInter integration over the grid
  double sumdgInter;

  //! result of the dgInter*rho^4/3, integration over the grid
  double scoreInterac; 

  // Single atom related values

  //! TO DOCUMENT
  double **sumDeltaGInterAtom;

  //! The number of threads for the current run
  unsigned int nbThreads;
  
 public :
	
  /**
   * @fn Results(int nbAtomParam, int nbStepsParam)
   * @brief Basic constructor
   * @param nbAtomParam The number of focused atom.
   * @param nbStepsParam the number of steps for the grid crossing in each axis */
  Results(int nbAtomParam, int nbStepsParam);
				 
  /**
   * @fn ~Results()
   * @brief Destructor */
  ~Results();
		
  /**
   * @fn int getNbAtom()
   * @brief Returns the number of atom
   * @return the number of atom */
  int getNbAtom();

  /**
   * @fn void updateCubePauli( int index, double &self)
   * @brief Function used to store self descriptor for current grid node                
   * @param index grid index value
   * @param input --> the self promolecular descriptor */
  void updateCubePauli( int index, double &self);

				
  /**
   * @fn void updateCube( int index, LocalData & data, double & rho, double & lambda)
   * @brief Function used to update the cube values using index and the vectors' norms
   * @param index grid index value
   * @param data the Gradients
   * @param rho the previously calculated value of rho
   * @param lambda second lambda value */
  void updateCube( int index, LocalData & data, double & rho, double & lambda);

  /**
   * @fn void updateCubeFC( int index, LocalData & data)
   * @brief Function used to update the cube values with basis change using index and the vectors' norms
   * @param index = input = position of current point in the grid represented as a one dimension array
   * @param data = input = an object containing results like grad, gradIGM, ... but not rho */
   void
   updateCubeFC( int index, LocalData & data);
		
  /**
   * @fn void updateAtom( int i, LocalData & data)
   * @brief Function used to update the atom values using index and the vectors' norms
   * @param i Atom index value
   * @param data the previously calculated norms (cf Gradient) */
  void updateAtom( int i, LocalData & data);
		
  /**
   * @fn void update( int index, double rho, double value)
   * @brief Function used to update the values using a given value
   * @param index index value
   * @param rho the previously calculated value of rho
   * @param value value */
  void update( int index, double rho, double value = 0.0 );
		
  /**
   * @fn void sum()
   * @brief Function used to threads values together */
  void sum();
				
  /**
   * @fn void intermolecular(bool check, int pos)
   * @brief Function used to threads values together */
  void intermolecular(bool check, int pos);
				
  /********************************************************************/
  /**************************OUTPUT UTILITIES**************************/
  /********************************************************************/
		
  //! TO DOCUMENT
  static const int DGSIE=16;

  //! TO DOCUMENT
  static const int DKSIE=17;
		
  /**
   * @fn double get(int index, int type)
   * @brief Gets the indicated value and given index
   * @param index index of the value
   * @param type the type of value
   * @return the current type of value */
  double get(int index, int type);
				
  /**
   * @fn double* get(int type)
   * @brief Gets the indicated value
   * @param type : the type of value
   * @return the current type of value */
  double* get(int type);
				
  /**
   * @fn bool* getShouldPrint()
   * @brief Gets the indicated values of intermolecular checking
   * @return the current the values array */
  bool* getShouldPrint();

  /**
   * @fn double getsumdgInter()
   * @brief returns  the sumdgInter grid integration property
   * @return sumdgInter */
  double getsumdgInter();

  /**
   * @fn double getscoreInterac()
   * @brief returns  the scoreInterac grid integration property
   * @return scoreInterac */
  double getscoreInterac();

  /**
   * @fn void setsumdgInter(double *newvalue)
   * @brief Set the sumdgInter  grid integration property
   * @param newvalue The new value*/
  void setsumdgInter(double *newvalue);


  /**
   * @fn void setscoreInterac(double newvalue)
   * @brief Set the scoreInterac grid integration property*/
  void setscoreInterac(double newvalue);


}; // end of  C L A S S    R E S U L T S .....................................................

#endif
