/*************************************************************************
 *    CompuCell - A software framework for multimodel simulations of     *
 * biocomplexity problems Copyright (C) 2003 University of Notre Dame,   *
 *                             Indiana                                   *
 *                                                                       *
 * This program is free software; IF YOU AGREE TO CITE USE OF CompuCell  *
 *  IN ALL RELATED RESEARCH PUBLICATIONS according to the terms of the   *
 *  CompuCell GNU General Public License RIDER you can redistribute it   *
 * and/or modify it under the terms of the GNU General Public License as *
 *  published by the Free Software Foundation; either version 2 of the   *
 *         License, or (at your option) any later version.               *
 *                                                                       *
 * This program is distributed in the hope that it will be useful, but   *
 *      WITHOUT ANY WARRANTY; without even the implied warranty of       *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    *
 *             General Public License for more details.                  *
 *                                                                       *
 *  You should have received a copy of the GNU General Public License    *
 *     along with this program; if not, write to the Free Software       *
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.        *
 *************************************************************************/

#include "VolumeEnergy.h"

#include <CompuCell3D/Potts3D/Potts3D.h>
using namespace CompuCell3D;

#include <XMLCereal/XMLPullParser.h>
#include <XMLCereal/XMLSerializer.h>

#include <BasicUtils/BasicString.h>
#include <BasicUtils/BasicException.h>

#include <string>
using namespace std;

double VolumeEnergy::localEnergy(const Point3D &pt) {
  return 0;
}

double VolumeEnergy::changeEnergy(const Point3D &pt,
				  const CellG *newCell,
				  const CellG *oldCell) {

  /// E = lambda * (volume - targetVolume) ^ 2 
  
  
  
//  cellAccessor->getClass(newCell);
  double energy = 0;

  if (oldCell == newCell) return 0;
    
//   if (newCell)
//     energy += lambdaVolume *
//       (1 + 2 * ((int)newCell->volume - newCell->targetVolume));
// 
//   if (oldCell)
//     energy += lambdaVolume *
//       (1 - 2 * ((int)oldCell->volume - oldCell->targetVolume));

   //as in the original version 
  if (newCell)
    energy += lambdaVolume *
      (1 + 2 * ((int)newCell->volume - (int)targetVolume));

  if (oldCell)
    energy += lambdaVolume *
      (1 - 2 * ((int)oldCell->volume - (int)targetVolume));

      
//    cout<<"VOLUME CHANGE ENERGY NEW: "<<energy<<endl;
  return energy;
}


void VolumeEnergy::readXML(XMLPullParser &in) {
  in.skip(TEXT);

  while (in.check(START_ELEMENT)) {
    if (in.getName() == "TargetVolume") {
      targetVolume = BasicString::parseUInteger(in.matchSimple());

    } else if (in.getName() == "LambdaVolume") {
      lambdaVolume = BasicString::parseDouble(in.matchSimple());

    } else {
      throw BasicException(string("Unexpected element '") + in.getName() + 
			   "'!", in.getLocation());
    }

    in.skip(TEXT);
  }  
}

void VolumeEnergy::writeXML(XMLSerializer &out) {
}

std::string VolumeEnergy::toString(){
   return string("Volume");
}