/*
  *** DO NOT EDIT ***
  This file has been generated by opc89, and will be overwritten.
  Please edit the source of this file instead.
*/

#ifndef G2D_SARC_H
#define G2D_SARC_H
#include <assert.h>
#include <opc89.h>
#include <gengeo2d/prim.h>
#include <gengeo2d/common.h>
#include <gengeo2d/vect.h>
#include <gengeo2d/carc.h>
#include <gengeo2d/box.h>


/****** API ******/

/* Construct a sarc center, radius and angles */
G2D_INLINE g2d_sarc_t g2d_sarc(g2d_vect_t center, g2d_coord_t radius, g2d_angle_t start, g2d_angle_t end, g2d_coord_t width, g2d_cap_t cap);

/* Calculate the bounding box of a sarc */
G2D_INLINE g2d_box_t g2d_sarc_bbox(const g2d_sarc_t *arc);


/* Return the carc for the inner and outer edge of a sarc */
G2D_INLINE void g2d_sarc_sides(const g2d_sarc_t *sarc, g2d_carc_t *side_outer, g2d_carc_t *side_inner);

/****** IMPLEMENTATION ******/


G2D_INLINE g2d_sarc_t g2d_sarc(g2d_vect_t center, g2d_coord_t radius, g2d_angle_t start, g2d_angle_t delta, g2d_coord_t width, g2d_cap_t cap)
{
	g2d_sarc_t a;
	a.c.c = center; a.c.r = radius;
	a.c.start = start; a.c.delta = delta;
	a.s.width = width; a.s.cap = cap;
	return a;
}


G2D_INLINE g2d_box_t g2d_sarc_bbox(const g2d_sarc_t *arc)
{
	g2d_box_t bb = g2d_carc_bbox(&arc->c);
	g2d_calc_t wp2 = g2d_calc_t_div_g2d_calc_t(g2d_calc_t_convfrom_g2d_coord_t(arc->s.width),g2d_calc_t_convfrom_double(2.0));


	bb.p1.x = g2d_round_coord_down(g2d_calc_t_sub_g2d_calc_t(g2d_calc_t_convfrom_g2d_coord_t(bb.p1.x ) ,wp2));
	bb.p1.y = g2d_round_coord_down(g2d_calc_t_sub_g2d_calc_t(g2d_calc_t_convfrom_g2d_coord_t(bb.p1.y ) ,wp2));
	bb.p2.x = g2d_round_coord_up(g2d_calc_t_add_g2d_calc_t(g2d_calc_t_convfrom_g2d_coord_t(bb.p2.x ) ,wp2));
	bb.p2.y = g2d_round_coord_up(g2d_calc_t_add_g2d_calc_t(g2d_calc_t_convfrom_g2d_coord_t(bb.p2.y ) ,wp2));

	if (arc->s.cap == /*G2D_CAP_SQUARE*/1) {
		g2d_cvect_t t0, t1, n0, n1, e0, e1;
		e0 = g2d__carc_offs(&arc->c, g2d_offs_t_convfrom_double(0.0));
		e1 = g2d__carc_offs(&arc->c, g2d_offs_t_convfrom_double(1.0));
		t0 = g2d__carc_offs_tang1(&arc->c, g2d_offs_t_convfrom_double(0.0));
		t1 = g2d__carc_offs_tang1(&arc->c, g2d_offs_t_convfrom_double(1.0));
		if (g2d_angle_t_gte_g2d_angle_t(arc->c.delta  ,g2d_angle_t_convfrom_double(0.0)))
			t0 = g2d_cvect_t_neg(t0);
		else
			t1 = g2d_cvect_t_neg(t1);
		n0 = g2d__vect_perp(t0);
		n1 = g2d__vect_perp(t1);
		if (g2d_angle_t_lt_g2d_angle_t(arc->c.delta  ,g2d_angle_t_convfrom_double(0.0))) {
			n0 = g2d_cvect_t_neg(n0);
			n1 = g2d_cvect_t_neg(n1);
		}
		g2d__box_bump_pt(&bb, g2d_cvect(g2d_calc_t_add_g2d_calc_t(g2d_calc_t_add_g2d_calc_t(e0.x,g2d_calc_t_mul_g2d_calc_t(t0.x,wp2)),g2d_calc_t_mul_g2d_calc_t(n0.x,wp2)), g2d_calc_t_add_g2d_calc_t(g2d_calc_t_add_g2d_calc_t(e0.y,g2d_calc_t_mul_g2d_calc_t(t0.y,wp2)),g2d_calc_t_mul_g2d_calc_t(n0.y,wp2))));
		g2d__box_bump_pt(&bb, g2d_cvect(g2d_calc_t_sub_g2d_calc_t(g2d_calc_t_add_g2d_calc_t(e0.x,g2d_calc_t_mul_g2d_calc_t(t0.x,wp2)),g2d_calc_t_mul_g2d_calc_t(n0.x,wp2)), g2d_calc_t_sub_g2d_calc_t(g2d_calc_t_add_g2d_calc_t(e0.y,g2d_calc_t_mul_g2d_calc_t(t0.y,wp2)),g2d_calc_t_mul_g2d_calc_t(n0.y,wp2))));
		g2d__box_bump_pt(&bb, g2d_cvect(g2d_calc_t_add_g2d_calc_t(g2d_calc_t_add_g2d_calc_t(e1.x,g2d_calc_t_mul_g2d_calc_t(t1.x,wp2)),g2d_calc_t_mul_g2d_calc_t(n1.x,wp2)), g2d_calc_t_add_g2d_calc_t(g2d_calc_t_add_g2d_calc_t(e1.y,g2d_calc_t_mul_g2d_calc_t(t1.y,wp2)),g2d_calc_t_mul_g2d_calc_t(n1.y,wp2))));
		g2d__box_bump_pt(&bb, g2d_cvect(g2d_calc_t_sub_g2d_calc_t(g2d_calc_t_add_g2d_calc_t(e1.x,g2d_calc_t_mul_g2d_calc_t(t1.x,wp2)),g2d_calc_t_mul_g2d_calc_t(n1.x,wp2)), g2d_calc_t_sub_g2d_calc_t(g2d_calc_t_add_g2d_calc_t(e1.y,g2d_calc_t_mul_g2d_calc_t(t1.y,wp2)),g2d_calc_t_mul_g2d_calc_t(n1.y,wp2))));
	}
	return bb;
}


G2D_INLINE void g2d_sarc_sides(const g2d_sarc_t *sarc, g2d_carc_t *side_outer, g2d_carc_t *side_inner)
{
	if (side_outer != NULL) {
		*side_outer = sarc->c;
		side_outer->r = g2d_coord_t_convfrom_g2d_calc_t(g2d_calc_t_add_g2d_calc_t(g2d_calc_t_convfrom_g2d_coord_t(sarc->c.r ) ,g2d_calc_t_div_g2d_calc_t(g2d_calc_t_convfrom_g2d_coord_t(sarc->s.width ) ,g2d_calc_t_convfrom_double(2.0))));
	}
	if (side_inner != NULL) {
		*side_inner = sarc->c;
		side_inner->r =  g2d_coord_t_convfrom_g2d_calc_t(g2d_calc_t_add_g2d_calc_t(g2d_calc_t_convfrom_g2d_coord_t(sarc->c.r ) ,g2d_calc_t_div_g2d_calc_t(g2d_calc_t_convfrom_g2d_coord_t(sarc->s.width ) ,g2d_calc_t_convfrom_double(2.0))));
	}
}
#endif /* G2D_SARC_H */
