#include "mpi.h"
#include "mpe.h"
#include "pmandel.h"


















DefineMPITypes()
{
  Winspecs winspecs;
  Flags flags;
  rect rectangle;
  
  int len[3], disp[3];
  MPI_Datatype types[3];
  
  NUM_type = MPI_DOUBLE;
  
  MPI_Type_contiguous(6, MPI_INT, &winspecs_type);
  MPI_Type_commit(&winspecs_type);
  
  len[0] = 10;
  len[1] = 2;
  len[2] = 6;
  disp[0] = (int) ((char *) (&(flags.breakout)) - (char *) (&(flags)));
  disp[1] = (int) ((char *) (&(flags.boundary_sq)) - (char *) (&(flags)));
  disp[2] = (int) ((char *) (&(flags.rmin)) - (char *) (&(flags)));
  types[0] = MPI_INT;
  types[1] = MPI_DOUBLE;
  types[2] = NUM_type;
  MPI_Type_struct(3, len, disp, types, &flags_type);
  MPI_Type_commit(&flags_type);
  
  len[0] = 5;
  disp[0] = (int) ((char *) (&(rectangle.l)) - (char *) (&(rectangle)));
  types[0] = MPI_INT;
  MPI_Type_struct(1, len, disp, types, &rect_type);
  MPI_Type_commit(&rect_type);
  
  return 0;
}


