#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "charm++.h"
#include "util.h"
#include "jacobi.h"
#include "main.h"

int M; // readonly variable. All global variables must be readonly. 

main::main(CkArgMsg *m)
{ 
  int i;
  M = 5;
  A = CProxy_jacobi::ckNew(M); // 1-D decomposition: array of 5 cells
  for (i=0; i<M; i++) {
    CProxy_jacobi B(A);
    B[i].run(new DataMsg);
  }
  CkStartQD(EntryIndex(main,allDone,CkQdMsg), &thishandle);
  CkPrintf("main done\n");
};

void main::allDone(CkQdMsg *m)
{
  CkPrintf("Quiescence detected. stopping\n");
  CkExit();
};

/*
void jacobi::borderValues(DataMsg *m)
{
 CkPrintf("[%d] A[%d]: received message from nbr\n", CkMyPe(), thisIndex);

 copyBorder(data, (double *) &(m->b), m->fromLeft);

 if ((0 == --count)  && (++iterations < 3))
   {
     nextIteration(data);

     count = 2;
     sendToNeighbors();
   }
};
*/

void
jacobi::doCalc(DataMsg *m1, DataMsg *m2)
{
  copyBorder(data, (double *) &(m1->b), m1->fromLeft);
  copyBorder(data, (double *) &(m2->b), m2->fromLeft);
  nextIteration(data);
  sendToNeighbors();
}

void
jacobi::sendToNeighbors(void)
{
 CkPrintf("[%d] A[%d]: sending to %d and %d\n", CkMyPe(), thisIndex,
	   (thisIndex+1)%M, (M+thisIndex-1)%M );
 CProxy_jacobi B(thisAID);

 DataMsg * d = new DataMsg;
 d->fromLeft = 0;
 fillBorder(data,  (double *) &(d->b), d->fromLeft);
 B[(thisIndex-1+M)%M].borderValues(d);

 d = new DataMsg;
 fillBorder(data, (double *)&(d->b), d->fromLeft);
 d->fromLeft = 1;
 B[(thisIndex+1)%M].borderValues(d);

};

#include "main.def.h"

