/*************************************************************************
 *    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 "ViscosityPlugin.h"

#include "ViscosityEnergy.h"

#include <CompuCell3D/Simulator.h>
#include <CompuCell3D/Automaton/Automaton.h>
using namespace CompuCell3D;

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

#include <BasicUtils/BasicString.h>
#include <BasicUtils/BasicException.h>
#include <CompuCell3D/plugins/CellVelocity/CellVelocityPlugin.h>
#include <CompuCell3D/plugins/NeighborTracker/NeighborTrackerPlugin.h>




ViscosityPlugin::ViscosityPlugin() : viscosityEnergy(0) {
}

ViscosityPlugin::~ViscosityPlugin() {
  if (viscosityEnergy) delete viscosityEnergy;
}

void ViscosityPlugin::init(Simulator *simulator) {
  viscosityEnergy = new ViscosityEnergy(simulator->getPotts());
  simulator->getPotts()->registerEnergyFunction(viscosityEnergy);
  viscosityEnergy->setSimulator(simulator);
}


void ViscosityPlugin::extraInit(Simulator *simulator) {
   CellVelocityPlugin * cellVelocityPluginPtr=(CellVelocityPlugin*)(Simulator::pluginManager.get("CellInstantVelocity"));
   ASSERT_OR_THROW("CellVelocity plugin not initialized!", cellVelocityPluginPtr);
   ASSERT_OR_THROW("CellVelocityAccessorPtr  not initialized!", cellVelocityPluginPtr->getCellVelocityDataAccessorPtr());
   ASSERT_OR_THROW("CellVelocityData: cldeque tas too small size - size=2 or greater needed!",
    cellVelocityPluginPtr->getCldequeCapacity()>=2);
    
   viscosityEnergy->setCellVelocityDataAccessorPtr(cellVelocityPluginPtr->getCellVelocityDataAccessorPtr());
    
   CenterOfMassPlugin * centerOfMassPluginPtr=(CenterOfMassPlugin*)(Simulator::pluginManager.get("CenterOfMass"));
   ASSERT_OR_THROW("CenterOfMass plugin not initialized!", centerOfMassPluginPtr);

     
   viscosityEnergy->setCOMPtr(centerOfMassPluginPtr);

   NeighborTrackerPlugin * neighborTrackerPluginPtr=(NeighborTrackerPlugin*)(Simulator::pluginManager.get("NeighborTracker"));
   ASSERT_OR_THROW("NeighborTracker plugin not initialized!", neighborTrackerPluginPtr);
   ASSERT_OR_THROW("neighborAccessorPtr  not initialized!", neighborTrackerPluginPtr->getNeighborTrackerAccessorPtr());
   
   viscosityEnergy->setNeighborTrackerAccessorPtr(neighborTrackerPluginPtr->getNeighborTrackerAccessorPtr());
   viscosityEnergy->initializeViscosityEnergy();
}


void ViscosityPlugin::readXML(XMLPullParser &in) {
  ASSERT_OR_THROW("Viscosity plugin not initialized!", viscosityEnergy);
  viscosityEnergy->readXML(in);
}

void ViscosityPlugin::writeXML(XMLSerializer &out) {
  ASSERT_OR_THROW("Viscosity plugin not initialized!", viscosityEnergy);
  viscosityEnergy->writeXML(out);
}
