/* -=- sraRegion.c
 * Copyright (c) 2001 James "Wez" Weatherall, Johannes E. Schindelin
 *
 * A general purpose region clipping library
 * Only deals with rectangular regions, though.
 */

#include <rfb/rfb.h>
#include <rfb/rfbregion.h>

/* -=- Internal Span structure */

struct sraRegion;

typedef struct sraSpan {
  struct sraSpan *_next;
  struct sraSpan *_prev;
  int start;
  int end;
  struct sraRegion *subspan;
} sraSpan;

typedef struct sraRegion {
  sraSpan front;
  sraSpan back;
} sraSpanList;

/* -=- Span routines */

sraSpanList *sraSpanListDup(const sraSpanList *src);
void sraSpanListDestroy(sraSpanList *list);

static sraSpan *
sraSpanCreate(int start, int end, const sraSpanList *subspan) {
  sraSpan *item = (sraSpan*)malloc(sizeof(sraSpan));
  item->_next = item->_prev = NULL;
  item->start = start;
  item->end = end;
  item->subspan = sraSpanListDup(subspan);
  return item;
}

static sraSpan *
sraSpanDup(const sraSpan *src) {
  sraSpan *span;
  if (!src) return NULL;
  span = sraSpanCreate(src->start, src->end, src->subspan);
  return span;
}

static void
sraSpanInsertAfter(sraSpan *newspan, sraSpan *after) {
  newspan->_next = after->_next;
  newspan->_prev = after;
  after->_next->_prev = newspan;
  after->_next = newspan;
}

static void
sraSpanInsertBefore(sraSpan *newspan, sraSpan *before) {
  newspan->_next = before;
  newspan->_prev = before->_prev;
  before->_prev->_next = newspan;
  before->_prev = newspan;
}

static void
sraSpanRemove(sraSpan *span) {
  span->_prev->_next = span->_next;
  span->_next->_prev = span->_prev;
}

static void
sraSpanDestroy(sraSpan *span) {
  if (span->subspan) sraSpanListDestroy(span->subspan);
  free(span);
}

#ifdef DEBUG
static void
sraSpanCheck(const sraSpan *span, const char *text) {
  /* Check the span is valid! */
  if (span->start == span->end) {
    printf(text); 
    printf(":%d-%d\n", span->start, span->end);
  }
}
#endif

/* -=- SpanList routines */

static void sraSpanPrint(const sraSpan *s);

static void
sraSpanListPrint(const sraSpanList *l) {
  sraSpan *curr;
  if (!l) {
	  printf("NULL");
	  return;
  }
  curr = l->front._next;
  printf("[");
  while (curr != &(l->back)) {
    sraSpanPrint(curr);
    curr = curr->_next;
  }
  printf("]");
}

void
sraSpanPrint(const sraSpan *s) {
  printf("(%d-%d)", (s->start), (s->end));
  if (s->subspan)
    sraSpanListPrint(s->subspan);
}

static sraSpanList *
sraSpanListCreate(void) {
  sraSpanList *item = (sraSpanList*)malloc(sizeof(sraSpanList));
  item->front._next = &(item->back);
  item->front._prev = NULL;
  item->back._prev = &(item->front);
  item->back._next = NULL;
  return item;
}

sraSpanList *
sraSpanListDup(const sraSpanList *src) {
  sraSpanList *newlist;
  sraSpan *newspan, *curr;

  if (!src) return NULL;
  newlist = sraSpanListCreate();
  curr = src->front._next;
  while (curr != &(src->back)) {
    newspan = sraSpanDup(curr);
    sraSpanInsertBefore(newspan, &(newlist->back));
    curr = curr->_next;
  }

  return newlist;
}

void
sraSpanListDestroy(sraSpanList *list) {
  sraSpan *curr, *next;
  while (list->front._next != &(list->back)) {
    curr = list->front._next;
    next = curr->_next;
    sraSpanRemove(curr);
    sraSpanDestroy(curr);
    curr = next;
  }
  free(list);
}