GetDefaultWinspecs(winspecs)
Winspecs *winspecs;
{
  winspecs->height = DEF_height;
  winspecs->width = DEF_width;
  winspecs->bw = DEF_bw;
  winspecs->xpos = DEF_xpos;
  winspecs->ypos = DEF_ypos;
  winspecs->numColors = DEF_numColors;
  
  return 0;
}
GetDefaultFlags(winspecs, flags)
Winspecs *winspecs;
Flags *flags;
{
  flags->logfile = DEF_logfile;
  flags->inf = DEF_inf;
  flags->outf = DEF_outf;
  flags->winspecs = winspecs;
  flags->breakout = DEF_breakout;
  flags->randomize = DEF_randomize;
  flags->colReduceFactor = DEF_colReduceFactor;
  flags->loop = DEF_loop;
  flags->zoom = DEF_zoom;
  flags->askNeighbor = DEF_askNeighbor;
  flags->sendMasterComplexity = DEF_sendMasterComplexity;
  flags->drawBlockRegion = DEF_drawBlockRegion;
  flags->fractal = DEF_fractal;
  flags->maxiter = DEF_maxiter;
  flags->boundary_sq = DEF_boundary * DEF_boundary;
  flags->epsilon = DEF_epsilon;
  NUM_ASSIGN(flags->rmin, DEF_rmin);
  NUM_ASSIGN(flags->rmax, DEF_rmax);
  NUM_ASSIGN(flags->imin, DEF_imin);
  NUM_ASSIGN(flags->imax, DEF_imax);
  NUM_ASSIGN(flags->julia_r, DEF_julia_r);
  NUM_ASSIGN(flags->julia_i, DEF_julia_i);
  
  return 0;
}
GetWinspecs(argc, argv, winspecs)
int *argc;
char **argv;
Winspecs *winspecs;
{
  int myid;
  
  MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  
  if (!myid) {
    GetIntArg(argc, argv, "-height", &(winspecs->height));
    GetIntArg(argc, argv, "-width", &(winspecs->width));
    winspecs->bw = IsArgPresent(argc, argv, "-bw");
    GetIntArg(argc, argv, "-xpos", &(winspecs->xpos));
    GetIntArg(argc, argv, "-ypos", &(winspecs->ypos));
    GetIntArg(argc, argv, "-colors", &(winspecs->numColors));
  }
  
  MPI_Bcast(winspecs, 1, winspecs_type, 0, MPI_COMM_WORLD);
  
  
  
  return 0;
}
GetFlags(argc, argv, winspecs, flags)
int *argc;
char **argv;
Winspecs *winspecs;
Flags *flags;
{
  double x, y;
  int myid, strLens[3];
  
  MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  
  if (!myid) {
    GetStringArg(argc, argv, "-l", &(flags->logfile));
    GetStringArg(argc, argv, "-i", &(flags->inf));
    GetStringArg(argc, argv, "-o", &(flags->outf));
    GetIntArg(argc, argv, "-breakout", &(flags->breakout));
    if (IsArgPresent(argc, argv, "-randomize")) {
      flags->randomize = 0;
    }
    if (IsArgPresent(argc, argv, "+randomize")) {
      flags->randomize = 1;
    }
    GetIntArg(argc, argv, "-colreduce", &(flags->colReduceFactor));
    flags->loop = IsArgPresent(argc, argv, "-loop");
    if (IsArgPresent(argc, argv, "-zoom")) {
      flags->zoom = 0;
    }
    if (IsArgPresent(argc, argv, "+zoom")) {
      flags->zoom = 1;
    }
    flags->askNeighbor = IsArgPresent(argc, argv, "-neighbor");
    flags->sendMasterComplexity = IsArgPresent(argc, argv, "-complexity");
    flags->drawBlockRegion = IsArgPresent(argc, argv, "-delaydraw");
    
    if (IsArgPresent(argc, argv, "-mandel")) {
      flags->fractal = MBROT;
    } else if (IsArgPresent(argc, argv, "-julia")) {
      flags->fractal = JULIA;
    } else if (IsArgPresent(argc, argv, "-newton")) {
      flags->fractal = NEWTON;
    }
    GetIntArg(argc, argv, "-maxiter", &(flags->maxiter));
    if (GetDoubleArg(argc, argv, "-boundary", &x)) {
      flags->boundary_sq = x * x;
    }
    GetDoubleArg(argc, argv, "-epsilon", &(flags->epsilon));
    if (GetDoubleArg(argc, argv, "-rmin", &x)) {
      NUM_ASSIGN(flags->rmin, DBL2NUM(x));
    }
    if (GetDoubleArg(argc, argv, "-rmax", &x)) {
      NUM_ASSIGN(flags->rmax, DBL2NUM(x));
    }
    if (GetDoubleArg(argc, argv, "-imin", &x)) {
      NUM_ASSIGN(flags->imin, DBL2NUM(x));
    }
    if (GetDoubleArg(argc, argv, "-imax", &x)) {
      NUM_ASSIGN(flags->imax, DBL2NUM(x));
    }
    if (GetDoubleArg(argc, argv, "-radius", &x)) {
      if (GetDoubleArg(argc, argv, "-rcenter", &y)) {
	NUM_ASSIGN(flags->rmin, DBL2NUM(y - x));
	NUM_ASSIGN(flags->rmax, DBL2NUM(y + x));
      }
      if (GetDoubleArg(argc, argv, "-icenter", &y)) {
	NUM_ASSIGN(flags->imin, DBL2NUM(y - x));
	NUM_ASSIGN(flags->imax, DBL2NUM(y + x));
      }
    }
    strLens[0] = (flags->logfile) ? strlen(flags->logfile) + 1 : 0;
    strLens[1] = (flags->inf) ? strlen(flags->inf) + 1 : 0;
    strLens[2] = (flags->outf) ? strlen(flags->outf) + 1 : 0;
  }
  MPI_Bcast(flags, 1, flags_type, 0, MPI_COMM_WORLD);
  
  MPI_Bcast(strLens, 3, MPI_INT, 0, MPI_COMM_WORLD);
  if (myid != 0) {
    flags->logfile = (strLens[0]) ?
      (char *) malloc(strLens[0] * sizeof(char)) : 0;
    flags->inf = (strLens[1]) ?
      (char *) malloc(strLens[1] * sizeof(char)) : 0;
    flags->outf = (strLens[2]) ?
      (char *) malloc(strLens[2] * sizeof(char)) : 0;
  }
  if (strLens[0])
    MPI_Bcast(flags->logfile, strLens[0], MPI_CHAR, 0, MPI_COMM_WORLD);
  if (strLens[1])
    MPI_Bcast(flags->inf, strLens[1], MPI_CHAR, 0, MPI_COMM_WORLD);
  if (strLens[2])
    MPI_Bcast(flags->outf, strLens[2], MPI_CHAR, 0, MPI_COMM_WORLD);
  
  
  return 0;
}



