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

void scroll_up(window& W, double ymax, double fh)
{ int d = 5;
  for(int y = 0; y < fh; y+=d)
    W.copy_rect(W.xmin(),W.ymin()+10,W.xmax()-10,ymax-d,W.xmin(),ymax); 
 }


void anchor(window& W, double x, double y, double f)
{
  list<point> poly;
  poly.append(point(x-0.5*f,y+0.0*f));
  poly.append(point(x-0.5*f,y-4.5*f));
  poly.append(point(x-2.0*f,y-3.0*f));
  poly.append(point(x-1.5*f,y-2.5*f));
  poly.append(point(x-3.25*f,y-2.5*f));
  poly.append(point(x-3.25*f,y-4.25*f));
  poly.append(point(x-2.75*f,y-3.75*f));
  poly.append(point(x-0.5*f,y-6.0*f));

  poly.append(point(x+0.5*f,y-6.0*f));
  poly.append(point(x+2.75*f,y-3.75*f));
  poly.append(point(x+3.25*f,y-4.25*f));
  poly.append(point(x+3.25*f,y-2.5*f));
  poly.append(point(x+1.5*f,y-2.5*f));
  poly.append(point(x+2.0*f,y-3.0*f));
  poly.append(point(x+0.5*f,y-4.5*f));
  poly.append(point(x+0.5*f,y+0.0*f));


  W.draw_filled_polygon(poly,black);
  //W.draw_disc(x+0.0*f,y+0.0*f,0.500*f,black);
  //W.draw_disc(x+0.0*f,y-4.0*f,0.707*f,black);
}


void ship(window& W, double x, double y, double fx, double fy,
                   color c0, color c1, color c2, color c3)
{ list<point> poly1;
  poly1.append(point(x+ 0.0*fx,y+3.0*fy));
  poly1.append(point(x+ 2.0*fx,y+0.0*fy));
  poly1.append(point(x+11.0*fx,y+0.0*fy));
  poly1.append(point(x+12.5*fx,y+3.0*fy));
  poly1.append(point(x+11.0*fx,y+2.5*fy));
  poly1.append(point(x+ 3.0*fx,y+2.5*fy));

  list<point> poly2;
  poly2.append(point(x+ 3.0*fx,y+2.5*fy));
  poly2.append(point(x+10.0*fx,y+2.5*fy));
  poly2.append(point(x+ 9.0*fx,y+4.0*fy));
  poly2.append(point(x+ 3.5*fx,y+4.0*fy));

  list<point> poly3;
  poly3.append(point(x+4.5*fx,y+4.0*fy));
  poly3.append(point(x+8.5*fx,y+4.0*fy));
  poly3.append(point(x+7.5*fx,y+5.0*fy));
  poly3.append(point(x+5.0*fx,y+5.0*fy));

  list<point> poly4;
  poly4.append(point(x+6.0*fx,y+5.0*fy));
  poly4.append(point(x+7.0*fx,y+5.0*fy));
  poly4.append(point(x+7.0*fx,y+6.0*fy));
  poly4.append(point(x+6.5*fx,y+6.0*fy));

  W.draw_filled_polygon(poly1,c0);
  W.draw_polygon(poly1,black);

  W.draw_filled_polygon(poly2,c1);
  W.draw_polygon(poly2,black);

  W.draw_filled_polygon(poly3,c2);
  W.draw_polygon(poly3,black);

  W.draw_filled_polygon(poly4,c3);

  W.draw_filled_rectangle(x+3.75*fx,y+3.0*fy,x+5.25*fx,y+3.5*fy,grey1);
  W.draw_rectangle(x+3.75*fx,y+3.0*fy,x+5.25*fx,y+3.5*fy,black);

  W.draw_filled_rectangle(x+5.75*fx,y+3.0*fy,x+7.25*fx,y+3.5*fy,grey1);
  W.draw_rectangle(x+5.75*fx,y+3.0*fy,x+7.25*fx,y+3.5*fy,black);

  W.draw_filled_rectangle(x+7.75*fx,y+3.0*fy,x+9.0*fx,y+3.5*fy,grey1);
  W.draw_rectangle(x+7.75*fx,y+3.0*fy,x+9.0*fx,y+3.5*fy,black);

  //W.draw_disc(x+1.75*fx,y+2.25*fy,0.2*fx,white);
  //W.draw_circle(x+1.75*fx,y+2.25*fy,0.2*fx,black);

  anchor(W,x+1.3*fx,y+2.3*fy,5);

}