static void
sraSpanListMakeEmpty(sraSpanList *list) {
  sraSpan *curr, *next;
  while (list->front._next != &(list->back)) {
    curr = list->front._next;
    next = curr->_next;
    sraSpanRemove(curr);
    sraSpanDestroy(curr);
    curr = next;
  }
  list->front._next = &(list->back);
  list->front._prev = NULL;
  list->back._prev = &(list->front);
  list->back._next = NULL;
}

static rfbBool
sraSpanListEqual(const sraSpanList *s1, const sraSpanList *s2) {
  sraSpan *sp1, *sp2;

  if (!s1) {
    if (!s2) {
      return 1;
    } else {
      rfbErr("sraSpanListEqual:incompatible spans (only one NULL!)\n");
      return FALSE;
    }
  }

  sp1 = s1->front._next;
  sp2 = s2->front._next;
  while ((sp1 != &(s1->back)) &&
	 (sp2 != &(s2->back))) {
    if ((sp1->start != sp2->start) ||
	(sp1->end != sp2->end) ||
	(!sraSpanListEqual(sp1->subspan, sp2->subspan))) {
      return 0;
    }
    sp1 = sp1->_next;
    sp2 = sp2->_next;
  }

  if ((sp1 == &(s1->back)) && (sp2 == &(s2->back))) {
    return 1;
  } else {
    return 0;
  }    
}

static rfbBool
sraSpanListEmpty(const sraSpanList *list) {
  return (list->front._next == &(list->back));
}

static unsigned long
sraSpanListCount(const sraSpanList *list) {
  sraSpan *curr = list->front._next;
  unsigned long count = 0;
  while (curr != &(list->back)) {
    if (curr->subspan) {
      count += sraSpanListCount(curr->subspan);
    } else {
      count += 1;
    }
    curr = curr->_next;
  }
  return count;
}

static void
sraSpanMergePrevious(sraSpan *dest) {
  sraSpan *prev = dest->_prev;
 
  while ((prev->_prev) &&
	 (prev->end == dest->start) &&
	 (sraSpanListEqual(prev->subspan, dest->subspan))) {
    /*
    printf("merge_prev:");
    sraSpanPrint(prev);
    printf(" & ");
    sraSpanPrint(dest);
    printf("\n");
    */
    dest->start = prev->start;
    sraSpanRemove(prev);
    sraSpanDestroy(prev);
    prev = dest->_prev;
  }
}    

static void
sraSpanMergeNext(sraSpan *dest) {
  sraSpan *next = dest->_next;
  while ((next->_next) &&
	 (next->start == dest->end) &&
	 (sraSpanListEqual(next->subspan, dest->subspan))) {
/*
	  printf("merge_next:");
    sraSpanPrint(dest);
    printf(" & ");
    sraSpanPrint(next);
    printf("\n");
	*/
    dest->end = next->end;
    sraSpanRemove(next);
    sraSpanDestroy(next);
    next = dest->_next;
  }
}

