/* Copyright (C) 2011 Edward Der-Hua Liu, Hsin-Chu, Taiwan
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation version 2.1
 * of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <sys/stat.h>

#include "hime.h"

#include "gtab.h"
#include "pho.h"

static GtkWidget *gwin_pho_near = NULL;

static struct {
    int type;
    char group[5];
} groups[] = {
    {0, {15, 19, -1}},  // ㄓㄗ, 以 -1 做結尾
    {0, {16, 20, -1}},  // ㄔㄘ
    {0, {8, 18, -1}},   // ㄌㄖ
    {0, {4, 11, -1}},   // ㄈㄏ
    {0, {17, 21, -1}},  // ㄕㄙ
    {2, {2, 3, -1}},    // ㄛㄜ
    {2, {10, 12, -1}},  // ㄣㄥ
};

static int groupsN = sizeof (groups) / sizeof (groups[0]);

static char *find_group (int type, int num) {
    int i;

    for (i = 0; i < groupsN; i++) {
        if (groups[i].type != type)
            continue;

        char *p;
        for (p = groups[i].group; *p > 0; p++)
            if (*p == num) {
                return groups[i].group;
            }
    }

    static char alone[2] = {-1, -1};
    alone[0] = num;

    return alone;
}

void key_typ_pho (phokey_t phokey, u_char rtyp_pho[]);
gboolean get_start_stop_idx (phokey_t key, int *start_i, int *stop_i);
void close_win_pho_near ();

typedef struct {
    GtkWidget *label;
    phokey_t pk;
} NEAR_ENTRY;

static NEAR_ENTRY *near_entries;
static int near_entriesN;
gboolean add_to_tsin_buf (char *str, phokey_t *pho, int len);
void tsin_remove_last ();

static void cb_sel (GtkWidget *button, gpointer user_data) {
    NEAR_ENTRY *near_entry = &near_entries[GPOINTER_TO_INT (user_data)];
    const char *ch = gtk_label_get_text (GTK_LABEL (near_entry->label));
    char tt[CH_SZ + 1];
    strcpy (tt, ch);

    tsin_remove_last ();
    char_play (tt);
    add_to_tsin_buf (tt, &near_entry->pk, 1);

    close_win_pho_near ();
}

char *phokey2pinyin (phokey_t k);

void create_win_pho_near (phokey_t pho) {
    if (gwin_pho_near)
        close_win_pho_near ();

    gwin_pho_near = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_has_resize_grip (GTK_WINDOW (gwin_pho_near), FALSE);
    gtk_widget_realize (gwin_pho_near);
    set_no_focus (gwin_pho_near);

    GtkWidget *frame = gtk_frame_new (NULL);
    gtk_container_add (GTK_CONTAINER (gwin_pho_near), frame);

    GtkWidget *vbox_top = gtk_vbox_new (FALSE, 0);
    gtk_orientable_set_orientation (GTK_ORIENTABLE (vbox_top), GTK_ORIENTATION_VERTICAL);
    gtk_container_add (GTK_CONTAINER (frame), vbox_top);
    gtk_container_set_border_width (GTK_CONTAINER (vbox_top), 0);

    char t_typ_pho[4], mtyp_pho[4];
    key_typ_pho (pho, (u_char *) t_typ_pho);
    memcpy (mtyp_pho, t_typ_pho, 4);

    char *group0;
    char *group2;
    gboolean b_first = TRUE;

    //  dbg("zz %d %d\n",t_typ_pho[0], t_typ_pho[2]);

    for (group0 = find_group (0, t_typ_pho[0]); *group0 >= 0; group0++) {
        mtyp_pho[0] = *group0;
        //    dbg("%d\n",mtyp_pho[0]);

        for (group2 = find_group (2, t_typ_pho[2]); *group2 >= 0; group2++) {
            mtyp_pho[2] = *group2;

            for (mtyp_pho[3] = 0; mtyp_pho[3] < 5; mtyp_pho[3]++) {
                //      dbg("  %d\n",mtyp_pho[2]);
                phokey_t pk = pho2key (mtyp_pho);
                char *pho_str = pin_juyin ? phokey2pinyin (pk) : phokey_to_str (pk);

                int start_i, stop_i;

                if (!get_start_stop_idx (pk, &start_i, &stop_i))
                    continue;

                if (b_first) {
                    b_first = FALSE;
                } else {
                    GtkWidget *separator = gtk_hseparator_new ();
                    gtk_box_pack_start (GTK_BOX (vbox_top), separator, FALSE, FALSE, 0);
                }

                GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
                gtk_box_pack_start (GTK_BOX (vbox_top), hbox, FALSE, FALSE, 0);

                GtkWidget *label_pho = gtk_label_new (pho_str);
                gtk_box_pack_start (GTK_BOX (hbox), label_pho, FALSE, FALSE, 0);
                set_label_font_size (label_pho, hime_font_size_pho_near);

                int i;
                for (i = start_i; i < stop_i; i++) {
                    char tt[CH_SZ + 1];
                    memset (tt, 0, sizeof (tt));
                    utf8cpy (tt, pho_idx_str (i));

                    GtkWidget *button = gtk_button_new ();
                    gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);

                    GtkWidget *label_pho = gtk_label_new (tt);
                    gtk_container_add (GTK_CONTAINER (button), label_pho);
                    set_label_font_size (label_pho, hime_font_size_pho_near);

                    near_entries = trealloc (near_entries, NEAR_ENTRY, near_entriesN);
                    near_entries[near_entriesN].label = label_pho;
                    near_entries[near_entriesN].pk = pk;
                    g_signal_connect (G_OBJECT (button), "clicked",
                                      G_CALLBACK (cb_sel), GINT_TO_POINTER (near_entriesN));

                    near_entriesN++;
                }
            }
        }
    }

    gtk_widget_show_all (gwin_pho_near);
}

void close_win_pho_near () {
    if (!gwin_pho_near)
        return;

    gtk_widget_destroy (gwin_pho_near);
    gwin_pho_near = NULL;

    free (near_entries);
    near_entriesN = 0;
    near_entries = NULL;
}