Pixel2Complex(flags, x, y, nx, ny)
Flags *flags;
int x, y;
NUM *nx, *ny;
{
  NUM_PTR_ASSIGN(
		 nx,
		 NUM_ADD(
			 NUM_MULT(
				  DBL2NUM((double) x / flags->winspecs->width),
				  NUM_SUB(flags->rmax, flags->rmin)),
			 flags->rmin)
		 );
  
  NUM_PTR_ASSIGN(
		 ny,
		 NUM_ADD(
			 NUM_MULT(
				  DBL2NUM((double) y / flags->winspecs->height),
				  NUM_SUB(flags->imin, flags->imax)),
			 flags->imax)
		 );
  
  
  
  
  
  
  
  
  
  return 0;
}


StrContainsNonWhiteSpace(str)
char *str;
{
  while (*str) {
    if (!isspace(*str))
      return 1;
    str++;
  }
  return 0;
}





void Q_Create(q, randomize)
rect_queue *q;
int randomize;
{
  q->head = q->tail = 0;
  q->size = 100;
  q->r = (rect *) malloc(q->size * sizeof(rect));
  q->randomPt = 1;
  q->randomize = randomize;
}



void Q_Checksize(q)
rect_queue *q;
{
  if (q->head == q->tail + 1 ||
      !q->head && q->tail == q->size - 1) {
    
    q->r = (rect *) realloc(q->r, sizeof(rect) * q->size * 2);
    
    if (q->tail < q->head) {
      memcpy(q->r + q->size, q->r, q->tail * sizeof(rect));
      
      q->tail += q->size;
    }
    if (q->randomize && q->randomPt < q->head) {
      q->randomPt += q->size;
    }
    q->size *= 2;
  }
}


Q_Print(q)
rect_queue *q;
{
  int i;
  i = q->head;
  while (i != q->tail) {
    fprintf(debug_file, "queue[%d] = (%d %d %d %d)\n", i, q->r[i].l, q->r[i].r,
	    q->r[i].t, q->r[i].b);
    i++;
    if (i == q->size)
      i = 0;
  }
}


Q_CheckValidity(q)
rect_queue *q;
{
  int i;
  i = q->head;
  while (i != q->tail) {
    if (q->r[i].l > 10000 ||
	q->r[i].r > 10000 ||
	q->r[i].t > 10000 ||
	q->r[i].b > 10000 ||
	q->r[i].length > 10000) {
      fprintf(debug_file, "Error in queue[%d]: (%d %d %d %d %d)\n",
	      i, q->r[i].l, q->r[i].r, q->r[i].t, q->r[i].b, q->r[i].length);
    }
    if (++i == q->size)
      i = 0;
  }
  return 0;
}



void Q_Enqueue(q, r)
rect_queue *q;
rect *r;
{
  
  Q_Checksize(q);
  q->r[q->tail] = *r;
  
  if (++q->tail == q->size)
    q->tail = 0;
  
  
}


void Q_Dequeue(q, r)
rect_queue *q;
rect *r;
{
  
  *r = q->r[q->head];
  
  if (++q->head == q->size)
    q->head = 0;
  if (q->randomize && ((q->head == q->randomPt) ||
		       (q->head == q->randomPt + 1))) {
    int i, j, numItems;
    rect temp;
    numItems = (q->tail < q->head)
      ? q->size - q->head + q->tail
	: q->tail - q->head;
    for (i = q->head; i != q->tail; i++) {
      j = random() % numItems + q->head;
      if (j >= q->size)
	j -= q->size;
      temp = q->r[j];
      q->r[j] = q->r[i];
      q->r[i] = temp;
      if (i == q->size - 1) {
	i = -1;
      }
    }
    q->randomPt = q->tail;
  }
  
  
}




int RectBorderLen(r)
rect *r;
{
  return (r->r - r->l) ?
    (r->b - r->t) ?
      (2 * (r->r - r->l + r->b - r->t))
	:
	  (r->r - r->l + 1)
	    :
	      (r->b - r->t) ?
		(r->b - r->t + 1)
		  :
		    1;
}