static void
sraSpanListOr(sraSpanList *dest, const sraSpanList *src) {
  sraSpan *d_curr, *s_curr;
  int s_start, s_end;

  if (!dest) {
    if (!src) {
      return;
    } else {
      rfbErr("sraSpanListOr:incompatible spans (only one NULL!)\n");
      return;
    }
  }

  d_curr = dest->front._next;
  s_curr = src->front._next;
  s_start = s_curr->start;
  s_end = s_curr->end;
  while (s_curr != &(src->back)) {

    /* - If we are at end of destination list OR
       If the new span comes before the next destination one */
    if ((d_curr == &(dest->back)) ||
		(d_curr->start >= s_end)) {
      /* - Add the span */
      sraSpanInsertBefore(sraSpanCreate(s_start, s_end,
					s_curr->subspan),
			  d_curr);
      if (d_curr != &(dest->back))
	sraSpanMergePrevious(d_curr);
      s_curr = s_curr->_next;
      s_start = s_curr->start;
      s_end = s_curr->end;
    } else {

      /* - If the new span overlaps the existing one */
      if ((s_start < d_curr->end) &&
	  (s_end > d_curr->start)) {

	/* - Insert new span before the existing destination one? */
	if (s_start < d_curr->start) {
	  sraSpanInsertBefore(sraSpanCreate(s_start,
					    d_curr->start,
					    s_curr->subspan),
			      d_curr);
	  sraSpanMergePrevious(d_curr);
	}

	/* Split the existing span if necessary */
	if (s_end < d_curr->end) {
	  sraSpanInsertAfter(sraSpanCreate(s_end,
					   d_curr->end,
					   d_curr->subspan),
			     d_curr);
	  d_curr->end = s_end;
	}
	if (s_start > d_curr->start) {
	  sraSpanInsertBefore(sraSpanCreate(d_curr->start,
					    s_start,
					    d_curr->subspan),
			      d_curr);
	  d_curr->start = s_start;
	}

	/* Recursively OR subspans */
	sraSpanListOr(d_curr->subspan, s_curr->subspan);

	/* Merge this span with previous or next? */
	if (d_curr->_prev != &(dest->front))
	  sraSpanMergePrevious(d_curr);
	if (d_curr->_next != &(dest->back))
	  sraSpanMergeNext(d_curr);

	/* Move onto the next pair to compare */
	if (s_end > d_curr->end) {
	  s_start = d_curr->end;
	  d_curr = d_curr->_next;
	} else {
	  s_curr = s_curr->_next;
	  s_start = s_curr->start;
	  s_end = s_curr->end;
	}
      } else {
	/* - No overlap.  Move to the next destination span */
	d_curr = d_curr->_next;
      }
    }
  }
}

static rfbBool
sraSpanListAnd(sraSpanList *dest, const sraSpanList *src) {
  sraSpan *d_curr, *s_curr, *d_next;

  if (!dest) {
    if (!src) {
      return 1;
    } else {
      rfbErr("sraSpanListAnd:incompatible spans (only one NULL!)\n");
      return FALSE;
    }
  }

  d_curr = dest->front._next;
  s_curr = src->front._next;
  while ((s_curr != &(src->back)) && (d_curr != &(dest->back))) {

    /* - If we haven't reached a destination span yet then move on */
    if (d_curr->start >= s_curr->end) {
      s_curr = s_curr->_next;
      continue;
    }

    /* - If we are beyond the current destination span then remove it */
    if (d_curr->end <= s_curr->start) {
      sraSpan *next = d_curr->_next;
      sraSpanRemove(d_curr);
      sraSpanDestroy(d_curr);
      d_curr = next;
      continue;
    }

    /* - If we partially overlap a span then split it up or remove bits */
    if (s_curr->start > d_curr->start) {
      /* - The top bit of the span does not match */
      d_curr->start = s_curr->start;
    }
    if (s_curr->end < d_curr->end) {
      /* - The end of the span does not match */
      sraSpanInsertAfter(sraSpanCreate(s_curr->end,
				       d_curr->end,
				       d_curr->subspan),
			 d_curr);
      d_curr->end = s_curr->end;
    }

    /* - Now recursively process the affected span */
    if (!sraSpanListAnd(d_curr->subspan, s_curr->subspan)) {
      /* - The destination subspan is now empty, so we should remove it */
		sraSpan *next = d_curr->_next;
      sraSpanRemove(d_curr);
      sraSpanDestroy(d_curr);
      d_curr = next;
    } else {
      /* Merge this span with previous or next? */
      if (d_curr->_prev != &(dest->front))
	sraSpanMergePrevious(d_curr);

      /* - Move on to the next span */
      d_next = d_curr;
      if (s_curr->end >= d_curr->end) {
	d_next = d_curr->_next;
      }
      if (s_curr->end <= d_curr->end) {
	s_curr = s_curr->_next;
      }
      d_curr = d_next;
    }
  }

  while (d_curr != &(dest->back)) {
    sraSpan *next = d_curr->_next;
    sraSpanRemove(d_curr);
    sraSpanDestroy(d_curr);
    d_curr=next;
  }

  return !sraSpanListEmpty(dest);
}

