#include "Element_Aura.h"
namespace MFM {


  /*********************************************
   * Grow: myLoc/possibleLoc absolute X,Y to core
   *       possiblePt relative X,y to eventwindow
   *********************************************/
  template<class CC>
  void Element_Tumor<CC>::Grow(EventWindow<CC>& window) const{
    const T us = window.GetCenterAtom();
    MDist<R>& md = MDist<R>::get();

    SPoint myLoc;

    SPoint possiblePt;
    SPoint newLoc;

    s8 possibleX = 0;
    s8 possibleY = 0;

    FillLoc(myLoc,us);

    for(u32 i = md.GetFirstIndex(1); i <= md.GetLastIndex(2); i++)
    {
      possiblePt=md.GetPoint(i);
      if (!window.IsLiveSite(possiblePt))
      {
	continue;
      }
      T other = window.GetRelativeAtom(possiblePt);
      u32 type = other.GetType();
      possibleX = possiblePt.GetX();
      possibleY = possiblePt.GetY();
      //LOG.Debug("x(%d)y(%d)",possibleX,possibleY);
      if (((possibleX<=1) && (possibleX>=-1)) &&
	  ((possibleY<=1) && (possibleY>=-1)))
      {
	if(type == Element_Empty<CC>::THE_INSTANCE.GetType())
	  //  ||
	  //(type == Element_Aura<CC>::THE_INSTANCE.GetType()))
	{
	  T tumor = Element_Tumor<CC>::THE_INSTANCE.GetDefaultAtom();
	  Element_Tumor<CC>::THE_INSTANCE.SetRadius(tumor,GetRadius(us));
	  Element_Tumor<CC>::THE_INSTANCE.SetLayer(tumor, GetLayer(us)+1);
	  newLoc.Set(myLoc.GetX()+possibleX,myLoc.GetY()+possibleY);
	  Element_Tumor<CC>::THE_INSTANCE.SetLoc(tumor, newLoc);
	  Element_Tumor<CC>::THE_INSTANCE.SetIDLabel(tumor, GetIDLabel(us));
	  Element_Tumor<CC>::THE_INSTANCE.SetTimer(tumor, GetTimer(us));
	  window.SetRelativeAtom(possiblePt, tumor);
	  continue;
	}
      }
    }//endFor
  }

  template<class CC>
  void Element_Tumor<CC>::EmitAura(EventWindow<CC>& window) const{
    Random & random = window.GetRandom();
    u16 randomID = random.Between(1,60000);
    SPoint dir;
    MDist<R>::get().FillRandomSingleDir(dir, random);

    if (window.IsLiveSite(dir))
    {
      T atom = window.GetRelativeAtom(dir);
      u32 oldType = atom.GetType();

      if(Element_Empty<CC>::THE_INSTANCE.IsType(oldType))
      {
	if(random.OddsOf(m_auraDense.GetValue()*10,100))
        {
	  atom = Element_Aura<CC>::THE_INSTANCE.GetDefaultAtom();
	  Element_Aura<CC>::THE_INSTANCE.SetDense(atom, 0);
	  Element_Aura<CC>::THE_INSTANCE.SetID(atom, randomID);
	  Element_Aura<CC>::THE_INSTANCE.SetLife(atom, m_auraLife.GetValue());
	}
      }
      if(atom.GetType() != oldType)
      {
	window.SetRelativeAtom(dir, atom);
      }
    }
  }
}
