/* map.c --- 蝨ー蝗ウ縺ョ陦ィ遉コ
  cc map.c -g -O2 -Wall -Wno-unused-result -o map -I/usr/include/freetype2 -lftgl -lglfw -lGLU -lGL -lX11 -lXrandr -lm 
 */

#include <stdio.h>
#include <math.h>
#include <unistd.h>
#include <GL/glfw.h>
#include <FTGL/ftgl.h>

#define CROSSING_SIZE 100  /* 莠、蟾ョ轤ケ謨ー=100 */
#define MAX_NAME_SIZE  50  /* 譛€螟ァ譁�ュ玲焚50譁�ュ�(蜊願ァ�) */

/* 蠎ァ讓吝、画鋤繝槭け繝ュ縺ョ螳夂セゥ */
#define ORIGIN_X     -3.0
#define ORIGIN_Y      0.0
#define REAL_SIZE_X   8.0
#define REAL_SIZE_Y   8.0

#ifndef FONT_FILENAME
/* 繝輔か繝ウ繝医�繝輔ぃ繧、繝ォ蜷� */
#define FONT_FILENAME "/usr/share/fonts/truetype/takao-gothic/TakaoGothic.ttf"
#endif
static FTGLfont *font; /* 隱ュ縺ソ霎シ繧薙□繝輔か繝ウ繝医r蟾ョ縺吶�繧、繝ウ繧ソ */

/* 繝��繧ソ讒矩€�縺ョ螳夂セゥ */
typedef struct {
    double x, y;           /* 菴咲スョ x, y */
} Position;              /* 菴咲スョ繧定。ィ縺呎ァ矩€�菴� */

typedef struct {
    int id;                /* 莠、蟾ョ轤ケ逡ェ蜿キ */
    Position pos;          /* 菴咲スョ繧定。ィ縺呎ァ矩€�菴� */
    double wait;           /* 蟷ウ蝮�セ�■譎る俣 */
    char jname[MAX_NAME_SIZE];   /* 莠、蟾ョ轤ケ蜷�(譌・譛ャ隱�) */
    char ename[MAX_NAME_SIZE];   /* 莠、蟾ョ轤ケ蜷�(繝ュ繝シ繝槫ュ�) */
    int points;            /* 莠、蟾ョ驕楢キッ謨ー */
    int next[5];           /* 髫」謗・縺吶k莠、蟾ョ轤ケ逡ェ蜿キ */
} Crossing;

/* 繝��繧ソ繧呈�シ邏阪☆繧句、画焚縺ョ螳夂セゥ */
static Crossing cross[CROSSING_SIZE];

/* 蜀�r謠冗判 */
static void draw_circle(double x, double y, double r) {
    int const N = 12;  /* 蜀�捉繧� 12蛻�牡縺励※邱壼�縺ァ謠冗判縺吶k縺薙→縺ォ縺吶k */
    int i;

    glBegin(GL_LINE_LOOP);
    for (i = 0; i < N; i++) {
        glVertex2d(x + cos(2 * M_PI * i / N) * r,
                   y + sin(2 * M_PI * i / N) * r);
    }
    glEnd();
}

/* 譁�ュ怜�繧呈緒逕サ */
static void draw_outtextxy(double x, double y, char const *text) {
    double const scale = 0.01;
    glPushMatrix();
    glTranslated(x, y, 0.0);
    glScaled(scale, scale, scale);
    ftglRenderFont(font, text, FTGL_RENDER_ALL);
    glPopMatrix();
}

/* 繝輔ぃ繧、繝ォ縺ョ隱ュ縺ソ霎シ縺ソ */
static int map_read(char *filename) {
    FILE *fp;
    int i, j;
    int crossing_number;          /* 莠、蟾ョ轤ケ謨ー */

    fp = fopen(filename, "r");
    if (fp == NULL) {
        perror(filename);
        return -1;
    }

    /* 縺ッ縺倥a縺ォ莠、蟾ョ轤ケ謨ー繧定ェュ縺ソ霎シ繧€ */
    fscanf(fp, "%d", &crossing_number);

    for (i = 0; i < crossing_number; i++) {
        /* 髢「謨ーfprintf繧剃スソ縺」縺ヲ縲∵ァ矩€�菴薙�繝��繧ソ繧�
             繝輔ぃ繧、繝ォ縺ク譖ク縺榊�縺吶�繝ュ繧ー繝ゥ繝�繧定ィ伜�縺励↑縺輔> */

        fscanf(fp, "%d,%lf,%lf,%lf,%[^,],%[^,],%d",
                     &(cross[i].id), &(cross[i].pos.x), &(cross[i].pos.y),
                     &(cross[i].wait), cross[i].jname,
                     cross[i].ename, &(cross[i].points));

        for (j = 0; j < cross[i].points; j++) {
            fscanf(fp, ",%d", &(cross[i].next[j]));
        }

    }
    fclose(fp);

    /* 繝輔ぃ繧、繝ォ縺九i隱ュ縺ソ霎シ繧薙□莠、蟾ョ轤ケ謨ー繧定ソ斐☆ */
    return crossing_number;
}