static rfbBool
sraSpanListSubtract(sraSpanList *dest, const sraSpanList *src) {
  sraSpan *d_curr, *s_curr;

  if (!dest) {
    if (!src) {
      return 1;
    } else {
      rfbErr("sraSpanListSubtract:incompatible spans (only one NULL!)\n");
      return FALSE;
    }
  }

  d_curr = dest->front._next;
  s_curr = src->front._next;
  while ((s_curr != &(src->back)) && (d_curr != &(dest->back))) {

    /* - If we haven't reached a destination span yet then move on */
    if (d_curr->start >= s_curr->end) {
      s_curr = s_curr->_next;
      continue;
    }

    /* - If we are beyond the current destination span then skip it */
    if (d_curr->end <= s_curr->start) {
      d_curr = d_curr->_next;
      continue;
    }

    /* - If we partially overlap the current span then split it up */
    if (s_curr->start > d_curr->start) {
      sraSpanInsertBefore(sraSpanCreate(d_curr->start,
					s_curr->start,
					d_curr->subspan),
			  d_curr);
      d_curr->start = s_curr->start;
    }
    if (s_curr->end < d_curr->end) {
      sraSpanInsertAfter(sraSpanCreate(s_curr->end,
				       d_curr->end,
				       d_curr->subspan),
			 d_curr);
      d_curr->end = s_curr->end;
    }

    /* - Now recursively process the affected span */
    if ((!d_curr->subspan) || !sraSpanListSubtract(d_curr->subspan, s_curr->subspan)) {
      /* - The destination subspan is now empty, so we should remove it */
      sraSpan *next = d_curr->_next;
      sraSpanRemove(d_curr);
      sraSpanDestroy(d_curr);
      d_curr = next;
    } else {
      /* Merge this span with previous or next? */
      if (d_curr->_prev != &(dest->front))
	sraSpanMergePrevious(d_curr);
      if (d_curr->_next != &(dest->back))
	sraSpanMergeNext(d_curr);

      /* - Move on to the next span */
      if (s_curr->end > d_curr->end) {
	d_curr = d_curr->_next;
      } else {
	s_curr = s_curr->_next;
      }
    }
  }

  return !sraSpanListEmpty(dest);
}

/* -=- Region routines */

sraRegion *
sraRgnCreate(void) {
  return (sraRegion*)sraSpanListCreate();
}

sraRegion *
sraRgnCreateRect(int x1, int y1, int x2, int y2) {
  sraSpanList *vlist, *hlist;
  sraSpan *vspan, *hspan;

  /* - Build the horizontal portion of the span */
  hlist = sraSpanListCreate();
  hspan = sraSpanCreate(x1, x2, NULL);
  sraSpanInsertAfter(hspan, &(hlist->front));

  /* - Build the vertical portion of the span */
  vlist = sraSpanListCreate();
  vspan = sraSpanCreate(y1, y2, hlist);
  sraSpanInsertAfter(vspan, &(vlist->front));

  sraSpanListDestroy(hlist);

  return (sraRegion*)vlist;
}

sraRegion *
sraRgnCreateRgn(const sraRegion *src) {
  return (sraRegion*)sraSpanListDup((sraSpanList*)src);
}

void
sraRgnDestroy(sraRegion *rgn) {
  sraSpanListDestroy((sraSpanList*)rgn);
}

void
sraRgnMakeEmpty(sraRegion *rgn) {
  sraSpanListMakeEmpty((sraSpanList*)rgn);
}

/* -=- Boolean Region ops */

