/*  Note: You are free to use whatever license you want.
    Eventually you will be able to edit it within Glade. */

/*  eppdiag
 *  Copyright (C) <YEAR> <AUTHORS>
 *
 *  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <sys/stat.h>
#include <unistd.h>
#include <string.h>

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "gladesig.h"
#include "gladesrc.h"

GtkWidget*
get_widget                             (GtkWidget       *widget,
                                        gchar           *widget_name)
{
  GtkWidget *parent, *found_widget;

  for (;;)
    {
      if (GTK_IS_MENU (widget))
        parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
      else
        parent = widget->parent;
      if (parent == NULL)
        break;
      widget = parent;
    }

  found_widget = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (widget),
                                                   widget_name);
  if (!found_widget)
    g_warning ("Widget not found: %s", widget_name);
  return found_widget;
}

/* This is an internally used function to set notebook tab widgets. */
void
set_notebook_tab                       (GtkWidget       *notebook,
                                        gint             page_num,
                                        GtkWidget       *widget)
{
  GtkNotebookPage *page;
  GtkWidget *notebook_page;

  page = (GtkNotebookPage*) g_list_nth (GTK_NOTEBOOK (notebook)->children, page_num)->data;
  notebook_page = page->child;
  gtk_widget_ref (notebook_page);
  gtk_notebook_remove_page (GTK_NOTEBOOK (notebook), page_num);
  gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), notebook_page,
                            widget, page_num);
  gtk_widget_unref (notebook_page);
}

static GList *pixmaps_directories = NULL;

/* Use this function to set the directory containing installed pixmaps. */
void
add_pixmap_directory                   (gchar           *directory)
{
  pixmaps_directories = g_list_prepend (pixmaps_directories, g_strdup (directory));
}

/* This is an internally used function to check if a pixmap file exists. */
#ifndef G_DIR_SEPARATOR_S
#define G_DIR_SEPARATOR_S "/"
#endif
gchar*
check_file_exists                      (gchar           *directory,
                                        gchar           *filename)
{
  gchar *full_filename;
  struct stat s;
  gint status;

  full_filename = g_malloc (strlen (directory) + 1 + strlen (filename) + 1);
  strcpy (full_filename, directory);
  strcat (full_filename, G_DIR_SEPARATOR_S);
  strcat (full_filename, filename);

  status = stat (full_filename, &s);
  if (status == 0 && S_ISREG (s.st_mode))
    return full_filename;
  g_free (full_filename);
  return NULL;
}

/* This is an internally used function to create pixmaps. */
GtkWidget*
create_pixmap                          (GtkWidget       *widget,
                                        gchar           *filename)
{
  gchar *found_filename = NULL;
  GdkColormap *colormap;
  GdkPixmap *gdkpixmap;
  GdkBitmap *mask;
  GtkWidget *pixmap;
  GList *elem;

  /* We first try any pixmaps directories set by the application. */
  elem = pixmaps_directories;
  while (elem)
    {
      found_filename = check_file_exists ((gchar*)elem->data, filename);
      if (found_filename)
        break;
      elem = elem->next;
    }

  /* If we haven't found the pixmap, try the source directory. */
  if (!found_filename)
    {
      found_filename = check_file_exists ("pixmaps", filename);
    }

  if (!found_filename)
    {
      g_print ("Couldn't find pixmap file: %s", filename);
      return NULL;
    }

  colormap = gtk_widget_get_colormap (widget);
  gdkpixmap = gdk_pixmap_colormap_create_from_xpm (NULL, colormap, &mask,
                                                   NULL, found_filename);
  g_free (found_filename);
  if (gdkpixmap == NULL)
    return NULL;
  pixmap = gtk_pixmap_new (gdkpixmap, mask);
  gdk_pixmap_unref (gdkpixmap);
  gdk_bitmap_unref (mask);
  return pixmap;
}

