#include <gtk/gtk.h> /* libgtk-3-dev */
#define HANDY_USE_UNSTABLE_API
#include <handy.h>

#include <calculations.h>
#include <webconnection.h>
#include <handler.h>
#include <plot.h>

/* TODO
 * Clock should show allways TWO digits
 * Make everything translatable
 * Timezone does not change when selecting a date in summer time for example */

GtkWidget *window;
GtkWidget *button_search;
GtkWidget *button_now;
GtkWidget *button_calculate;
GtkWidget *label_heading;
GtkWidget *box_scale;
GtkWidget *scale_button;

GtkEntry *north_entry;
GtkEntry *east_entry;
GtkEntry *location_entry;

GtkSearchEntry *searchentry;

GtkSpinButton *entry_min;
GtkSpinButton *entry_hour;
GtkSpinButton *entry_day;
GtkSpinButton *entry_year;

GtkComboBox *entry_month;

GtkBuilder *builder;

HdySqueezer *squeezer;
HdyViewSwitcher *view_switcher;
HdyViewSwitcherBar *switcher_bar;

int time_utc[6];
float latitude;
float longitude;
gboolean plotted = FALSE;

/* Button Search */
static int search(GtkWidget *widget, gpointer data)
{
  char east_text[10];
  char north_text[10];

  double east;
  double north;

  const char *displayText;
  const char *const_east_text;
  const char *const_north_text;

  const gchar *searchtext;

	/* Get the Text from the GtkSearchEntry field */
	searchtext = gtk_entry_get_text(GTK_ENTRY(searchentry));

  if (strlen(searchtext)<1)
	{
    /* Do not search if search entry is emty */
		return 0;
	}
	g_print("Location to search for: %s\n", searchtext);

  /* Use webconnection.c with curl to serach at nominatim for a result */
  struct Output *search_result = search_nominatim (searchtext);

  east = search_result->east;
  north = search_result->north;
  displayText = search_result->displayText;

  g_print("Output of Search: %s, North: %f, East: %f\n",displayText, east, north);

  sprintf(east_text, "%f", east);
  const_east_text = east_text;
  gtk_entry_set_text(east_entry, const_east_text);

  sprintf(north_text, "%f", north);
  const_north_text = north_text;
  gtk_entry_set_text(north_entry, const_north_text);

  gtk_entry_set_text(location_entry, displayText);

  /* Inform the user if there is no search result available */
  if (displayText == NULL){gtk_entry_set_text(location_entry, "No result found or no connection to server!");}
  else { gtk_window_set_focus (GTK_WINDOW(window), button_calculate);}

  return 1;
}

static int correct_time (GtkWidget *widget, gpointer data){
  /* This function is used to choose the correct maximum available days at a spesific year and month
   * For example: January 2020 has 31 days max February 2020 has 29 but February 2019 had only 28
   * It should not be possible to choose a day that does not exist */

  double entry_day_double;
  const char *entry_month_string;
  double entry_year_double;

  entry_day_double = gtk_spin_button_get_value (entry_day);
  entry_month_string = gtk_combo_box_get_active_id (entry_month);
  entry_year_double = gtk_spin_button_get_value (entry_year);

  int max_days = max_day_in_month (atoi(entry_month_string), (int)entry_year_double);

  /* adjust the max. day that can be set */
  GtkAdjustment *d_adjust;
  d_adjust = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "d_adjustment"));
  gtk_adjustment_set_upper (d_adjust, max_days);

  /* if the day has already been set to a day higher than the highest possible day in this month set it to the max. possible day */
  if (entry_day_double>max_days) {
    gtk_spin_button_set_value (entry_day, max_days);
  }

  g_print("Day entry: %d\n", (int)entry_day_double);
  g_print("Month entry: %i\n", atoi(entry_month_string));
  g_print("Max days: %i\n", max_days);
  return 1;
}

static int set_time_now (GtkWidget *widget, gpointer data){
  g_print("Now\n");
  int time_utc_now[6];
  int time_local[6];
  calc_time_utc (time_utc_now);
  utc_zone_to_time (time_utc_now, time_local);
  gtk_spin_button_set_value (entry_year, *(time_local));
  gtk_combo_box_set_active (entry_month, *(time_local+1)-1);
  gtk_spin_button_set_value (entry_day, *(time_local+2));
  gtk_spin_button_set_value (entry_hour, *(time_local+3));
  gtk_spin_button_set_value (entry_min, *(time_local+4));
  return 1;
}

/* Button calculate */
static int calculate (GtkWidget *widget,  gpointer data)
{
  int year;
  int month;
  int day;
  int hour;
  int min;

  const char *north_entry_string;
  const char *east_entry_string;

  north_entry_string = gtk_entry_get_text (north_entry);
  east_entry_string = gtk_entry_get_text (east_entry);
  if (strlen(north_entry_string)<1 || strlen(east_entry_string)<1)
	{
    /* Do not search if coordinates are entry */
		return 0;
	}
  latitude = atof(north_entry_string);
  longitude = atof(east_entry_string);

  year = gtk_spin_button_get_value_as_int (entry_year);
  month = gtk_combo_box_get_active (entry_month)+1;
  day = gtk_spin_button_get_value_as_int (entry_day);
  hour = gtk_spin_button_get_value_as_int (entry_hour);
  min = gtk_spin_button_get_value_as_int (entry_min);

  int time_local[6];

  *(time_local) = year;
  *(time_local+1) = month;
  *(time_local+2) = day;
  *(time_local+3) = hour;
  *(time_local+4) = min;

  time_to_utc (time_local, time_utc);

  hand_overview (builder, latitude, longitude, time_utc);
  hand_plot_mw (builder, latitude, longitude, time_utc);
  hand_plot_sun (builder, latitude, longitude, time_utc);
  hand_plot_moon (builder, latitude, longitude, time_utc);

  plotted = TRUE;
  return 1;
}