rfbBool
sraRgnAnd(sraRegion *dst, const sraRegion *src) {
  return sraSpanListAnd((sraSpanList*)dst, (sraSpanList*)src);
}

void
sraRgnOr(sraRegion *dst, const sraRegion *src) {
  sraSpanListOr((sraSpanList*)dst, (sraSpanList*)src);
}

rfbBool
sraRgnSubtract(sraRegion *dst, const sraRegion *src) {
  return sraSpanListSubtract((sraSpanList*)dst, (sraSpanList*)src);
}

void
sraRgnOffset(sraRegion *dst, int dx, int dy) {
  sraSpan *vcurr, *hcurr;

  vcurr = ((sraSpanList*)dst)->front._next;
  while (vcurr != &(((sraSpanList*)dst)->back)) {
    vcurr->start += dy;
    vcurr->end += dy;
    
    hcurr = vcurr->subspan->front._next;
    while (hcurr != &(vcurr->subspan->back)) {
      hcurr->start += dx;
      hcurr->end += dx;
      hcurr = hcurr->_next;
    }

    vcurr = vcurr->_next;
  }
}

sraRegion *sraRgnBBox(const sraRegion *src) {
  int xmin=((unsigned int)(int)-1)>>1,ymin=xmin,xmax=1-xmin,ymax=xmax;
  sraSpan *vcurr, *hcurr;

  if(!src)
    return sraRgnCreate();

  vcurr = ((sraSpanList*)src)->front._next;
  while (vcurr != &(((sraSpanList*)src)->back)) {
    if(vcurr->start<ymin)
      ymin=vcurr->start;
    if(vcurr->end>ymax)
      ymax=vcurr->end;
    
    hcurr = vcurr->subspan->front._next;
    while (hcurr != &(vcurr->subspan->back)) {
      if(hcurr->start<xmin)
	xmin=hcurr->start;
      if(hcurr->end>xmax)
	xmax=hcurr->end;
      hcurr = hcurr->_next;
    }

    vcurr = vcurr->_next;
  }

  if(xmax<xmin || ymax<ymin)
    return sraRgnCreate();

  return sraRgnCreateRect(xmin,ymin,xmax,ymax);
}

rfbBool
sraRgnPopRect(sraRegion *rgn, sraRect *rect, unsigned long flags) {
  sraSpan *vcurr, *hcurr;
  sraSpan *vend, *hend;
  rfbBool right2left = (flags & 2) == 2;
  rfbBool bottom2top = (flags & 1) == 1;

  /* - Pick correct order */
  if (bottom2top) {
    vcurr = ((sraSpanList*)rgn)->back._prev;
    vend = &(((sraSpanList*)rgn)->front);
  } else {
    vcurr = ((sraSpanList*)rgn)->front._next;
    vend = &(((sraSpanList*)rgn)->back);
  }

  if (vcurr != vend) {
    rect->y1 = vcurr->start;
    rect->y2 = vcurr->end;

    /* - Pick correct order */
    if (right2left) {
      hcurr = vcurr->subspan->back._prev;
      hend = &(vcurr->subspan->front);
    } else {
      hcurr = vcurr->subspan->front._next;
      hend = &(vcurr->subspan->back);
    }

    if (hcurr != hend) {
      rect->x1 = hcurr->start;
      rect->x2 = hcurr->end;

      sraSpanRemove(hcurr);
      sraSpanDestroy(hcurr);
      
      if (sraSpanListEmpty(vcurr->subspan)) {
	sraSpanRemove(vcurr);
	sraSpanDestroy(vcurr);
      }

#if 0
      printf("poprect:(%dx%d)-(%dx%d)\n",
	     rect->x1, rect->y1, rect->x2, rect->y2);
#endif
      return 1;
    }
  }

  return 0;
}

unsigned long
sraRgnCountRects(const sraRegion *rgn) {
  unsigned long count = sraSpanListCount((sraSpanList*)rgn);
  return count;
}

