Index: menu.c
===================================================================
--- menu.c	(revision 292)
+++ menu.c	(revision 293)
@@ -6,8 +6,16 @@
 #include "rectangle.h"
 #include "proj_func.h"
 #include "proj_macros.h"
+#include "errors.h"
 
+const int W  = 400;
+const int H  = 60;
+const int W1 = 40;
+const int H1 = 40;
+const int H2 = 20;
+
 struct menu {
+    const font_t *fnt;
     size_t sz;
     rectangle_t **r;
     text_t      **t;
@@ -18,6 +26,7 @@
     if(fnt == NULL) return NULL;
     menu_t *ret = (menu_t*)malloc(sizeof(menu_t));
     if (ret == NULL) return NULL;
+    ret->fnt = fnt;
     ret->sz = 0;
     ret->r = NULL;
     ret->t = NULL;
@@ -28,126 +37,73 @@
     rectangle_set_outline_color(ret->frame, GRAPH_WHITE);
     rectangle_set_fill_trans(ret->frame, GRAPH_TRANSPARENT);
 
+    menu_add_item(ret, "Play");
+    menu_add_item(ret, "Test");
+    menu_add_item(ret, "Exit");
 
-    ret->sz = 3;
-    ret->r = realloc(ret->r, ret->sz*sizeof(rectangle_t*));
-    ret->t = realloc(ret->t, ret->sz*sizeof(text_t     *));
-    ret->r[0] = rectangle_ctor(0, 0, 400, 100);
-    ret->r[1] = rectangle_ctor(0, 0, 400, 100);
-    ret->r[2] = rectangle_ctor(0, 0, 400, 100);
-    ret->t[0] = text_ctor(fnt, "Play");
-    ret->t[1] = text_ctor(fnt, "Test");
-    ret->t[2] = text_ctor(fnt, "Exit");
+    return ret;
+}
 
-    if (ret->r[0] == NULL || ret->r[1] == NULL || ret->r[2] == NULL ||
-        ret->t[0] == NULL || ret->t[1] == NULL || ret->t[2] == NULL ||
-        ret->frame == NULL) return NULL;
-    // VISUAL
-    rectangle_set_fill_color(ret->r[0], GRAPH_BLACK);
-    rectangle_set_outline_width(ret->r[0], 2);
-    rectangle_set_outline_color(ret->r[0], GRAPH_WHITE);
-    rectangle_set_fill_trans(ret->r[0], GRAPH_TRANSPARENT);
+static int menu_recalculate(menu_t *menu){
+    const int Wtotal = 2*W1+W;
+    const int Htotal = 2*H1+menu->sz*H+(menu->sz-1)*H2;
+    int x = graph_get_XRes()/2-Wtotal/2;
+    int y = graph_get_YRes()/2-Htotal/2;
+    rectangle_set_pos (menu->frame, x, y);
+    rectangle_set_size(menu->frame, Wtotal, Htotal);
+    x += W1; y += H1;
+    for(size_t i = 0; i < menu->sz; ++i, y+=H+H2){
+        rectangle_set_pos(menu->r[i], x, y);
+        text_set_pos     (menu->t[i], x+W/2, y+H/2);
+    }
+    return SUCCESS;
+}
 