PrintHelp(progName)
char *progName;
{
  printf("Options recognized by %s:\n", progName);
  printf("(defaults are in parentheses () )\n");
  
  
  
  printf("   -i <filename>              (none) input file\n");
  
  printf("   -xpos <xpos>               (%d) window horizontal coordinate\n",
	 DEF_xpos);
  printf("   -ypos <xpos>               (%d) window vertical coordinate\n",
	 DEF_ypos);
  printf("   -width <width>             (%d) width of computed area in points\n", DEF_width);
  printf("   -height <height>           (%d) height of computed area in points\n", DEF_height);
  printf("   -boundary <boundary>       (%.1lf) boundary value for M-set computation\n", DEF_boundary);
  printf("   -maxiter <max. iter>       (%d) maximum # of iterations for M-set\n", DEF_maxiter);
  printf("                              compuptation algorithm\n");
  printf("   -rmin <real min.>          (%.2lf) minimum real coordinate of computed area\n", DEF_rmin);
  printf("   -rmax <real max.>          (%.2lf) maximum real coordinate of computed area\n", DEF_rmax);
  printf("   -imin <imag. min.>         (%.2lf) minimum imaginary coordinate of computed\n", DEF_imin);
  printf("                              area\n");
  printf("   -imax <imag. max.>         (%.2lf) maximum imaginary coordinate of computed\n", DEF_imax);
  printf("                              area\n");
  printf("\n");
  printf("      alternate form: (if specified, overrides <r|i><min|max>)\n");
  printf("   -rcenter <real center>     (%.2lf) center real coordinate of computed area\n", (DEF_rmin + DEF_rmax) / 2);
  printf("   -icenter <imag. center>    (%.2lf) center imaginary coordinate of computed\n", (DEF_imin + DEF_imax) / 2);
  printf("                              area\n");
  printf("   -radius <area radius>      (%.2lf) radius of the computed area\n", (DEF_rmax - DEF_rmin));
  printf("\n");
  printf("   -breakout <breakout size>  (%d) maximum length or width rectangle to\n", DEF_breakout);
  printf("                              subdivide\n");
  printf("   -colors <# of colors>      (%d) number of colors to request\n", DEF_numColors);
  printf("   -colreduce <reduce factor> (%d) factor by which to scale down iteration\n", DEF_colReduceFactor);
  printf("                              values to reduce color changes\n");
  printf("   <+,->randomize             (%sset) (on,off) compute regions in as random of\n",
	 DEF_randomize ? "" : "not ");
  printf("                              order as possible\n");
  
  
  
  
  printf("   -bw                        (%sset) draw in black and white instead of\n", DEF_bw ? "" : "not ");
  printf("                              color\n");
  exit(0);
}


MPE_Color Iter2Color(flags, iter)
Flags *flags;
int iter;
{
  if (flags->winspecs->bw) {
    return ((iter == flags->maxiter) ? MPE_BLACK :
	    ((iter / flags->colReduceFactor) % 2) ? MPE_WHITE : MPE_BLACK);
  } else {
    if (iter == flags->maxiter) {
      return MPE_BLACK;
    } else {
      return flags->winspecs->colorArray[(iter / flags->colReduceFactor) %
					 flags->winspecs->numColors];
    }
  }
}


ChunkIter2Color(flags, iterData, colorData, size)
Flags *flags;
int *iterData, size;
int *colorData;
{
  int i;
  
  for (i = 0; i < size; i++) {
    *colorData = Iter2Color(flags, *iterData);
    
    colorData++;
    iterData++;
  }
}




ComputeChunk(flags, r, pointData, iterData, maxnpoints, npoints)
Flags *flags;
rect *r;
int *iterData, maxnpoints, *npoints;
MPE_Point *pointData;
{
  int i, x, y;
  
  CalcField(flags->fractal, iterData, r->l, r->r, r->t, r->b);
  
  
  *npoints = (r->r - r->l + 1) * (r->b - r->t + 1);
  x = r->l;
  y = r->t;
  for (i = 0; i < *npoints; i++) {
    pointData[i].x = x++;
    pointData[i].y = y;
    pointData[i].c = Iter2Color(flags, iterData[i]);
    
    if (x > r->r) {
      x = r->l;
      y++;
    }
  }
  return 0;
}



DrawChunk(graph, colorData, r)
MPE_XGraph graph;
int *colorData;
rect r;
{
  int a, b;
  
  for (b = r.t; b <= r.b; b++) {
    for (a = r.l; a <= r.r; a++) {
      MPE_Draw_point(graph, a, b, *colorData);
      
      colorData++;
    }
  }
  MPE_Update(graph);
  return 0;
}



























































