/* 驕楢キッ邯イ縺ョ陦ィ遉コ */
static void map_show(int crossing_number) {
    int i, j;
    double x0, y0, x1, y1;

    /* 莠、蟾ョ轤ケ豈弱�繝ォ繝シ繝� */
    for (i = 0; i < crossing_number; i++) {
        x0 = cross[i].pos.x;
        y0 = cross[i].pos.y;

        /* 莠、蟾ョ轤ケ繧定。ィ縺吝�繧呈緒縺� */
        glColor3d(1.0, 0.5, 0.5);
        draw_circle(x0, y0, 0.1);

        /* 莠、蟾ョ轤ケ縺ョ蜷榊燕繧呈緒縺� */
        glColor3d(1.0, 1.0, 0.0);
        draw_outtextxy(x0, y0, cross[i].jname);

        /* 莠、蟾ョ轤ケ縺九i莨ク縺ウ繧矩%霍ッ繧呈緒縺� */
        glColor3d(1.0, 1.0, 1.0);
        glBegin(GL_LINES);
        for (j = 0; j < cross[i].points; j++) {
            x1 = cross[ cross[i].next[j] ].pos.x;
            y1 = cross[ cross[i].next[j] ].pos.y;
            glVertex2d(x0, y0);
            glVertex2d(x1, y1);
        }
        glEnd();
    }
}

int main(void) {
    int crossing_number;          /* 莠、蟾ョ轤ケ謨ー */

    /* 繧ー繝ゥ繝輔ぅ繝�け迺ー蠅�r蛻晄悄蛹悶@縺ヲ縲√え繧」繝ウ繝峨え繧帝幕縺� */
    glfwInit();
    glfwOpenWindow(640, 640, 0, 0, 0, 0, 0, 0, GLFW_WINDOW);

    /* (ORIGIN_X, ORIGIN_Y) 繧剃クュ蠢�↓縲ヽEAL_SIZE_X * REAL_SIZE_Y 縺ョ遽�峇縺ョ
         遨コ髢薙r繝薙Η繝シ繝昴�繝医↓謚募スア縺吶k */
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(ORIGIN_X + REAL_SIZE_X * -0.5, ORIGIN_X + REAL_SIZE_X * 0.5,
            ORIGIN_Y + REAL_SIZE_Y * -0.5, ORIGIN_Y + REAL_SIZE_Y * 0.5,
            -1.0, 1.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();             /* 縺昴l莉・螟悶�蠎ァ讓吝、画鋤縺ッ陦後o縺ェ縺� */

    /* 譁�ュ怜�謠冗判縺ョ縺溘a縺ョ繝輔か繝ウ繝医�隱ュ縺ソ霎シ縺ソ縺ィ險ュ螳� */
    font = ftglCreateExtrudeFont(FONT_FILENAME);
    if (font == NULL) {
        perror(FONT_FILENAME);
        fprintf(stderr, "could not load font\n");
        exit(1);
    }
    ftglSetFontFaceSize(font, 24, 24);
    ftglSetFontDepth(font, 0.01);
    ftglSetFontOutset(font, 0, 0.1);
    ftglSetFontCharMap(font, ft_encoding_unicode);

    /* 繝槭ャ繝励ヵ繧。繧、繝ォ縺ョ隱ュ縺ソ霎シ縺ソ */
    crossing_number = map_read("map2.dat");
    if (crossing_number < 0) {
        fprintf(stderr, "couldn't read map file\n");
        exit(1);
    }

    while (1) {
        int width, height;

        /* Esc 縺梧款縺輔l繧九°繧ヲ繧」繝ウ繝峨え縺碁哩縺倥i繧後◆繧峨♀縺励∪縺� */
        //glfwWaitEvents();
        if (glfwGetKey(GLFW_KEY_ESC) || !glfwGetWindowParam(GLFW_OPENED))
            break;

        glfwGetWindowSize(&width, &height);  /* 迴セ蝨ィ縺ョ繧ヲ繧」繝ウ繝峨え繧オ繧、繧コ繧貞叙蠕励☆繧� */
        glViewport(0, 0, width, height);  /* 繧ヲ繧」繝ウ繝峨え蜈ィ髱「繧偵ン繝・繝シ繝昴�繝医↓縺吶k */

        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT);  /* 繝舌ャ繧ッ繝舌ャ繝輔ぃ繧帝サ偵〒蝪励j貎ー縺� */

        map_show(crossing_number);  /* 驕楢キッ邯イ縺ョ陦ィ遉コ */
        glfwSwapBuffers();  /* 繝輔Ο繝ウ繝医ヰ繝�ヵ繧。縺ィ繝舌ャ繧ッ繝舌ャ繝輔ぃ繧貞�繧梧崛縺医k */
    }

    glfwTerminate();

    return 0;
}