GtkWidget*
create_diag ()
{
  GtkWidget *diag;
  GtkWidget *hbox1;
  GtkWidget *vbox1;
  GtkWidget *table1;
  GtkWidget *label7;
  GtkWidget *label6;
  GtkWidget *label5;
  GtkWidget *label4;
  GtkWidget *parfilter;
  GList *parfilter_items = NULL;
  GtkObject *parbitrate_adj;
  GtkWidget *parbitrate;
  GtkWidget *paraddress;
  GList *paraddress_items = NULL;
  GtkWidget *partest;
  GtkWidget *label8;
  GtkObject *parfclk_adj;
  GtkWidget *parfclk;
  GtkWidget *parclk;
  GtkWidget *hbox4;
  GtkWidget *parmodem;
  GtkWidget *parstat;
  GtkWidget *parloopback;
  GtkWidget *hbuttonbox1;
  GtkWidget *bquit;
  GtkWidget *btest;
  GtkWidget *vpaned1;
  GtkWidget *scrolledwindow1;
  GtkWidget *textl;
  GtkWidget *scrolledwindow2;
  GtkWidget *textt;

  diag = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_object_set_data (GTK_OBJECT (diag), "diag", diag);
  gtk_window_set_title (GTK_WINDOW (diag), "EPP FPGA Modem Diagnostics");
  gtk_window_set_policy (GTK_WINDOW (diag), TRUE, TRUE, FALSE);

  hbox1 = gtk_hbox_new (FALSE, 0);
  gtk_object_set_data (GTK_OBJECT (diag), "hbox1", hbox1);
  gtk_widget_show (hbox1);
  gtk_container_add (GTK_CONTAINER (diag), hbox1);

  vbox1 = gtk_vbox_new (FALSE, 0);
  gtk_object_set_data (GTK_OBJECT (diag), "vbox1", vbox1);
  gtk_widget_show (vbox1);
  gtk_box_pack_start (GTK_BOX (hbox1), vbox1, FALSE, FALSE, 0);

  table1 = gtk_table_new (5, 2, FALSE);
  gtk_object_set_data (GTK_OBJECT (diag), "table1", table1);
  gtk_widget_show (table1);
  gtk_box_pack_start (GTK_BOX (vbox1), table1, FALSE, FALSE, 0);
  gtk_table_set_row_spacings (GTK_TABLE (table1), 4);

  label7 = gtk_label_new ("Filter");
  gtk_object_set_data (GTK_OBJECT (diag), "label7", label7);
  gtk_widget_show (label7);
  gtk_table_attach (GTK_TABLE (table1), label7, 0, 1, 3, 4,
                    (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0, 0, 0);
  gtk_label_set_justify (GTK_LABEL (label7), GTK_JUSTIFY_LEFT);
  gtk_misc_set_alignment (GTK_MISC (label7), 0.05, 0.5);
  gtk_misc_set_padding (GTK_MISC (label7), 4, 0);

  label6 = gtk_label_new ("Bitrate");
  gtk_object_set_data (GTK_OBJECT (diag), "label6", label6);
  gtk_widget_show (label6);
  gtk_table_attach (GTK_TABLE (table1), label6, 0, 1, 2, 3,
                    (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0, 0, 0);
  gtk_label_set_justify (GTK_LABEL (label6), GTK_JUSTIFY_LEFT);
  gtk_misc_set_alignment (GTK_MISC (label6), 0.05, 0.5);
  gtk_misc_set_padding (GTK_MISC (label6), 4, 0);

  label5 = gtk_label_new ("Port Address");
  gtk_object_set_data (GTK_OBJECT (diag), "label5", label5);
  gtk_widget_show (label5);
  gtk_table_attach (GTK_TABLE (table1), label5, 0, 1, 1, 2,
                    (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0, 0, 0);
  gtk_misc_set_alignment (GTK_MISC (label5), 0.05, 0.5);
  gtk_misc_set_padding (GTK_MISC (label5), 4, 0);

  label4 = gtk_label_new ("Test");
  gtk_object_set_data (GTK_OBJECT (diag), "label4", label4);
  gtk_widget_show (label4);
  gtk_table_attach (GTK_TABLE (table1), label4, 0, 1, 0, 1,
                    (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0, 0, 0);
  gtk_label_set_justify (GTK_LABEL (label4), GTK_JUSTIFY_LEFT);
  gtk_misc_set_alignment (GTK_MISC (label4), 0.05, 0.5);
  gtk_misc_set_padding (GTK_MISC (label4), 4, 0);

  parfilter = gtk_combo_new ();
  gtk_object_set_data (GTK_OBJECT (diag), "parfilter", parfilter);
  gtk_widget_show (parfilter);
  gtk_table_attach (GTK_TABLE (table1), parfilter, 1, 2, 3, 4,
                    (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0, 0, 0);
  gtk_combo_set_use_arrows_always (GTK_COMBO (parfilter), TRUE);
  parfilter_items = g_list_append (parfilter_items, "Default");
  parfilter_items = g_list_append (parfilter_items, "Analog Filter Eq");
  parfilter_items = g_list_append (parfilter_items, "Linear Phase");
  gtk_combo_set_popdown_strings (GTK_COMBO (parfilter), parfilter_items);
  g_list_free (parfilter_items);

  parbitrate_adj = gtk_adjustment_new (9600, 4800, 1.5e+06, 4800, 115200, 115200);
  parbitrate = gtk_spin_button_new (GTK_ADJUSTMENT (parbitrate_adj), 1, 0);
  gtk_object_set_data (GTK_OBJECT (diag), "parbitrate", parbitrate);
  gtk_widget_show (parbitrate);
  gtk_table_attach (GTK_TABLE (table1), parbitrate, 1, 2, 2, 3,
                    (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0, 0, 0);

  paraddress = gtk_combo_new ();
  gtk_object_set_data (GTK_OBJECT (diag), "paraddress", paraddress);
  gtk_widget_show (paraddress);
  gtk_table_attach (GTK_TABLE (table1), paraddress, 1, 2, 1, 2,
                    (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0, 0, 0);
  paraddress_items = g_list_append (paraddress_items, "0x378");
  paraddress_items = g_list_append (paraddress_items, "0x278");
  paraddress_items = g_list_append (paraddress_items, "0x3bc");
  gtk_combo_set_popdown_strings (GTK_COMBO (paraddress), paraddress_items);
  g_list_free (paraddress_items);

  partest = gtk_combo_new ();
  gtk_object_set_data (GTK_OBJECT (diag), "partest", partest);
  gtk_widget_show (partest);
  gtk_table_attach (GTK_TABLE (table1), partest, 1, 2, 0, 1,
                    (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0, 0, 0);
  gtk_combo_set_use_arrows_always (GTK_COMBO (partest), TRUE);

  label8 = gtk_label_new ("FPGA clock");
  gtk_object_set_data (GTK_OBJECT (diag), "label8", label8);
  gtk_widget_show (label8);
  gtk_table_attach (GTK_TABLE (table1), label8, 0, 1, 4, 5,
                    (GtkAttachOptions) GTK_EXPAND | GTK_FILL, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
  gtk_misc_set_alignment (GTK_MISC (label8), 0.05, 0.5);
  gtk_misc_set_padding (GTK_MISC (label8), 4, 0);

  parfclk_adj = gtk_adjustment_new (1.96666e+07, 1e+06, 2.5e+07, 100000, 1e+06, 1e+06);
  parfclk = gtk_spin_button_new (GTK_ADJUSTMENT (parfclk_adj), 1, 0);
  gtk_object_set_data (GTK_OBJECT (diag), "parfclk", parfclk);
  gtk_widget_show (parfclk);
  gtk_table_attach (GTK_TABLE (table1), parfclk, 1, 2, 4, 5,
                    (GtkAttachOptions) GTK_FILL, (GtkAttachOptions) 0, 0, 0);

  parclk = gtk_check_button_new_with_label ("Internal Clock");
  gtk_object_set_data (GTK_OBJECT (diag), "parclk", parclk);
  gtk_widget_show (parclk);
  gtk_box_pack_start (GTK_BOX (vbox1), parclk, FALSE, FALSE, 2);
  gtk_widget_set_usize (parclk, 60, -2);

  hbox4 = gtk_hbox_new (FALSE, 0);
  gtk_object_set_data (GTK_OBJECT (diag), "hbox4", hbox4);
  gtk_widget_show (hbox4);
  gtk_box_pack_start (GTK_BOX (vbox1), hbox4, FALSE, FALSE, 2);

  parmodem = gtk_check_button_new_with_label ("Internal Modem");
  gtk_object_set_data (GTK_OBJECT (diag), "parmodem", parmodem);
  gtk_widget_show (parmodem);
  gtk_box_pack_start (GTK_BOX (hbox4), parmodem, FALSE, FALSE, 2);
  gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (parmodem), TRUE);

  parstat = gtk_check_button_new_with_label ("Extended Status");
  gtk_object_set_data (GTK_OBJECT (diag), "parstat", parstat);
  gtk_widget_show (parstat);
  gtk_box_pack_start (GTK_BOX (vbox1), parstat, FALSE, FALSE, 2);
  gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (parstat), TRUE);

  parloopback = gtk_check_button_new_with_label ("Loopback");
  gtk_object_set_data (GTK_OBJECT (diag), "parloopback", parloopback);
  gtk_widget_show (parloopback);
  gtk_box_pack_start (GTK_BOX (vbox1), parloopback, FALSE, FALSE, 2);

  hbuttonbox1 = gtk_hbutton_box_new ();
  gtk_object_set_data (GTK_OBJECT (diag), "hbuttonbox1", hbuttonbox1);
  gtk_widget_show (hbuttonbox1);
  gtk_box_pack_end (GTK_BOX (vbox1), hbuttonbox1, FALSE, FALSE, 0);
  gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox1), GTK_BUTTONBOX_SPREAD);

  bquit = gtk_button_new_with_label ("Quit");
  gtk_object_set_data (GTK_OBJECT (diag), "bquit", bquit);
  gtk_widget_show (bquit);
  gtk_container_add (GTK_CONTAINER (hbuttonbox1), bquit);
  gtk_container_border_width (GTK_CONTAINER (bquit), 5);
  gtk_signal_connect (GTK_OBJECT (bquit), "clicked",
                      GTK_SIGNAL_FUNC (on_bquit_clicked),
                      NULL);

  btest = gtk_button_new_with_label ("Test");
  gtk_object_set_data (GTK_OBJECT (diag), "btest", btest);
  gtk_widget_show (btest);
  gtk_container_add (GTK_CONTAINER (hbuttonbox1), btest);
  GTK_WIDGET_SET_FLAGS (btest, GTK_CAN_DEFAULT);
  gtk_signal_connect (GTK_OBJECT (btest), "clicked",
                      GTK_SIGNAL_FUNC (on_btest_clicked),
                      NULL);

  vpaned1 = gtk_vpaned_new ();
  gtk_object_set_data (GTK_OBJECT (diag), "vpaned1", vpaned1);
  gtk_widget_show (vpaned1);
  gtk_box_pack_start (GTK_BOX (hbox1), vpaned1, TRUE, TRUE, 0);
  gtk_paned_gutter_size (GTK_PANED (vpaned1), 15);

  scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
  gtk_object_set_data (GTK_OBJECT (diag), "scrolledwindow1", scrolledwindow1);
  gtk_widget_show (scrolledwindow1);
  gtk_container_add (GTK_CONTAINER (vpaned1), scrolledwindow1);

  textl = gtk_text_new (NULL, NULL);
  gtk_object_set_data (GTK_OBJECT (diag), "textl", textl);
  gtk_widget_show (textl);
  gtk_container_add (GTK_CONTAINER (scrolledwindow1), textl);

  scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL);
  gtk_object_set_data (GTK_OBJECT (diag), "scrolledwindow2", scrolledwindow2);
  gtk_widget_show (scrolledwindow2);
  gtk_container_add (GTK_CONTAINER (vpaned1), scrolledwindow2);

  textt = gtk_text_new (NULL, NULL);
  gtk_object_set_data (GTK_OBJECT (diag), "textt", textt);
  gtk_widget_show (textt);
  gtk_container_add (GTK_CONTAINER (scrolledwindow2), textt);

  return diag;
}