rfbBool
sraRgnEmpty(const sraRegion *rgn) {
  return sraSpanListEmpty((sraSpanList*)rgn);
}

/* iterator stuff */
sraRectangleIterator *sraRgnGetIterator(sraRegion *s)
{
  /* these values have to be multiples of 4 */
#define DEFSIZE 4
#define DEFSTEP 8
  sraRectangleIterator *i =
    (sraRectangleIterator*)malloc(sizeof(sraRectangleIterator));
  if(!i)
    return NULL;

  /* we have to recurse eventually. So, the first sPtr is the pointer to
     the sraSpan in the first level. the second sPtr is the pointer to
     the sraRegion.back. The third and fourth sPtr are for the second
     recursion level and so on. */
  i->sPtrs = (sraSpan**)malloc(sizeof(sraSpan*)*DEFSIZE);
  if(!i->sPtrs) {
    free(i);
    return NULL;
  }
  i->ptrSize = DEFSIZE;
  i->sPtrs[0] = &(s->front);
  i->sPtrs[1] = &(s->back);
  i->ptrPos = 0;
  i->reverseX = 0;
  i->reverseY = 0;
  return i;
}

sraRectangleIterator *sraRgnGetReverseIterator(sraRegion *s,rfbBool reverseX,rfbBool reverseY)
{
  sraRectangleIterator *i = sraRgnGetIterator(s);
  if(reverseY) {
    i->sPtrs[1] = &(s->front);
    i->sPtrs[0] = &(s->back);
  }
  i->reverseX = reverseX;
  i->reverseY = reverseY;
  return(i);
}

static rfbBool sraReverse(sraRectangleIterator *i)
{
  return( ((i->ptrPos&2) && i->reverseX) ||
     (!(i->ptrPos&2) && i->reverseY));
}

static sraSpan* sraNextSpan(sraRectangleIterator *i)
{
  if(sraReverse(i))
    return(i->sPtrs[i->ptrPos]->_prev);
  else
    return(i->sPtrs[i->ptrPos]->_next);
}

rfbBool sraRgnIteratorNext(sraRectangleIterator* i,sraRect* r)
{
  /* is the subspan finished? */
  while(sraNextSpan(i) == i->sPtrs[i->ptrPos+1]) {
    i->ptrPos -= 2;
    if(i->ptrPos < 0) /* the end */
      return(0);
  }

  i->sPtrs[i->ptrPos] = sraNextSpan(i);

  /* is this a new subspan? */
  while(i->sPtrs[i->ptrPos]->subspan) {
    if(i->ptrPos+2 > i->ptrSize) { /* array is too small */
      i->ptrSize += DEFSTEP;
      i->sPtrs = (sraSpan**)realloc(i->sPtrs, sizeof(sraSpan*)*i->ptrSize);
    }
    i->ptrPos += 2;
    if(sraReverse(i)) {
      i->sPtrs[i->ptrPos]   =   i->sPtrs[i->ptrPos-2]->subspan->back._prev;
      i->sPtrs[i->ptrPos+1] = &(i->sPtrs[i->ptrPos-2]->subspan->front);
    } else {
      i->sPtrs[i->ptrPos]   =   i->sPtrs[i->ptrPos-2]->subspan->front._next;
      i->sPtrs[i->ptrPos+1] = &(i->sPtrs[i->ptrPos-2]->subspan->back);
    }
  }

  if((i->ptrPos%4)!=2) {
    rfbErr("sraRgnIteratorNext: offset is wrong (%d%%4!=2)\n",i->ptrPos);
    return FALSE;
  }

  r->y1 = i->sPtrs[i->ptrPos-2]->start;
  r->y2 = i->sPtrs[i->ptrPos-2]->end;
  r->x1 = i->sPtrs[i->ptrPos]->start;
  r->x2 = i->sPtrs[i->ptrPos]->end;

  return(-1);
}

