// reduces a polynomial with respect to a set of polynomials F
Polynomial *normal_form(Polynomial **set, Polynomial *orig, 
                        int index, int num_polys, int *reduced){
    Polynomial *res, *temp; 

    // we must try all quotient and remainders
    Polynomial **quots = (Polynomial **) malloc(sizeof(Polynomial *) * num_polys);
    Polynomial **rems = (Polynomial **) malloc(sizeof(Polynomial *) * num_polys);
     
    res = copy_poly(orig);
    *reduced = 0;
  
    printf("computing some reduction\n");  
    // try to divide using all things in the set 
    for (int i = 0; i < num_polys; i++){
        if (i == index) continue;
        divide_polys(orig, set[i], &(quots[i]), &(rems[i]));
    }

    printf("wtf tried to divide everything\n"); 
    // nothing divided out completely the first time
    // keep trying to divide out stuff recursively
    for (int i = 0; i < num_polys; i++){
        if (i == index) continue;
        
        // remainder is 0, return this right away
        if (rems[i]->terms[0].coeff.num == 0){
            free(res);  
            res = copy_poly(rems[i]);
            break;
        }

        // try to divide recursively
        else if (quots[i]->terms[0].coeff.num != 0){
            temp = normal_form(set, rems[i], index, num_polys, reduced);
            free(res); 
            // it reduced all the way
            if (temp->terms[0].coeff.num == 0){
                res = copy_poly(temp);
                break; 
            }
            else{
                res = copy_poly(rems[i]); 
            }
            free(temp); 
        }
    }

    // free all this stuff
    for (int i = 0; i < num_polys; i++) {
        if (i == index) continue; 
        free(quots[i]);
        free(rems[i]); 
    }

    free(quots);
    free(rems); 

    return res; 
}
/* draw an angle from the current point to b and then to c,
 * with a rounded corner of the given radius.
 */
static void
rounded_corner (cairo_t * cr,
		gdouble bx, gdouble by,
		gdouble cx, gdouble cy, gdouble radius)
{
    gdouble ax, ay;
    gdouble n1x, n1y, d1;
    gdouble n2x, n2y, d2;
    gdouble pd1, pd2;
    gdouble ix, iy;
    gdouble dist1, dist2;
    gdouble nx, ny, d;
    gdouble a1x, a1y, c1x, c1y;
    gdouble phi1, phi2;

    cairo_get_current_point (cr, &ax, &ay);
#ifdef KBDRAW_DEBUG
    printf ("        current point: (%f, %f), radius %f:\n", ax, ay,
            radius);
#endif

    /* make sure radius is not too large */
    dist1 = length (bx - ax, by - ay);
    dist2 = length (cx - bx, cy - by);

    radius = MIN (radius, MIN (dist1, dist2));

    /* construct normal forms of the lines */
    normal_form (ax, ay, bx, by, &n1x, &n1y, &d1);
    normal_form (bx, by, cx, cy, &n2x, &n2y, &d2);

    /* find which side of the line a,b the point c is on */
    if (point_line_distance (cx, cy, n1x, n1y) < d1)
        pd1 = d1 - radius;
    else
        pd1 = d1 + radius;

    /* find which side of the line b,c the point a is on */
    if (point_line_distance (ax, ay, n2x, n2y) < d2)
        pd2 = d2 - radius;
    else
        pd2 = d2 + radius;

    /* intersect the parallels to find the center of the arc */
    intersect (n1x, n1y, pd1, n2x, n2y, pd2, &ix, &iy);

    nx = (bx - ax) / dist1;
    ny = (by - ay) / dist1;
    d = point_line_distance (ix, iy, nx, ny);

    /* a1 is the point on the line a-b where the arc starts */
    intersect (n1x, n1y, d1, nx, ny, d, &a1x, &a1y);

    nx = (cx - bx) / dist2;
    ny = (cy - by) / dist2;
    d = point_line_distance (ix, iy, nx, ny);

    /* c1 is the point on the line b-c where the arc ends */
    intersect (n2x, n2y, d2, nx, ny, d, &c1x, &c1y);

    /* determine the first angle */
    if (a1x - ix == 0)
        phi1 = (a1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
    else if (a1x - ix > 0)
        phi1 = atan ((a1y - iy) / (a1x - ix));
    else
        phi1 = M_PI + atan ((a1y - iy) / (a1x - ix));

    /* determine the second angle */
    if (c1x - ix == 0)
        phi2 = (c1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
    else if (c1x - ix > 0)
        phi2 = atan ((c1y - iy) / (c1x - ix));
    else
        phi2 = M_PI + atan ((c1y - iy) / (c1x - ix));

    /* compute the difference between phi2 and phi1 mod 2pi */
    d = phi2 - phi1;
    while (d < 0)
        d += 2 * M_PI;
    while (d > 2 * M_PI)
        d -= 2 * M_PI;

#ifdef KBDRAW_DEBUG
    printf ("        line 1 to: (%f, %f):\n", a1x, a1y);
#endif
    if (!(isnan (a1x) || isnan (a1y)))
        cairo_line_to (cr, a1x, a1y);

    /* pick the short arc from phi1 to phi2 */
    if (d < M_PI)
        cairo_arc (cr, ix, iy, radius, phi1, phi2);
    else
        cairo_arc_negative (cr, ix, iy, radius, phi1, phi2);

#ifdef KBDRAW_DEBUG
    printf ("        line 2 to: (%f, %f):\n", cx, cy);
#endif
    cairo_line_to (cr, cx, cy);
}