#include "Bdef.h"

int Ssring_br(ctxt, scope, rsrc, csrc)
BLACSCONTEXT  *ctxt;
char  scope;
int  rsrc;
int  csrc;
{
   void Ssend2d00();
   void Srecv2d00();

   int mydist;  	/* my distance from source */
   int Ng, nprow, npcol, myrow, mycol;
   int rightedge, rdest, cdest, vsrc;
   int msgid;
   int info, rbufid;

   Mgridinfo(ctxt, Ng, nprow, npcol, myrow, mycol);
   scope = Mlowcase(scope);
   switch(scope)
   {
   case 'r':
      msgid = Mrid(ctxt);
      mydist = (npcol + mycol - csrc) % npcol;
      rightedge = npcol/2;
      Srecv2d00(ctxt, msgid);
/*
    *    Free send buffer, send from receive buff
 */
      rbufid = pvm_getrbuf();
      info = pvm_freebuf(pvm_setsbuf(rbufid));
      Mpvmerror(info, "pvm_freebuf", __LINE__, __FILE__);

      if (mydist < rightedge)   /* between source & right edge of split ring */
         Ssend2d00(ctxt, myrow, (mycol+1)%npcol, msgid);
      else if (mydist > rightedge+1) /* between source and leftedge */
         Ssend2d00(ctxt, myrow, (npcol+mycol-1)%npcol, msgid);
      break;

   case 'c':

      msgid = Mcid(ctxt);
      mydist = (nprow + myrow - rsrc) % nprow; /* distance from source */
      rightedge = nprow/2;
      Srecv2d00(ctxt, msgid);
/*
    *    Free send buffer, send from receive buff
 */
      rbufid = pvm_getrbuf();
      info = pvm_freebuf(pvm_setsbuf(rbufid));
      Mpvmerror(info, "pvm_freebuf", __LINE__, __FILE__);

      if (mydist < rightedge)	/* between source & right edge of split ring */
         Ssend2d00(ctxt, (myrow+1)%nprow, mycol, msgid);
      else if (mydist > rightedge+1) /* between source and leftedge */
         Ssend2d00(ctxt, (nprow+myrow-1)%nprow, mycol, msgid);
      break;

   case 'a':

      vsrc = Mvkpnum(ctxt, rsrc, csrc);
      msgid = Maid(ctxt);
      mydist = (Ng + ctxt->vIam - vsrc) % Ng; /* distance from source */
      rightedge = Ng/2;

      Srecv2d00(ctxt, msgid);
/*
    *    Free send buffer, send from receive buff
 */
      rbufid = pvm_getrbuf();
      info = pvm_freebuf(pvm_setsbuf(rbufid));
      Mpvmerror(info, "pvm_freebuf", __LINE__, __FILE__);

      if (mydist < rightedge)	/* between source & right edge of split ring */
      {
	 Mvpcoord(ctxt, (ctxt->vIam+1)%Ng, rdest, cdest);
         Ssend2d00(ctxt,  rdest, cdest, msgid);
      }
      else if (mydist > rightedge+1) /* between source and leftedge */
      {
	 Mvpcoord(ctxt, (Ng+ctxt->vIam-1)%Ng, rdest, cdest);
         Ssend2d00(ctxt,  rdest, cdest, msgid);
      }
      break;

   default:
      return(BADSCP);
   }
   pvm_setrbuf(rbufid);  /* restore buffer state */
   return(0);
}