-    rectangle_set_fill_color(ret->r[1], GRAPH_BLACK);
-    rectangle_set_outline_width(ret->r[1], 2);
-    rectangle_set_outline_color(ret->r[1], GRAPH_WHITE);
-    rectangle_set_fill_trans(ret->r[1], GRAPH_TRANSPARENT);
+int (menu_add_item)(menu_t *menu, const char *s){
+    rectangle_t *r = rectangle_ctor(0, 0, W, H);
+    text_t      *t = text_ctor(menu->fnt, s);
+    if(r == NULL || t == NULL){
+        rectangle_dtor(r);
+        text_dtor(t);
+        return NULL_PTR;
+    }
+    rectangle_set_fill_color   (r, GRAPH_BLACK);
+    rectangle_set_outline_width(r, 2);
+    rectangle_set_outline_color(r, GRAPH_WHITE);
 
-    rectangle_set_fill_color(ret->r[2], GRAPH_BLACK);
-    rectangle_set_outline_width(ret->r[2], 2);
-    rectangle_set_outline_color(ret->r[2], GRAPH_WHITE);
-    rectangle_set_fill_trans(ret->r[2], GRAPH_TRANSPARENT);
+    text_set_valign(t, text_valign_center);
+    text_set_halign(t, text_halign_center);
+    text_set_color (t, TEXT_COLOR);
 
-    text_set_valign(ret->t[0], text_valign_center);
-    text_set_halign(ret->t[0], text_halign_center);
-    text_set_color(ret->t[0], TEXT_COLOR);
+    ++menu->sz;
+    menu->r = realloc(menu->r, menu->sz*sizeof(rectangle_t*));
+    menu->t = realloc(menu->t, menu->sz*sizeof(text_t     *));
+    menu->r[menu->sz-1] = r;
+    menu->t[menu->sz-1] = t;
 
-    text_set_valign(ret->t[1], text_valign_center);
-    text_set_halign(ret->t[1], text_halign_center);
-    text_set_color(ret->t[1], TEXT_COLOR);
-
-    text_set_valign(ret->t[2], text_valign_center);
-    text_set_halign(ret->t[2], text_halign_center);
-    text_set_color(ret->t[2], TEXT_COLOR);
-    // POSITIONS
-    rectangle_set_pos(ret->r[0],
-                      graph_get_XRes()/2    - rectangle_get_w(ret->r[0])/2,
-                      graph_get_YRes()*0.35 - rectangle_get_h(ret->r[0])/2);
-
-
-    rectangle_set_pos(ret->r[1],
-                    graph_get_XRes()/2    - rectangle_get_w(ret->r[1])/2,
-                    graph_get_YRes()*0.5 - rectangle_get_h(ret->r[1])/2);
-
-
-    rectangle_set_pos(ret->r[2],
-                  graph_get_XRes()/2    - rectangle_get_w(ret->r[2])/2,
-                  graph_get_YRes()*0.65 - rectangle_get_h(ret->r[2])/2);
-
-    text_set_pos(ret->t[0], rectangle_get_x(ret->r[0])+rectangle_get_w(ret->r[0])/2,
-                          rectangle_get_y(ret->r[0])+rectangle_get_h(ret->r[0])/2);
-
-    text_set_pos(ret->t[1], rectangle_get_x(ret->r[1])+rectangle_get_w(ret->r[1])/2,
-                          rectangle_get_y(ret->r[1])+rectangle_get_h(ret->r[1])/2);
-
-    text_set_pos(ret->t[2], rectangle_get_x(ret->r[2])+rectangle_get_w(ret->r[2])/2,
-                          rectangle_get_y(ret->r[2])+rectangle_get_h(ret->r[2])/2);
-
-    rectangle_set_pos(ret->frame,
-                  graph_get_XRes()/2    - rectangle_get_w(ret->frame)/2,
-                  graph_get_YRes()*0.5 - rectangle_get_h(ret->frame)/2);
-    return ret;
+    return menu_recalculate(menu);
 }
 
 int (menu_update_state)(menu_t *menu, int click) {
-
-    if (rectangle_collide_point(menu->r[0], *get_mouse_X(), *get_mouse_Y())) {
-        highlighted = GAME;
-        if (click) return GAME;
-    } else if (rectangle_collide_point(menu->r[1], *get_mouse_X(), *get_mouse_Y())) {
-        highlighted = TEST;
-        if (click) return TEST;
-    } else if (rectangle_collide_point(menu->r[2], *get_mouse_X(), *get_mouse_Y())) {
-        highlighted = EXIT;
-        if (click) return EXIT;
-    } else {
-        highlighted = -1;
-    }
-    return MENU;
+    if(!click) return -1;
+    for(size_t i = 0; i < menu->sz; ++i)
+        if(rectangle_collide_point(menu->r[i], *get_mouse_X(), *get_mouse_Y()))
+            return i;
+    return -1;
 }
 
 void (menu_draw)(menu_t *menu) {
     rectangle_draw(menu->frame);
-    switch (highlighted) {
-    case GAME:
-        rectangle_set_fill_color(menu->r[0], HIGHLIGHT_COLOR);
-        rectangle_draw(menu->r[0]);
-        rectangle_draw(menu->r[1]);
-        rectangle_draw(menu->r[2]);
-        rectangle_set_fill_color(menu->r[0], GRAPH_BLACK);
-        break;
-    case TEST:
-        rectangle_set_fill_color(menu->r[1], HIGHLIGHT_COLOR);
-        rectangle_draw(menu->r[0]);
-        rectangle_draw(menu->r[1]);
-        rectangle_draw(menu->r[2]);
-        rectangle_set_fill_color(menu->r[1], GRAPH_BLACK);
-        break;
-    case EXIT:
-        rectangle_set_fill_color(menu->r[2], HIGHLIGHT_COLOR);
-        rectangle_draw(menu->r[0]);
-        rectangle_draw(menu->r[1]);
-        rectangle_draw(menu->r[2]);
-        rectangle_set_fill_color(menu->r[2], GRAPH_BLACK);
-        break;
-    default:
-        rectangle_draw(menu->r[0]);
-        rectangle_draw(menu->r[1]);
-        rectangle_draw(menu->r[2]);
-        break;
+    int x = *get_mouse_X(), y = *get_mouse_Y();
+    for(size_t i = 0; i < menu->sz; ++i){
+        if(rectangle_collide_point(menu->r[i], x, y))
+            rectangle_set_fill_color(menu->r[i], HIGHLIGHT_COLOR);
+        rectangle_draw(menu->r[i]);
+        text_draw     (menu->t[i]);
     }
     for(size_t i = 0; i < menu->sz; ++i)
-        text_draw(menu->t[i]);
+        if(rectangle_collide_point(menu->r[i], x, y))
+            rectangle_set_fill_color(menu->r[i], GRAPH_BLACK);
 }
 
 void (menu_dtor)(menu_t *p){
