#include <string.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <time.h>

#include "mmyth_epg_grid_view.h"
#include "mmyth_epg_grid_widget.h"

/*
 * Service genre 
 */
#define GENRE_MIN               0
#define GENRE_MAX               10
#define GENRE_UNDEFINED         0
#define GENRE_MOVIE             1
#define GENRE_NEWS              2
#define GENRE_SHOW              3
#define GENRE_SPORTS            4
#define GENRE_CHILDREN          5
#define GENRE_MUSIC             6
#define GENRE_CULTURE           7
#define GENRE_SOCIAL            8
#define GENRE_EDUCATION         9
#define GENRE_LEISURE           10

#define NRO_HOURS 3

/*
 * Function prototypes
 */
static void     update_service_details(MMythEpgGridWidget * object,
                                       gpointer arg1, gpointer user_data);
static gboolean key_press_epg_grid_view(GtkWidget * widget,
                                        GdkEventKey * event,
                                        gpointer user_data);

static GtkWidget *mmyth_epg_grid_widget = NULL;

/*
 * is a GtkEventBox 
 */
static GtkWidget *program_details_area = NULL;
static GtkWidget *details_main_hbox = NULL;
static GtkWidget *details_vbox = NULL;
static GtkWidget *details_logo_vbox = NULL;

/*
 * update signal callback from MMythEpgGridWidget 
 */
static void
update_service_details(MMythEpgGridWidget * object, gpointer arg1,
                       gpointer user_data)
{
    g_return_if_fail(arg1 != NULL);

    EpgGridItem    *epg_grid_item = (EpgGridItem *) arg1;

    gchar           sel_prog_desc[100] = "<big><b>";
    gchar           time_buffer[50];

    /*
     * FIXME: get first content from content_list
     */
    GMythProgramInfo *proginfo =
        (GMythProgramInfo *) epg_grid_item->proginfo;

    if (proginfo) {
        GString        *prog_name = proginfo->title;
        GString        *service_name = proginfo->chanid;

        if (details_vbox != NULL)
            gtk_container_remove(GTK_CONTAINER(details_main_hbox),
                                 details_vbox);

        /*
         * update service description 
         */
        strcat(sel_prog_desc, service_name->str);
        strcat(sel_prog_desc, "</b></big>");

        GtkWidget      *fst_line_lbl = gtk_label_new(NULL);
        gtk_misc_set_alignment(GTK_MISC(fst_line_lbl), 0.0, 0.0);
        gtk_label_set_markup(GTK_LABEL(fst_line_lbl), sel_prog_desc);

        /*
         * freeing char[] 
         */
        sel_prog_desc[0] = 0;
        strcat(sel_prog_desc, "\t");
        strcat(sel_prog_desc, prog_name->str);

        struct tm       loctime_start,
                        loctime_end;

        // Convert it to local time representation. 
        /*
         * FIXME: conversion from time to localtime is different in
         * different machines 
         */
        long int        schedule_start_time = proginfo->startts->tv_sec;
        long int        schedule_end_time = proginfo->endts->tv_sec;

        if (localtime_r(&schedule_start_time, &loctime_start) == NULL) {
            g_warning("localtime_r error in mmyth_epg_grid_view!\n");
        }
#if 0
        fprintf(stderr, asctime(loctime_start));
#endif

        strftime(time_buffer, 100, "  %H:%M - ", &loctime_start);
        strcat(sel_prog_desc, time_buffer);

        if (localtime_r(&schedule_end_time, &loctime_end) == NULL) {
            g_warning("localtime_r error in mmyth_epg_grid_view!\n");
        }
#if 0
        fprintf(stderr, asctime(loctime_end));
#endif

        strftime(time_buffer, 100, "%H:%M\n", &loctime_end);
        strcat(sel_prog_desc, time_buffer);

        GtkWidget      *snd_line_lbl = gtk_label_new(NULL);
        gtk_misc_set_alignment(GTK_MISC(snd_line_lbl), 0.0, 0.0);
        gtk_label_set_markup(GTK_LABEL(snd_line_lbl), sel_prog_desc);

        // add the current selected program description to the label
        details_vbox = gtk_vbox_new(FALSE, 0);
        GtkWidget      *fst_line_hbox = gtk_hbox_new(FALSE, 0);

        gtk_box_pack_start(GTK_BOX(fst_line_hbox),
                           fst_line_lbl, FALSE, FALSE, 6);
        gtk_box_pack_start(GTK_BOX(details_vbox),
                           fst_line_hbox, FALSE, FALSE, 0);
        gtk_box_pack_start(GTK_BOX(details_vbox),
                           snd_line_lbl, FALSE, FALSE, 0);
        gtk_box_pack_start(GTK_BOX(details_main_hbox),
                           details_vbox, FALSE, FALSE, 0);

        gtk_widget_show_all(details_main_hbox);
    }
}