static int adjust_time (GtkWidget *widget,  gpointer data){
  if (plotted){
    int hour = gtk_spin_button_get_value_as_int (entry_hour);
    int min = gtk_spin_button_get_value_as_int (entry_min);

    int time_local[6];

    utc_zone_to_time (time_utc, time_local);

    *(time_local+3) = hour;
    *(time_local+4) = min;

    time_to_utc (time_local, time_utc);

    hand_update_overview (latitude, longitude, time_utc);
  }
  return 1;
}

void scale_button_changed (GtkRange *range, GtkScrollType scroll, double value, gpointer user_data){
  if (plotted){
    plot_adjust_teta(G_PI/180*value);
  }
}


static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
  g_print ("delete event occured\n");
  return FALSE;
}
static void destroy( GtkWidget *widget, gpointer   data )
{
  gtk_main_quit ();
}
void hdy_size_config( GtkWidget *widget, gpointer data)
{
	/* Change the style of the window dependent on the resolution of the window.
	 * This is necessarry for mobile phones like the Librem 5 or the Pinephone. */
  int switch_size = 500;
  hdy_view_switcher_bar_set_reveal (switcher_bar, gtk_widget_get_allocated_width (window)<switch_size);
  gtk_widget_set_visible (GTK_WIDGET(view_switcher), gtk_widget_get_allocated_width (window)>switch_size);
  gtk_widget_set_visible (GTK_WIDGET(label_heading), gtk_widget_get_allocated_width (window)<switch_size);
  g_string_free(g_string_new(NULL), TRUE);
}

/* initial function */
int main( int   argc, char *argv[] )
{
  gtk_init (&argc, &argv);
  hdy_action_row_get_type ();

  builder = gtk_builder_new_from_resource("/main/picplanner-window.ui");

  window = GTK_WIDGET (gtk_builder_get_object(builder, "window"));
  button_search = GTK_WIDGET (gtk_builder_get_object(builder, "button_search"));
  button_now = GTK_WIDGET (gtk_builder_get_object(builder, "button_now"));
  button_calculate = GTK_WIDGET (gtk_builder_get_object(builder, "button_calculate"));
  squeezer = HDY_SQUEEZER (gtk_builder_get_object (builder, "squeezer"));
  view_switcher = HDY_VIEW_SWITCHER (gtk_builder_get_object (builder, "title_wide_switcher"));
  switcher_bar = HDY_VIEW_SWITCHER_BAR (gtk_builder_get_object(builder, "switcher_bar"));
  label_heading = GTK_WIDGET (gtk_builder_get_object (builder, "label_heading"));
  entry_min = GTK_SPIN_BUTTON (gtk_builder_get_object(builder, "entry_min"));
  entry_hour = GTK_SPIN_BUTTON (gtk_builder_get_object(builder, "entry_hour"));
  entry_day = GTK_SPIN_BUTTON (gtk_builder_get_object(builder, "entry_day"));
  entry_month = GTK_COMBO_BOX (gtk_builder_get_object (builder, "entry_month"));
  entry_year = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "entry_year"));

  location_entry = GTK_ENTRY(gtk_builder_get_object(builder, "location_entry"));
  north_entry = GTK_ENTRY(gtk_builder_get_object(builder, "north_entry"));
	east_entry = GTK_ENTRY(gtk_builder_get_object(builder, "east_entry"));
  searchentry = GTK_SEARCH_ENTRY(gtk_builder_get_object(builder, "searchentry"));

  box_scale = GTK_WIDGET (gtk_builder_get_object (builder, "scale_rotation"));

  scale_button = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0, 360, 1);
  gtk_widget_set_hexpand (scale_button, TRUE);
  gtk_container_add (GTK_CONTAINER (box_scale), scale_button);


  g_signal_connect (window, "delete-event", G_CALLBACK (delete_event), NULL);
  g_signal_connect (window, "destroy", G_CALLBACK (destroy), NULL);
  g_signal_connect (window, "configure-event", G_CALLBACK(hdy_size_config), NULL);
  g_signal_connect (button_search, "clicked", G_CALLBACK (search), NULL);
  g_signal_connect (button_now, "clicked", G_CALLBACK(set_time_now), NULL);
  g_signal_connect (button_calculate, "clicked", G_CALLBACK (calculate), NULL);
  g_signal_connect (entry_month, "changed", G_CALLBACK (correct_time), NULL);
  g_signal_connect (entry_year, "changed", G_CALLBACK (correct_time), NULL);
  g_signal_connect (entry_hour, "changed", G_CALLBACK (adjust_time), NULL);
  g_signal_connect (entry_min, "changed", G_CALLBACK (adjust_time), NULL);
  g_signal_connect (searchentry, "activate", G_CALLBACK (search), NULL);
  g_signal_connect (scale_button, "change-value", G_CALLBACK(scale_button_changed), NULL);



  set_time_now (window, NULL);

  gtk_widget_show_all  (window);

  gtk_main ();

  return 0;
}