int ComputeBorder(winspecs, flags, rectPtr, pointData, maxnpoints,
		  npoints, isContinuous)
Winspecs *winspecs;
Flags *flags;
rect *rectPtr;
MPE_Point *pointData;
int maxnpoints, *npoints, *isContinuous;
{
  register NUM re, im, rstep, istep;
  register int x, y;
  register MPE_Point *pointPtr;
  register MPE_Color firstColor;
  rect r;
  
  r = *rectPtr;
  
  
  
  NUM_ASSIGN(re, COORD2CMPLX(flags->rmin, flags->rmax, 0,
			     winspecs->width - 1, r.l));
  NUM_ASSIGN(im, COORD2CMPLX(flags->imax, flags->imin, 0,
			     winspecs->height - 1, r.t));
  NUM_ASSIGN(rstep, NUM_DIV(NUM_SUB(flags->rmax, flags->rmin),
			    INT2NUM(winspecs->width - 1)));
  NUM_ASSIGN(istep, NUM_DIV(NUM_SUB(flags->imin, flags->imax),
			    INT2NUM(winspecs->height - 1)));
  
  pointPtr = pointData + 1;
  pointData->x = r.l;
  pointData->y = r.t;
  pointData->c = firstColor = Iter2Color(flags,
					 (flags->fractal == MBROT) ? MbrotCalcIter(re, im) :
					 (flags->fractal == JULIA) ? JuliaCalcIter(re, im) :
					 MbrotCalcIter(re, im));
#780 "pm_genproc.c"
  
  
  *npoints = r.length;
  
  
  
  switch (flags->fractal) {
  case MBROT:
    if (r.b - r.t > 1 && r.r - r.l > 1) {
      (y = r.t, x = r.l + 1);
      while (x <= r.r) {
	NUM_ASSIGN(re, NUM_ADD(re, rstep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	if (pointPtr->c != firstColor)
	  goto m1;
	(pointPtr++, x++);
      };
      (x = r.r, y = r.t + 1);
      while (y <= r.b) {
	NUM_ASSIGN(im, NUM_ADD(im, istep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	if (pointPtr->c != firstColor)
	  goto m2;
	(pointPtr++, y++);
      };
      (y = r.b, x = r.r - 1);
      while (x >= r.l) {
	NUM_ASSIGN(re, NUM_SUB(re, rstep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	if (pointPtr->c != firstColor)
	  goto m3;
	(pointPtr++, x--);
      };
      (x = r.l, y = r.b - 1);
      while (y > r.t) {
	NUM_ASSIGN(im, NUM_SUB(im, istep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	if (pointPtr->c != firstColor)
	  goto m4;
	(pointPtr++, y--);
      };
      *isContinuous = 1;
      return 1;
      (y = r.t, x = r.l + 1);
      while (x <= r.r) {
	NUM_ASSIGN(re, NUM_ADD(re, rstep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
      m1:(pointPtr++, x++);
      };
      (x = r.r, y = r.t + 1);
      while (y <= r.b) {
	NUM_ASSIGN(im, NUM_ADD(im, istep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
      m2:(pointPtr++, y++);
      };
      (y = r.b, x = r.r - 1);
      while (x >= r.l) {
	NUM_ASSIGN(re, NUM_SUB(re, rstep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
      m3:(pointPtr++, x--);
      };
      (x = r.l, y = r.b - 1);
      while (y > r.t) {
	NUM_ASSIGN(im, NUM_SUB(im, istep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
      m4:(pointPtr++, y--);
      };
      *isContinuous = 0;
      return 0;
    } else {
      (y = r.t, x = r.l + 1);
      while (x <= r.r) {
	NUM_ASSIGN(re, NUM_ADD(re, rstep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	(pointPtr++, x++);
      };
      (x = r.r, y = r.t + 1);
      while (y <= r.b) {
	NUM_ASSIGN(im, NUM_ADD(im, istep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	(pointPtr++, y++);
      };
      if (r.r - r.l && r.b - r.t) {
	(y = r.b, x = r.r - 1);
	while (x >= r.l) {
	  NUM_ASSIGN(re, NUM_SUB(re, rstep));
	  pointPtr->x = x;
	  pointPtr->y = y;
	  pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	  (pointPtr++, x--);
	};
	(x = r.l, y = r.b - 1);
	while (y > r.t) {
	  NUM_ASSIGN(im, NUM_SUB(im, istep));
	  pointPtr->x = x;
	  pointPtr->y = y;
	  pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	  (pointPtr++, y--);
	};
      } *isContinuous = 0;
      return 0;
    };
  case JULIA:
    if (r.b - r.t > 1 && r.r - r.l > 1) {
      (y = r.t, x = r.l + 1);
      while (x <= r.r) {
	NUM_ASSIGN(re, NUM_ADD(re, rstep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, JuliaCalcIter(re, im));
	if (pointPtr->c != firstColor)
	  goto j1;
	(pointPtr++, x++);
      };
      (x = r.r, y = r.t + 1);
      while (y <= r.b) {
	NUM_ASSIGN(im, NUM_ADD(im, istep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, JuliaCalcIter(re, im));
	if (pointPtr->c != firstColor)
	  goto j2;
	(pointPtr++, y++);
      };
      (y = r.b, x = r.r - 1);
      while (x >= r.l) {
	NUM_ASSIGN(re, NUM_SUB(re, rstep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, JuliaCalcIter(re, im));
	if (pointPtr->c != firstColor)
	  goto j3;
	(pointPtr++, x--);
      };
      (x = r.l, y = r.b - 1);
      while (y > r.t) {
	NUM_ASSIGN(im, NUM_SUB(im, istep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, JuliaCalcIter(re, im));
	if (pointPtr->c != firstColor)
	  goto j4;
	(pointPtr++, y--);
      };
      *isContinuous = 1;
      return 1;
      (y = r.t, x = r.l + 1);
      while (x <= r.r) {
	NUM_ASSIGN(re, NUM_ADD(re, rstep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, JuliaCalcIter(re, im));
      j1:(pointPtr++, x++);
      };
      (x = r.r, y = r.t + 1);
      while (y <= r.b) {
	NUM_ASSIGN(im, NUM_ADD(im, istep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, JuliaCalcIter(re, im));
      j2:(pointPtr++, y++);
      };
      (y = r.b, x = r.r - 1);
      while (x >= r.l) {
	NUM_ASSIGN(re, NUM_SUB(re, rstep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, JuliaCalcIter(re, im));
      j3:(pointPtr++, x--);
      };
      (x = r.l, y = r.b - 1);
      while (y > r.t) {
	NUM_ASSIGN(im, NUM_SUB(im, istep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, JuliaCalcIter(re, im));
      j4:(pointPtr++, y--);
      };
      *isContinuous = 0;
      return 0;
    } else {
      (y = r.t, x = r.l + 1);
      while (x <= r.r) {
	NUM_ASSIGN(re, NUM_ADD(re, rstep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, JuliaCalcIter(re, im));
	(pointPtr++, x++);
      };
      (x = r.r, y = r.t + 1);
      while (y <= r.b) {
	NUM_ASSIGN(im, NUM_ADD(im, istep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, JuliaCalcIter(re, im));
	(pointPtr++, y++);
      };
      if (r.r - r.l && r.b - r.t) {
	(y = r.b, x = r.r - 1);
	while (x >= r.l) {
	  NUM_ASSIGN(re, NUM_SUB(re, rstep));
	  pointPtr->x = x;
	  pointPtr->y = y;
	  pointPtr->c = Iter2Color(flags, JuliaCalcIter(re, im));
	  (pointPtr++, x--);
	};
	(x = r.l, y = r.b - 1);
	while (y > r.t) {
	  NUM_ASSIGN(im, NUM_SUB(im, istep));
	  pointPtr->x = x;
	  pointPtr->y = y;
	  pointPtr->c = Iter2Color(flags, JuliaCalcIter(re, im));
	  (pointPtr++, y--);
	};
      } *isContinuous = 0;
      return 0;
    };
  case NEWTON:
    if (r.b - r.t > 1 && r.r - r.l > 1) {
      (y = r.t, x = r.l + 1);
      while (x <= r.r) {
	NUM_ASSIGN(re, NUM_ADD(re, rstep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	if (pointPtr->c != firstColor)
	  goto n1;
	(pointPtr++, x++);
      };
      (x = r.r, y = r.t + 1);
      while (y <= r.b) {
	NUM_ASSIGN(im, NUM_ADD(im, istep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	if (pointPtr->c != firstColor)
	  goto n2;
	(pointPtr++, y++);
      };
      (y = r.b, x = r.r - 1);
      while (x >= r.l) {
	NUM_ASSIGN(re, NUM_SUB(re, rstep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	if (pointPtr->c != firstColor)
	  goto n3;
	(pointPtr++, x--);
      };
      (x = r.l, y = r.b - 1);
      while (y > r.t) {
	NUM_ASSIGN(im, NUM_SUB(im, istep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	if (pointPtr->c != firstColor)
	  goto n4;
	(pointPtr++, y--);
      };
      *isContinuous = 1;
      return 1;
      (y = r.t, x = r.l + 1);
      while (x <= r.r) {
	NUM_ASSIGN(re, NUM_ADD(re, rstep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
      n1:(pointPtr++, x++);
      };
      (x = r.r, y = r.t + 1);
      while (y <= r.b) {
	NUM_ASSIGN(im, NUM_ADD(im, istep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
      n2:(pointPtr++, y++);
      };
      (y = r.b, x = r.r - 1);
      while (x >= r.l) {
	NUM_ASSIGN(re, NUM_SUB(re, rstep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
      n3:(pointPtr++, x--);
      };
      (x = r.l, y = r.b - 1);
      while (y > r.t) {
	NUM_ASSIGN(im, NUM_SUB(im, istep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
      n4:(pointPtr++, y--);
      };
      *isContinuous = 0;
      return 0;
    } else {
      (y = r.t, x = r.l + 1);
      while (x <= r.r) {
	NUM_ASSIGN(re, NUM_ADD(re, rstep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	(pointPtr++, x++);
      };
      (x = r.r, y = r.t + 1);
      while (y <= r.b) {
	NUM_ASSIGN(im, NUM_ADD(im, istep));
	pointPtr->x = x;
	pointPtr->y = y;
	pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	(pointPtr++, y++);
      };
      if (r.r - r.l && r.b - r.t) {
	(y = r.b, x = r.r - 1);
	while (x >= r.l) {
	  NUM_ASSIGN(re, NUM_SUB(re, rstep));
	  pointPtr->x = x;
	  pointPtr->y = y;
	  pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	  (pointPtr++, x--);
	};
	(x = r.l, y = r.b - 1);
	while (y > r.t) {
	  NUM_ASSIGN(im, NUM_SUB(im, istep));
	  pointPtr->x = x;
	  pointPtr->y = y;
	  pointPtr->c = Iter2Color(flags, MbrotCalcIter(re, im));
	  (pointPtr++, y--);
	};
      } *isContinuous = 0;
      return 0;
    };
  }
}


DrawBorder(graph, colorData, r)
MPE_XGraph graph;
int *colorData;
rect r;
{
  int x, y;
  
  for (y = r.t, x = r.l; x <= r.r; x++) {
#808 "pm_genproc.c"
    
    MPE_Draw_point(graph, x, y, *colorData);
    colorData++;
  }
  for (x = r.r, y = r.t + 1; y <= r.b; y++) {
#816 "pm_genproc.c"
    
    MPE_Draw_point(graph, x, y, *colorData);
    colorData++;
  }
  if (r.r - r.l && r.b - r.t) {
    for (y = r.b, x = r.r - 1; x >= r.l; x--) {
#825 "pm_genproc.c"
      
      MPE_Draw_point(graph, x, y, *colorData);
      colorData++;
    }
    for (x = r.l, y = r.b - 1; y > r.t; y--) {
#833 "pm_genproc.c"
      
      MPE_Draw_point(graph, x, y, *colorData);
      colorData++;
    }
  }
  MPE_Update(graph);
}


DrawBlock(graph, pointData, r)
MPE_XGraph graph;
MPE_Point *pointData;
rect *r;
{
#858 "pm_genproc.c"
  
  
  MPE_Fill_rectangle(graph, r->l, r->t, r->r - r->l + 1, r->b - r->t + 1,
		     pointData->c);
  
  MPE_Update(graph);
}
