/*
 *   Copyright (C) 1991-2000 by Jonathan Naylor HB9DRD/G4KLX
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include <string.h>
#include <time.h>

#include <gtk/gtk.h>

#include "global.h"

static struct {
	gchar *Name;
	char Code;
} Sat_Categories[] = {
	{"[All]",		'*'},
	{"Amateur",		'A'},
	{"Communications",	'C'},
	{"Earth Imaging",	'E'},
	{"Geostationary",	'F'},
	{"Globalstar/Iridium",	'I'},
	{"GPS",			'G'},
	{"Hardware",		'H'},
	{"LEO",			'L'},
	{"Military",		'M'},
	{"Molniya",		'N'},
	{"TVRO",		'T'},
	{"Weather",		'W'},
	{"Other",		'-'}
};

static void SatSelectCb(GtkWidget *, gpointer);
static void LocSelectCb(GtkWidget *, gpointer);

static void SatClickCb(GtkWidget *, gint, gint, GdkEventButton *, gpointer);
static void CatClickCb(GtkWidget *, gint, gint, GdkEventButton *, gpointer);
static void LocClickCb(GtkWidget *, gint, gint, GdkEventButton *, gpointer);

static void (*Sat_Callback)(struct Sat_Struct *);
static void (*Loc_Callback)(struct Loc_Struct *);

static void Fill_Sat_List(char);

static GtkWidget *CatList;
static GtkWidget *SatList;
static GtkWidget *SatName;

static GtkWidget *LocName;

struct Sat_Struct *Find_Satellite_Name(char *name)
{
	struct Sat_Struct *Sat_Data, *Found;
	GSList *Sat;

	Found = NULL;
	Sat   = Sat_List;

	while (Sat != NULL && Found == NULL) {
		Sat_Data = (struct Sat_Struct *)Sat->data;

		if (strcmp(Sat_Data->Name, name) == 0)
			Found = Sat_Data;

		Sat = g_slist_next(Sat);
	}

	return Found;
}

struct Sat_Struct *Find_Satellite_Cat_No(int cat_no)
{
	struct Sat_Struct *Sat_Data, *Found;
	GSList *Sat;

	Found = NULL;
	Sat   = Sat_List;

	while (Sat != NULL && Found == NULL) {
		Sat_Data = (struct Sat_Struct *)Sat->data;

		if (Sat_Data->Catalogue_No != 0L && Sat_Data->Catalogue_No == cat_no)
			Found = Sat_Data;

		Sat = g_slist_next(Sat);
	}

	return Found;
}

struct Loc_Struct *Find_Location_Name(char *name)
{
	struct Loc_Struct *Loc_Data, *Found;
	GSList *Loc;

	Found = NULL;
	Loc   = Loc_List;

	while (Loc != NULL && Found == NULL) {
		Loc_Data = (struct Loc_Struct *)Loc->data;

		if (strcmp(Loc_Data->QTH, name) == 0)
			Found = Loc_Data;

		Loc = g_slist_next(Loc);
	}

	return Found;
}

static void CatClickCb(GtkWidget *catlist, gint row, gint column, GdkEventButton *event, gpointer data)
{
	Fill_Sat_List(Sat_Categories[row].Code);
}

static void SatClickCb(GtkWidget *satlist, gint row, gint column, GdkEventButton *event, gpointer data)
{
	gchar *Satellite;
	
	gtk_clist_get_text(GTK_CLIST(satlist), row, column, &Satellite);

	gtk_entry_set_text(GTK_ENTRY(SatName), Satellite);
}

static void SatSelectCb(GtkWidget *w, gpointer data)
{
	GtkWidget *window = (GtkWidget *)data;
	struct Sat_Struct *Sat;
	char *Satellite;
	char buffer[60];
	
	Satellite = gtk_entry_get_text(GTK_ENTRY(SatName));

	if ((Sat = Find_Satellite_Name(Satellite)) == NULL) {
		sprintf(buffer, "Cannot find satellite %s", Satellite);
		Warning_Box(buffer);
	} else {
		gtk_widget_destroy(window);
		(*Sat_Callback)(Sat);
	}
}

static void LocClickCb(GtkWidget *loclist, gint row, gint column, GdkEventButton *event, gpointer data)
{
	gchar *QTH;
	
	gtk_clist_get_text(GTK_CLIST(loclist), row, column, &QTH);

	gtk_entry_set_text(GTK_ENTRY(LocName), QTH);
}

static void LocSelectCb(GtkWidget *w, gpointer data)
{
	GtkWidget *window = (GtkWidget *)data;
	struct Loc_Struct *Loc;
	char *QTH;
	char buffer[60];
	
	QTH = gtk_entry_get_text(GTK_ENTRY(LocName));

	if ((Loc = Find_Location_Name(QTH)) == NULL) {
		sprintf(buffer, "Cannot find location %s", QTH);
		Warning_Box(buffer);
	} else {
		gtk_widget_destroy(window);
		(*Loc_Callback)(Loc);
	}
}

void Choose_Satellite(void (*callback)(struct Sat_Struct *))
{
	GtkWidget *window;
	GtkWidget *vbox;
	GtkWidget *hbox;
	GtkWidget *catwin;
	GtkWidget *satwin;
	GtkWidget *bbox;
	GtkWidget *button[3];
	char *cat_title[2];
	char *sat_title[2];
	int Cat_Count = sizeof(Sat_Categories) / sizeof(Sat_Categories[0]);
	int i;

	if (Sat_List == NULL) {
		Warning_Box("No Satellites to choose from");
		return;
	}

	window = gtk_window_new(GTK_WINDOW_DIALOG);

	gtk_window_set_title(GTK_WINDOW(window), "Choose Satellite");
	gtk_container_set_border_width(GTK_CONTAINER(window), BORDER_WIDTH);

	vbox = gtk_vbox_new(FALSE, BORDER_WIDTH);
	gtk_container_add(GTK_CONTAINER(window), vbox);

	hbox = gtk_hbox_new(FALSE, BORDER_WIDTH);

	cat_title[0] = "Categories";
	cat_title[1] = NULL;
	CatList = gtk_clist_new_with_titles(1, (gchar **)cat_title);
	gtk_widget_set_usize(CatList, CAT_LIST_WIDTH, CAT_LIST_HEIGHT);
	gtk_signal_connect(GTK_OBJECT(CatList), "select_row", (GtkSignalFunc)CatClickCb, NULL);
	gtk_clist_column_titles_passive(GTK_CLIST(CatList));

	catwin = gtk_scrolled_window_new(NULL, NULL);
	gtk_container_add(GTK_CONTAINER(catwin), CatList);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(catwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
	gtk_container_set_border_width(GTK_CONTAINER(catwin), 5);
	gtk_box_pack_start(GTK_BOX(hbox), catwin, TRUE, TRUE, 0);

	sat_title[0] = "Satellites";
	sat_title[1] = NULL;
	SatList = gtk_clist_new_with_titles(1, (gchar **)sat_title);
	gtk_widget_set_usize(SatList, SAT_LIST_WIDTH, SAT_LIST_HEIGHT);
	gtk_signal_connect(GTK_OBJECT(SatList), "select_row", (GtkSignalFunc)SatClickCb, NULL);
	gtk_clist_column_titles_passive(GTK_CLIST(SatList));

	satwin = gtk_scrolled_window_new(NULL, NULL);
	gtk_container_add(GTK_CONTAINER(satwin), SatList);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(satwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
	gtk_container_set_border_width(GTK_CONTAINER(satwin), 5);
	gtk_box_pack_start(GTK_BOX(hbox), satwin, TRUE, TRUE, 0);

	gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);

	SatName = gtk_entry_new_with_max_length(20);
	gtk_box_pack_start(GTK_BOX(vbox), SatName, TRUE, TRUE, 0);

	bbox = gtk_hbutton_box_new();
	gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
	gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
	gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);

	button[0] = gtk_button_new_with_label("OK");
	button[1] = gtk_button_new_with_label("Cancel");
	button[2] = gtk_button_new_with_label("Help");

	gtk_container_add(GTK_CONTAINER(bbox), button[0]);
    	gtk_container_add(GTK_CONTAINER(bbox), button[1]);
      	gtk_container_add(GTK_CONTAINER(bbox), button[2]);
    
	gtk_signal_connect(GTK_OBJECT(button[0]), "clicked", GTK_SIGNAL_FUNC(SatSelectCb), window);
	gtk_signal_connect_object(GTK_OBJECT(button[1]), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(window));
	gtk_signal_connect(GTK_OBJECT(button[2]), "clicked", GTK_SIGNAL_FUNC(HelpCb), (gpointer)2);

	GTK_WIDGET_SET_FLAGS(button[0], GTK_CAN_DEFAULT);
	GTK_WIDGET_SET_FLAGS(button[1], GTK_CAN_DEFAULT);
	GTK_WIDGET_SET_FLAGS(button[2], GTK_CAN_DEFAULT);
	gtk_widget_grab_default(button[0]);

	gtk_clist_freeze(GTK_CLIST(CatList));

	for (i = 0; i < Cat_Count; i++)
		gtk_clist_append(GTK_CLIST(CatList), &Sat_Categories[i].Name);

	gtk_clist_select_row(GTK_CLIST(CatList), 0, 0);

	gtk_clist_thaw(GTK_CLIST(CatList));

	Fill_Sat_List('*');

	Sat_Callback = callback;

	gtk_widget_show(button[0]);
	gtk_widget_show(button[1]);
	gtk_widget_show(button[2]);
	gtk_widget_show(bbox);
	gtk_widget_show(hbox);
	gtk_widget_show(SatName);
	gtk_widget_show(satwin);
	gtk_widget_show(SatList);
	gtk_widget_show(catwin);
	gtk_widget_show(CatList);
	gtk_widget_show(vbox);
	gtk_widget_show(window);
}

static void Fill_Sat_List(char Category)
{
	gchar *name;
	GSList *Sat;
	struct Sat_Struct *Data;

	gtk_clist_freeze(GTK_CLIST(SatList));

	gtk_clist_clear(GTK_CLIST(SatList));

	Sat = Sat_List;

	while (Sat != NULL) {
		Data = (struct Sat_Struct *)Sat->data;

		name = Data->Name; 

		switch (Category) {
			case '*':
				gtk_clist_append(GTK_CLIST(SatList), &name);
				break;
			case '-':
				if (strlen(Data->Category) == 0)
					gtk_clist_append(GTK_CLIST(SatList), &name);
				break;
			default:
				if (strchr(Data->Category, Category) != NULL)
					gtk_clist_append(GTK_CLIST(SatList), &name);
				break;
		}

		Sat = g_slist_next(Sat);
	}

	gtk_clist_select_row(GTK_CLIST(SatList), 0, 0);

	gtk_clist_thaw(GTK_CLIST(SatList));
}

void Choose_Location(void (*callback)(struct Loc_Struct *))
{
	GtkWidget *window;
	GtkWidget *vbox;
	GtkWidget *hbox;
	GtkWidget *locwin, *loclist;
	GtkWidget *bbox;
	GtkWidget *button[3];
	gchar *name;
	char *loctitle[2];
	GSList *Loc;
	struct Loc_Struct *Data;

	if (Loc_List == NULL) {
		Warning_Box("No Locations to choose from");
		return;
	}

	window = gtk_window_new(GTK_WINDOW_DIALOG);

	gtk_window_set_title(GTK_WINDOW(window), "Choose Location");
	gtk_container_set_border_width(GTK_CONTAINER(window), BORDER_WIDTH);

	vbox = gtk_vbox_new(FALSE, BORDER_WIDTH);
	gtk_container_add(GTK_CONTAINER(window), vbox);

	hbox = gtk_hbox_new(FALSE, BORDER_WIDTH);

	loctitle[0] = "Locations";
	loctitle[1] = NULL;
	loclist = gtk_clist_new_with_titles(1, (gchar **)loctitle);
	gtk_widget_set_usize(loclist, CAT_LIST_WIDTH, CAT_LIST_HEIGHT);
	gtk_signal_connect(GTK_OBJECT(loclist), "select_row", (GtkSignalFunc)LocClickCb, NULL);
	gtk_clist_column_titles_passive(GTK_CLIST(loclist));

	locwin = gtk_scrolled_window_new(NULL, NULL);
	gtk_container_add(GTK_CONTAINER(locwin), loclist);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(locwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
	gtk_container_set_border_width(GTK_CONTAINER(locwin), 5);
	gtk_box_pack_start(GTK_BOX(hbox), locwin, TRUE, TRUE, 0);

	gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);

	LocName = gtk_entry_new_with_max_length(30);
	gtk_box_pack_start(GTK_BOX(vbox), LocName, TRUE, TRUE, 0);

	bbox = gtk_hbutton_box_new();
	gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
	gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
	gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);

	button[0] = gtk_button_new_with_label("OK");
	button[1] = gtk_button_new_with_label("Cancel");
	button[2] = gtk_button_new_with_label("Help");

	gtk_container_add(GTK_CONTAINER(bbox), button[0]);
    	gtk_container_add(GTK_CONTAINER(bbox), button[1]);
      	gtk_container_add(GTK_CONTAINER(bbox), button[2]);
    
	gtk_signal_connect(GTK_OBJECT(button[0]), "clicked", GTK_SIGNAL_FUNC(LocSelectCb), window);
	gtk_signal_connect_object(GTK_OBJECT(button[1]), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(window));
	gtk_signal_connect(GTK_OBJECT(button[2]), "clicked", GTK_SIGNAL_FUNC(HelpCb), (gpointer)4);

	gtk_clist_freeze(GTK_CLIST(loclist));

	Loc = Loc_List;

	while (Loc != NULL) {
		Data = (struct Loc_Struct *)Loc->data;
		name = Data->QTH;

		gtk_clist_append(GTK_CLIST(loclist), &name);

		Loc = g_slist_next(Loc);
	}

	gtk_clist_select_row(GTK_CLIST(loclist), 0, 0);

	gtk_clist_thaw(GTK_CLIST(loclist));

	Loc_Callback = callback;

	gtk_widget_show(button[0]);
	gtk_widget_show(button[1]);
	gtk_widget_show(button[2]);
	gtk_widget_show(bbox);
	gtk_widget_show(hbox);
	gtk_widget_show(LocName);
	gtk_widget_show(locwin);
	gtk_widget_show(loclist);
	gtk_widget_show(vbox);
	gtk_widget_show(window);
}
