#include <LEDA/window.h>
#include <math.h>

window W(600,250);

color col = green2;
color bg_col = "grey75";
color li_col  = black;
bool  draw_arc = false;
bool  base_line = false;
int   lw = 2;
int   N =  60;

#if !defined(M_PI)
#define	M_PI 3.14159265358979323846
#endif


void poly_arc(point p, point q, point c, list<point>& pol)
{ segment s0(c,p);
  segment s1(c,q);
  double delta = M_PI/N;
  double r = s0.length();
  double a;
  if (s0.angle() < s1.angle())
    for(a=s0.angle(); a <= s1.angle(); a+=delta) 
         pol.append(c.translate_by_angle(a,r));
  else
    for(a=s0.angle(); a >= s1.angle(); a-=delta) 
         pol.append(c.translate_by_angle(a,r));
 }

  


void draw_logo()
{
   W.clear(bg_col);
   W.set_mode(src_mode);
   W.set_line_width(lw);

   double d = 0.20;
   double eps = 0.05;

   circle c1(0,-1,sqrt(5.0));
   circle c2(0,-1,sqrt(5.0)-d);
   circle c3(0,0,1);
   circle c4(0,0,1-d);

   point A,B,C,D,E,F,G,H,I,J;
   segment s0,s1,s2;

   W.draw_disc(c1,bg_col);
   W.draw_box(-10,-10,10,0,bg_col);

   list<point> pol;

   double R0 = sqrt(5.0);
   double R1 = sqrt(5.0)-d;

   // L

   s0 = segment(-1-eps,0,-1-eps,2);
   s1 = segment(-2,d,0,d);

   A = c1.intersection(s0).head(); 
   B = c2.intersection(s0).head(); 
   C = c2.intersection(s1).head(); 
   D = point(-1-eps,d);
   E = point(-1-eps,0);
   F = point(-2,0);

   pol.append(A);
   pol.append(B);
   poly_arc(B,C,point(0,-1),pol);
   pol.append(C);
   pol.append(D);
   pol.append(E);
   pol.append(F);
   poly_arc(F,A,point(0,-1),pol);
   
   W.draw_filled_polygon(pol,col);
   if (lw > 0) W.draw_polygon(pol,li_col);


   // E


   s0 = segment(0,0.6,-2,0.6);
   s1 = segment(0,0.4,-2,0.4);
   s2 = segment(0,0.2,-2,0.2);

   A = point(-eps,1);
   B = point(-eps,1-d);
   C = c4.intersection(s0).head();
   D = point(-eps,C.ycoord());
   E = point(-eps,C.ycoord()-0.2);
   F = c4.intersection(s1).head();
   G = c4.intersection(s2).head();
   H = point(-eps,G.ycoord());
   I = point(-eps,0);
   J = point(-1,0);

   pol.clear();

   pol.append(A);
   pol.append(B);
   poly_arc(B,C,point(0,0),pol);
   pol.append(C);
   pol.append(D);
   pol.append(E);
   pol.append(F);
   poly_arc(F,G,point(0,0),pol);
   pol.append(G);
   pol.append(H);
   pol.append(I);
   pol.append(J);
   poly_arc(J,A,point(0,0),pol);

   W.draw_filled_polygon(pol,col);
   if (lw > 0) W.draw_polygon(pol,li_col);


   // D

   s0 = segment(0,d,2,d);
   s1 = segment(d+eps,0,d+eps,2);

   A = c4.intersection(s0).head();
   B = c4.intersection(s1).head();
   C = point(d+eps,d);

   D = point(1,0);
   E = point(eps,1);
   F = point(eps,0);

   pol.clear();
   pol.append(D);
   poly_arc(D,E,point(0,0),pol);
   pol.append(E);
   pol.append(F);
   W.draw_filled_polygon(pol,col);
   if (lw > 0) W.draw_polygon(pol,li_col);

   pol.clear();
   pol.append(A);
   poly_arc(A,B,point(0,0),pol);
   pol.append(B);
   pol.append(C);
   W.draw_filled_polygon(pol,bg_col);
   if (lw > 0) W.draw_polygon(pol,li_col);

   // A

   s0 = segment(1+eps,0,1+eps,2);
   s1 = segment(0,d,2,d);

   A = point(2,0);
   B = c1.intersection(s0).head();
   C = point(1+eps,0);
   D = point(1+eps+d,0);
   E = point(1+eps+d,d);
   F = c2.intersection(s1).head();
   s1 = segment(0,0,2,0);
   G = c2.intersection(s1).head();

   pol.clear();
   pol.append(A);
   poly_arc(A,B,point(0,-1),pol);
   pol.append(B);
   pol.append(C);
   pol.append(D);
   pol.append(E);
   pol.append(F);
   poly_arc(F,G,point(0,-1),pol);
   pol.append(G);
   W.draw_filled_polygon(pol,col);
   if (lw > 0) W.draw_polygon(pol,li_col);

   s0 = segment(0,2*d,2,2*d);
   s1 = segment(1+eps+d,0,1+eps+d,2);

   A = c2.intersection(s0).head();
   B = c2.intersection(s1).head();
   C = point(1+eps+d,2*d);

   pol.clear();
   pol.append(A);
   poly_arc(A,B,point(0,-1),pol);
   pol.append(B);
   pol.append(C);
   W.draw_filled_polygon(pol,bg_col);
   if (lw > 0) W.draw_polygon(pol,li_col);



   if (draw_arc)  
   { s0 = segment(-1-eps,0,-1-eps,2);
     s1 = segment( 1+eps,0, 1+eps,2);
     A = c1.intersection(s0).head();
     B = c1.intersection(s1).head();
     pol.clear();
     pol.append(A);
     poly_arc(A,B,point(0,-1),pol);
     pol.append(B);
     point p = pol.pop();
     while (!pol.empty())
     { W.draw_segment(p,pol.head());
       p  = pol.pop();
      }
    }

   if (base_line) W.draw_segment(2,0,-2,0);

}




int main()
{
   panel P("LEDA Logo");

   P.color_item("fg color",col);
   P.color_item("bg color",bg_col);
   P.color_item("line color",li_col);
   P.int_item  ("l_width",lw,0,5,1);
   P.int_item  ("vertices",N,1,120);
   P.bool_item ("draw arc",draw_arc);
   P.bool_item ("base line",base_line);

   P.button("continue",0);
   P.button("quit",1);

   W.display();
   W.set_redraw(draw_logo);
   W.init(-2.5,+2.5,-0.5);

   for(;;)
   { draw_logo();
     W.read_mouse();
     if (P.open()) break;
    }


   return 0;
}