void sraRgnReleaseIterator(sraRectangleIterator* i)
{
  free(i->sPtrs);
  free(i);
}

void
sraRgnPrint(const sraRegion *rgn) {
	sraSpanListPrint((sraSpanList*)rgn);
}

rfbBool
sraClipRect(int *x, int *y, int *w, int *h,
	    int cx, int cy, int cw, int ch) {
  if (*x < cx) {
    *w -= (cx-*x);
    *x = cx;
  }
  if (*y < cy) {
    *h -= (cy-*y);
    *y = cy;
  }
  if (*x+*w > cx+cw) {
    *w = (cx+cw)-*x;
  }
  if (*y+*h > cy+ch) {
    *h = (cy+ch)-*y;
  }
  return (*w>0) && (*h>0);
}

rfbBool
sraClipRect2(int *x, int *y, int *x2, int *y2,
	    int cx, int cy, int cx2, int cy2) {
  if (*x < cx)
    *x = cx;
  if (*y < cy)
    *y = cy;
  if (*x >= cx2)
    *x = cx2-1;
  if (*y >= cy2)
    *y = cy2-1;
  if (*x2 <= cx)
    *x2 = cx+1;
  if (*y2 <= cy)
    *y2 = cy+1;
  if (*x2 > cx2)
    *x2 = cx2;
  if (*y2 > cy2)
    *y2 = cy2;
  return (*x2>*x) && (*y2>*y);
}

/* test */

#ifdef SRA_TEST
/* pipe the output to sort|uniq -u and you'll get the errors. */
int main(int argc, char** argv)
{
  sraRegionPtr region, region1, region2;
  sraRectangleIterator* i;
  sraRect rect;
  rfbBool b;

  region = sraRgnCreateRect(10, 10, 600, 300);
  region1 = sraRgnCreateRect(40, 50, 350, 200);
  region2 = sraRgnCreateRect(0, 0, 20, 40);

  sraRgnPrint(region);
  printf("\n[(10-300)[(10-600)]]\n\n");

  b = sraRgnSubtract(region, region1);
  printf("%s ",b?"true":"false");
  sraRgnPrint(region);
  printf("\ntrue [(10-50)[(10-600)](50-200)[(10-40)(350-600)](200-300)[(10-600)]]\n\n");

  sraRgnOr(region, region2);
  printf("%ld\n6\n\n", sraRgnCountRects(region));

  i = sraRgnGetIterator(region);
  while(sraRgnIteratorNext(i, &rect))
    printf("%dx%d+%d+%d ",
	   rect.x2-rect.x1,rect.y2-rect.y1,
	   rect.x1,rect.y1);
  sraRgnReleaseIterator(i);
  printf("\n20x10+0+0 600x30+0+10 590x10+10+40 30x150+10+50 250x150+350+50 590x100+10+200 \n\n");

  i = sraRgnGetReverseIterator(region,1,0);
  while(sraRgnIteratorNext(i, &rect))
    printf("%dx%d+%d+%d ",
	   rect.x2-rect.x1,rect.y2-rect.y1,
	   rect.x1,rect.y1);
  sraRgnReleaseIterator(i);
  printf("\n20x10+0+0 600x30+0+10 590x10+10+40 250x150+350+50 30x150+10+50 590x100+10+200 \n\n");

  i = sraRgnGetReverseIterator(region,1,1);
  while(sraRgnIteratorNext(i, &rect))
    printf("%dx%d+%d+%d ",
	   rect.x2-rect.x1,rect.y2-rect.y1,
	   rect.x1,rect.y1);
  sraRgnReleaseIterator(i);
  printf("\n590x100+10+200 250x150+350+50 30x150+10+50 590x10+10+40 600x30+0+10 20x10+0+0 \n\n");

  sraRgnDestroy(region);
  sraRgnDestroy(region1);
  sraRgnDestroy(region2);

  return(0);
}
#endif