void locomotive(window& W, double x, double y, double f, color col1, color col2)
{ 
  list<point> poly;
  poly.append(point(x+0.5*f,y+1.0*f));
  poly.append(point(x+0.5*f,y+3.0*f));
  poly.append(point(x+4.0*f,y+3.0*f));
  poly.append(point(x+4.0*f,y+4.5*f));
  poly.append(point(x+3.5*f,y+4.5*f));
  poly.append(point(x+3.5*f,y+5.0*f));
  poly.append(point(x+7.0*f,y+5.0*f));
  poly.append(point(x+7.0*f,y+4.5*f));
  poly.append(point(x+6.5*f,y+4.5*f));
  poly.append(point(x+6.5*f,y+1.0*f));

  W.draw_filled_polygon(poly,col1);
  W.draw_polygon(poly,black);
  W.draw_disc  (x+1.75*f, y+f, 0.72*f,col2);
  W.draw_circle(x+1.75*f, y+f, 0.72*f,black);
  W.draw_filled_node(x+1.75*f, y+f,black);
  W.draw_disc  (x+5.25*f, y+f, 0.72*f,red);
  W.draw_circle(x+5.25*f, y+f, 0.72*f,black);
  W.draw_filled_node(x+5.25*f, y+f,black);

  W.draw_filled_rectangle(x+4.6*f,y+3*f,x+5.9*f,y+4.0*f,white);
  W.draw_rectangle       (x+4.6*f,y+3*f,x+5.9*f,y+4.0*f,black);
  W.draw_filled_rectangle(x+1.1*f,y+3*f,x+1.9*f,y+4.0*f,black);

  W.draw_filled_rectangle(x+6.50*f,y+1.3*f,x+7.35*f,y+1.5*f,black);
  W.draw_segment(x+7.35*f,y+1.0*f,x+7.35*f,y+1.8*f,black);
}


void waggon(window& W, double x, double y, double f, color col1, color col2)
{
  list<point> poly;
  poly.append(point(x+0.5*f,y+1.0*f));
  poly.append(point(x+0.5*f,y+4.0*f));
  poly.append(point(x+0.0*f,y+4.0*f));
  poly.append(point(x+0.0*f,y+4.5*f));
  poly.append(point(x+7.0*f,y+4.5*f));
  poly.append(point(x+7.0*f,y+4.0*f));
  poly.append(point(x+6.5*f,y+4.0*f));
  poly.append(point(x+6.5*f,y+1.0*f));

  W.draw_filled_rectangle(x-0.35*f,y+1.3*f,x+0.50*f,y+1.5*f,black);
  W.draw_segment(x-0.35*f,y+1.0*f,x-0.35*f,y+1.8*f,black);

  W.draw_filled_polygon(poly,col1);
  W.draw_polygon(poly,black);
  W.draw_disc  (x+1.75*f, y+f, 0.72*f,col2);
  W.draw_circle(x+1.75*f, y+f, 0.72*f,black);
  W.draw_filled_node(x+1.75*f, y+f,black);
  W.draw_disc  (x+5.25*f, y+f, 0.72*f,col2);
  W.draw_circle(x+5.25*f, y+f, 0.72*f,black);
  W.draw_filled_node(x+5.25*f, y+f,black);

  W.draw_box      (x+1.50*f,y+2.5*f,x+2.75*f,y+3.5*f,white);
  W.draw_rectangle(x+1.50*f,y+2.5*f,x+2.75*f,y+3.5*f,black);
  W.draw_box      (x+4.25*f,y+2.5*f,x+5.50*f,y+3.5*f,white);
  W.draw_rectangle(x+4.25*f,y+2.5*f,x+5.50*f,y+3.5*f,black);

  W.draw_filled_rectangle(x+6.50*f,y+1.3*f,x+7.35*f,y+1.5*f,black);
  W.draw_segment(x+7.35*f,y+1.0*f,x+7.35*f,y+1.8*f,black);
}


