double CCopasiSpringLayout::getPotential()
{
  //here we need to add the different effects that contribute to the potential

  double tmp = 0;

  //repulsion between species nodes
  unsigned int i, j;

  for (i = 0; i < mpLayout->getListOfMetaboliteGlyphs().size() - 1; ++i)
    for (j = i + 1; j < mpLayout->getListOfMetaboliteGlyphs().size(); ++j)
      {
        if (i != j)
          tmp += 100000 * potSpeciesSpecies(*mpLayout->getListOfMetaboliteGlyphs()[i], *mpLayout->getListOfMetaboliteGlyphs()[j]);
      }

  // only if we have reactions!
  if (mpLayout->getListOfReactionGlyphs().size() > 0)
    {
      //repulsion between species nodes and reaction nodes
      for (i = 0; i < mpLayout->getListOfMetaboliteGlyphs().size(); ++i)
        for (j = 0; j < mpLayout->getListOfReactionGlyphs().size(); ++j)
          {
            tmp += 100000 * potSpeciesReaction(*mpLayout->getListOfMetaboliteGlyphs()[i], *mpLayout->getListOfReactionGlyphs()[j]);
          }

      //repulsion between reaction nodes
      for (i = 0; i < mpLayout->getListOfReactionGlyphs().size() - 1; ++i)
        for (j = i + 1; j < mpLayout->getListOfReactionGlyphs().size(); ++j)
          {
            if (i != j)
              tmp += 100000 * potReactionReaction(*mpLayout->getListOfReactionGlyphs()[i], *mpLayout->getListOfReactionGlyphs()[j]);
          }
    }

  //spring force for species references
  for (i = 0; i < mpLayout->getListOfReactionGlyphs().size(); ++i)
    {
      CLReactionGlyph* pRG = mpLayout->getListOfReactionGlyphs()[i];

      for (j = 0; j < pRG->getListOfMetabReferenceGlyphs().size(); ++j)
        {
          tmp += 0.5 * potEdge(*pRG->getListOfMetabReferenceGlyphs()[j], *pRG);
        }
    }

  /*
      //forces at reaction nodes
      for (i=0; i<mReactionNodes.size(); ++i)
        {
          tmp += 3000* potReaction(mReactionNodes[i]);
        }
  */

  //force to keep species in compartment
  for (i = 0; i < mpLayout->getListOfMetaboliteGlyphs().size(); ++i)
    {
      CLMetabGlyph* tmpMG = mpLayout->getListOfMetaboliteGlyphs()[i];
      std::map<CLBase*, CLCompartmentGlyph*>::const_iterator mapIt = mCompartmentMap.find(tmpMG);

      if (mapIt == mCompartmentMap.end())
        {
          //there is no information in the map. Should not happen.
#ifdef COPASI_DEBUG
          std::cout << "No compartment info for a species glyph!!!" << std::endl;
#endif
          continue;
        }

      CLCompartmentGlyph* tmpCG = mapIt->second;

      if (tmpCG) //the species glyph is inside a compartment glyph
        tmp += 0.2 * potSpeciesCompartment(*tmpMG, *tmpCG);
    }

  //force to keep reaction nodes in compartment
  for (i = 0; i < mpLayout->getListOfReactionGlyphs().size(); ++i)
    {
      CLReactionGlyph* tmpRG = mpLayout->getListOfReactionGlyphs()[i];
      std::map<CLBase*, CLCompartmentGlyph*>::const_iterator mapIt = mCompartmentMap.find(tmpRG);

      if (mapIt == mCompartmentMap.end())
        {
          //there is no information in the map. Should not happen.
#ifdef COPASI_DEBUG
          std::cout << "No compartment info for a reaction glyph!!!" << std::endl;
#endif
          continue;
        }

      CLCompartmentGlyph* tmpCG = mapIt->second;

      if (tmpCG) //the reaction glyph is inside a compartment glyph
        tmp += 0.2 * potReactionCompartment(*tmpRG, *tmpCG);
    }

  /*

    //force to shrink compartments
    for (i=0; i<mCompartmentNodes.size(); ++i)
      {
        tmp += 0.2*(fabs(mCompartmentNodes[i].w-100)+fabs(mCompartmentNodes[i].h-100));
      }

    //repulsion between compartments
    for (i=0; i<mCompartmentNodes.size(); ++i)
    for (j=0; j<mCompartmentNodes.size(); ++j)
      {
        if (i!=j)
          tmp += 100*potCompartmentCompartment(mCompartmentNodes[i], mCompartmentNodes[j]);
      }

    //centering force
    for (i=0; i<mCompartmentNodes.size(); ++i)
      {
        tmp += 10*(fabs(mCompartmentNodes[i].x)+fabs(mCompartmentNodes[i].y));
      }
    */
  return tmp;
}
double CCopasiSpringLayout::getPotential()
{
  //here we need to add the different effects that contribute to the potential

  double tmp = 0;

  //repulsion between species nodes
  unsigned int i, j;

  for (i = 0; i < mpLayout->getListOfMetaboliteGlyphs().size() - 1; ++i)
    for (j = i + 1; j < mpLayout->getListOfMetaboliteGlyphs().size(); ++j)
      {
        if (i != j)
          tmp += mpPar->values[0] * potSpeciesSpecies(mpLayout->getListOfMetaboliteGlyphs()[i], mpLayout->getListOfMetaboliteGlyphs()[j]);
      }

  // only if we have reactions!
  if (mpLayout->getListOfReactionGlyphs().size() > 0)
    {
      //repulsion between species nodes and reaction nodes
      for (i = 0; i < mpLayout->getListOfMetaboliteGlyphs().size(); ++i)
        for (j = 0; j < mpLayout->getListOfReactionGlyphs().size(); ++j)
          {
            tmp += mpPar->values[0] * potSpeciesReaction(mpLayout->getListOfMetaboliteGlyphs()[i], mpLayout->getListOfReactionGlyphs()[j]);
          }

      //repulsion between reaction nodes
      for (i = 0; i < mpLayout->getListOfReactionGlyphs().size() - 1; ++i)
        for (j = i + 1; j < mpLayout->getListOfReactionGlyphs().size(); ++j)
          {
            if (i != j)
              tmp += mpPar->values[0] * potReactionReaction(mpLayout->getListOfReactionGlyphs()[i], mpLayout->getListOfReactionGlyphs()[j]);
          }
    }

  //spring force for species references
  for (i = 0; i < mpLayout->getListOfReactionGlyphs().size(); ++i)
    {
      CLReactionGlyph* pRG = &mpLayout->getListOfReactionGlyphs()[i];

      for (j = 0; j < pRG->getListOfMetabReferenceGlyphs().size(); ++j)
        {
          tmp += potEdge(pRG->getListOfMetabReferenceGlyphs()[j], *pRG);

          //second order
          CLMetabReferenceGlyph::Role role = pRG->getListOfMetabReferenceGlyphs()[j].getFunctionalRole();

          if (role != CLMetabReferenceGlyph::SUBSTRATE && role != CLMetabReferenceGlyph::SIDESUBSTRATE)
            continue;

          double dist = role == CLMetabReferenceGlyph::SUBSTRATE ? mpPar->values[1] : mpPar->values[3];
          size_t k;

          for (k = 0; k < pRG->getListOfMetabReferenceGlyphs().size(); ++k)
            {
              CLMetabReferenceGlyph::Role role2 = pRG->getListOfMetabReferenceGlyphs()[k].getFunctionalRole();

              if (role2 != CLMetabReferenceGlyph::PRODUCT && role2 != CLMetabReferenceGlyph::SIDEPRODUCT)
                continue;

              dist += role2 == CLMetabReferenceGlyph::PRODUCT ? mpPar->values[1] : mpPar->values[3];

              tmp += mpPar->values[5] * potSecondOrderEdge(pRG->getListOfMetabReferenceGlyphs()[j], pRG->getListOfMetabReferenceGlyphs()[k], dist);
            }
        }
    }

  for (i = 0; i < mpLayout->getListOfGeneralGlyphs().size(); ++i)
    {
      CLGeneralGlyph* pRG = &mpLayout->getListOfGeneralGlyphs()[i];

      for (j = 0; j < pRG->getListOfReferenceGlyphs().size(); ++j)
        {
          tmp += potGeneralEdge(pRG->getListOfReferenceGlyphs()[j], *pRG);
        }
    }

  /*
      //forces at reaction nodes
      for (i=0; i<mReactionNodes.size(); ++i)
        {
          tmp += 3000* potReaction(mReactionNodes[i]);
        }
  */

  //force to keep species in compartment
  for (i = 0; i < mpLayout->getListOfMetaboliteGlyphs().size(); ++i)
    {
      CLMetabGlyph* tmpMG = &mpLayout->getListOfMetaboliteGlyphs()[i];
      std::map<CLBase*, CLCompartmentGlyph*>::const_iterator mapIt = mCompartmentMap.find(tmpMG);

      if (mapIt == mCompartmentMap.end())
        {
          //there is no information in the map. Should not happen.
#ifdef COPASI_DEBUG
          std::cout << "No compartment info for a species glyph!!!" << std::endl;
#endif
          continue;
        }

      CLCompartmentGlyph* tmpCG = mapIt->second;

      if (tmpCG) //the species glyph is inside a compartment glyph
        tmp +=  mpPar->values[6] * potSpeciesCompartment(*tmpMG, *tmpCG);
    }

  //force to keep reaction nodes in compartment
  for (i = 0; i < mpLayout->getListOfReactionGlyphs().size(); ++i)
    {
      CLReactionGlyph* tmpRG = &mpLayout->getListOfReactionGlyphs()[i];
      std::map<CLBase*, CLCompartmentGlyph*>::const_iterator mapIt = mCompartmentMap.find(tmpRG);

      if (mapIt == mCompartmentMap.end())
        {
          //there is no information in the map. Should not happen.
#ifdef COPASI_DEBUG
          std::cout << "No compartment info for a reaction glyph!!!" << std::endl;
#endif
          continue;
        }

      CLCompartmentGlyph* tmpCG = mapIt->second;

      if (tmpCG) //the reaction glyph is inside a compartment glyph
        tmp += mpPar->values[7] * potReactionCompartment(*tmpRG, *tmpCG);
    }

  /*

    //force to shrink compartments
    for (i=0; i<mCompartmentNodes.size(); ++i)
      {
        tmp += 0.2*(fabs(mCompartmentNodes[i].w-100)+fabs(mCompartmentNodes[i].h-100));
      }

    //repulsion between compartments
    for (i=0; i<mCompartmentNodes.size(); ++i)
    for (j=0; j<mCompartmentNodes.size(); ++j)
      {
        if (i!=j)
          tmp += 100*potCompartmentCompartment(mCompartmentNodes[i], mCompartmentNodes[j]);
      }

    //centering force
    for (i=0; i<mCompartmentNodes.size(); ++i)
      {
        tmp += 10*(fabs(mCompartmentNodes[i].x)+fabs(mCompartmentNodes[i].y));
      }
    */
  return tmp;
}