/*
 * Callback for hardware keys 
 */
static          gboolean
key_press_epg_grid_view(GtkWidget * widget,
                        GdkEventKey * event, gpointer user_data)
{
    MMythEpgGridWidget *mmyth_epg_grid_widget =
        (MMythEpgGridWidget *) user_data;

    return mmyth_epg_grid_widget_key_press(mmyth_epg_grid_widget, widget,
                                           event);
}

GtkWidget      *
epg_grid_view_new(MMythUi * mmyth_ui)
{
    GtkWidget      *scrolled_window;
    scrolled_window = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
                                   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);

    gtk_widget_modify_bg(scrolled_window, GTK_STATE_NORMAL,
                         &main_bg_color);

    GtkWidget      *main_vbox = gtk_vbox_new(FALSE, 0);
    // gtk_container_set_border_width(main_vbox, 4); 

    GtkWidget      *details_event_box = gtk_event_box_new();
    gtk_widget_modify_bg(details_event_box, GTK_STATE_NORMAL,
                         &main_bg_color);

    program_details_area = gtk_vbox_new(FALSE, 0);
    gtk_container_add(GTK_CONTAINER(details_event_box),
                      program_details_area);
    gtk_container_set_border_width(GTK_CONTAINER(program_details_area), 4);

    details_main_hbox = gtk_hbox_new(FALSE, 10);

    gtk_box_pack_start(GTK_BOX(program_details_area),
                       details_main_hbox, FALSE, FALSE, 0);

    details_logo_vbox = gtk_vbox_new(FALSE, 0);

    GtkWidget      *details_desc_vbox = gtk_vbox_new(FALSE, 0);

    gtk_box_pack_start(GTK_BOX(details_main_hbox),
                       details_desc_vbox, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(details_main_hbox),
                       details_logo_vbox, FALSE, FALSE, 0);

    gtk_widget_set_size_request(program_details_area, -1, 120);

    mmyth_epg_grid_widget = mmyth_epg_grid_widget_new();
    g_signal_connect(mmyth_epg_grid_widget, "selection_updated",
                     G_CALLBACK(update_service_details), NULL);

    /*
     * select by default the first service 
     */
    /*
     * depends on mount services 
     */
    if (MMYTH_EPG_GRID_WIDGET(mmyth_epg_grid_widget)->epg_view_model) {
        GList          *fst_service = (GList *)
            MMYTH_EPG_GRID_WIDGET(mmyth_epg_grid_widget)->epg_view_model->
            data;
        mmyth_epg_grid_widget_update_service(MMYTH_EPG_GRID_WIDGET
                                             (mmyth_epg_grid_widget),
                                             fst_service);
    }

    gtk_box_pack_start(GTK_BOX(main_vbox),
                       details_event_box, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(main_vbox),
                       gtk_hseparator_new(), FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(main_vbox),
                       mmyth_epg_grid_widget, FALSE, FALSE, 0);

    gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW
                                          (scrolled_window), main_vbox);

    /*
     * Add hardware button listener to application 
     */
    g_signal_connect(mmyth_ui->main_window, "key_press_event",
                     G_CALLBACK(key_press_epg_grid_view),
                     mmyth_epg_grid_widget);

    gtk_widget_show_all(scrolled_window);

    return scrolled_window;
}

/*
 * DVBHScheduleEvent * mmyth_epg_grid_view_get_selected_schedule() {
 * return mmyth_epg_grid_get_selected_schedule
 * (MMYTH_EPG_GRID_WIDGET(mmyth_epg_grid_widget)); } 
 */