char* make_train(window& W, int f, color c0, color c1, color c2, color c3)
{ //locomotive(W,0,10,f,c0,c3);
  //waggon(W,  8*f,10,f,c1,c0);
  //waggon(W, 16*f,10,f,c2,c1);
  //waggon(W, 24*f,10,f,c3,c2);
  ship(W,0,10,1.5*f,f,c0,c1,c2,c3);
  char* map = W.get_pixrect(0.25*f,10+0.25*f,33*f,10+5.75*f);
  W.clear();
  return map;
}


char* fname[9] = {"0","1","2","3","4","5","6","7","8"};



int main()
{
   int scale = 4;
   color col = blue;

   color loc_col  = cyan;
   color wag1_col = red;
   color wag2_col = yellow;
   color wag3_col = blue;

   window W(630,430, "Tim's erstes Schreibprogramm");
   W.init(0,1000,0);
   W.set_text_mode(opaque);
   W.set_node_width(1);
   W.open(window::center,window::center);

   panel P;
   P.color_item("Lokomotive",loc_col);
   P.color_item("Waggon 1",wag1_col);
   P.color_item("Waggon 2",wag2_col);
   P.color_item("Waggon 3",wag3_col);
   P.color_item("Farbe",col);
   P.int_item("Groesse",scale,1,8,1);

   W.set_font(fname[scale]);

   int fw = (int)W.text_width("H");
   int fh = (int)W.text_height("H");

   int clen = 960/fw;

   int xmin = 20;
   int xmax = xmin + (clen-1)*fw;
   int ymin = fh;
   int ymax = int(W.ymax() - 100);

   int x = xmin;
   int y = ymax;

   double train_x = 500;
   double train_d = -3;
   int    train_steps = 100;

   int F = 15;

   char* train_image = make_train(W,F,loc_col,wag1_col,wag2_col,wag3_col);


   W.draw_hline(ymax+10);
   W.draw_box(W.xmin(),ymax,W.xmax(),ymax+10,blue);
   W.put_pixrect(train_x,W.ymax()-5.5*(F+1),train_image);

   W.draw_text(x,y,"_",col);

   for(;;)
   { int val;
     double a,b;

     int e = W.get_event(val,a,b);

     switch (e) 
     { 
        case no_event:
                  { if (train_steps >= 50) break;
                    train_x += train_d;
                    W.put_pixrect(train_x,W.ymax()-5.5*(F+1),train_image);
                    if (train_x < W.xmin()-480) train_x = W.xmax(); 
                    train_steps++;
                    break;
                   }


        case button_press_event:
                { if (val  == MOUSE_BUTTON(3))
                  { W.load_text_font("1");
                    P.open(W);
                    train_image = make_train(W,F,loc_col,wag1_col,wag2_col,
                                                                  wag3_col);
                    W.load_text_font(string("%d",scale));
                    fw = (int)W.text_width("H");
                    fh = (int)W.text_height("H");
                    clen = 960/fw;
                    xmax = xmin + (clen-1)*fw;
                   }
                  W.clear();
                  W.draw_hline(ymax+10);
                  W.draw_box(W.xmin(),ymax,W.xmax(),ymax+10,blue);
                  W.put_pixrect(train_x,W.ymax()-5.5*(F+1),train_image);
                  x = xmin;
                  y = ymax;
                  W.draw_text(x,y,"_",col);
                  W.draw_hline(ymax+10);
                  W.draw_box(W.xmin(),ymax,W.xmax(),ymax+10,blue);
                  break;
                 }
           
        case key_press_event: 
                { char c = (char)val;
                  train_steps = 0;

                  if (c == 8) // back-space
                  { W.draw_text(x,y," ",col);
                    x -= fw;
                    if (x < -5)
                    { x = xmax;
                      y += fh;
                     }
                    if (y > ymax)
                    { y = ymax;
                      x = xmin;
                     }
                    W.draw_text(x,y,"_",col);
                    break;
                   }

                  if (c == 13)   // return
                    { W.draw_text(x,y," ",col);
                      x = xmax+1;
                     }
                  else
                    if (isprint(c))
                    { W.draw_text(x,y,toupper(c),col);
                      x += fw;
                     }

                  if (x > xmax)
                  { x = xmin;
                    y -= fh;
                    if (y < ymin)
                    { scroll_up(W,ymax,fh);
                      y += fh;
                     }
                   }

                  W.draw_text(x,y,"_",col);
                  break;
                 }


       }

   }

  return 0;

}



