/*
 * Hardware Information, version 0.3
 * Copyright (C) 2003 Leandro Pereira <leandro@linuxmag.com.br>
 *
 * May be modified and/or distributed under the terms of GNU GPL version 2.
 *
 * Tested only with 2.4.x kernels on ix86.
 * USB support needs netdevfs.
 */

#include <stdio.h>
#include "hardinfo.h"
#include "net.h"

GtkWidget *net_get_widget(MainWindow * mainwindow)
{
    GtkWidget *vbox1;
    GtkWidget *scrolledwindow1;
    GtkWidget *clist1;
    GtkWidget *label2;
    GtkWidget *table1;
    GtkWidget *label4;
    GtkWidget *label5;
    GtkWidget *label7;
    GtkWidget *label8;
    GtkWidget *label3;
    GtkWidget *label10;
    GtkWidget *label11;
    GtkWidget *label12;
    GtkWidget *label14;
    GtkWidget *label15;
    GtkWidget *vseparator1;

    vbox1 = gtk_vbox_new(FALSE, 5);
    gtk_widget_show(vbox1);
    gtk_container_set_border_width(GTK_CONTAINER(vbox1), 4);

    scrolledwindow1 = gtk_scrolled_window_new(NULL, NULL);
    gtk_widget_show(scrolledwindow1);
    gtk_box_pack_start(GTK_BOX(vbox1), scrolledwindow1, TRUE, TRUE, 0);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow1),
				   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);

    clist1 = gtk_clist_new(2);
    gtk_widget_show(clist1);
    gtk_container_add(GTK_CONTAINER(scrolledwindow1), clist1);
    gtk_clist_set_column_width(GTK_CLIST(clist1), 0, 30);
    gtk_clist_set_column_width(GTK_CLIST(clist1), 1, 80);
    gtk_clist_column_titles_show(GTK_CLIST(clist1));

    label2 = gtk_label_new(_("Interface name"));
    gtk_widget_show(label2);
    gtk_clist_set_column_widget(GTK_CLIST(clist1), 1, label2);
    gtk_label_set_justify(GTK_LABEL(label2), GTK_JUSTIFY_LEFT);
    gtk_misc_set_alignment(GTK_MISC(label2), 0, 0.5);

    table1 = gtk_table_new(3, 5, FALSE);
    gtk_widget_show(table1);
    gtk_box_pack_start(GTK_BOX(vbox1), table1, FALSE, FALSE, 0);
    gtk_container_set_border_width(GTK_CONTAINER(table1), 4);
    gtk_table_set_row_spacings(GTK_TABLE(table1), 4);
    gtk_table_set_col_spacings(GTK_TABLE(table1), 4);

    label4 = gtk_label_new(_("Bytes:"));
    gtk_widget_show(label4);
    gtk_table_attach(GTK_TABLE(table1), label4, 0, 1, 1, 2,
		     (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, 0.5);

    label5 = gtk_label_new(_("Speed:"));
    gtk_widget_show(label5);
    gtk_table_attach(GTK_TABLE(table1), label5, 0, 1, 2, 3,
		     (GtkAttachOptions) (GTK_FILL),
		     (GtkAttachOptions) (0), 0, 0);
    gtk_label_set_justify(GTK_LABEL(label5), GTK_JUSTIFY_LEFT);
    gtk_misc_set_alignment(GTK_MISC(label5), 0, 0.5);

    label7 = gtk_label_new(_("Bytes:"));
    gtk_widget_show(label7);
    gtk_table_attach(GTK_TABLE(table1), label7, 3, 4, 1, 2,
		     (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, 0.5);

    label8 = gtk_label_new(_("Speed"));
    gtk_widget_show(label8);
    gtk_table_attach(GTK_TABLE(table1), label8, 3, 4, 2, 3,
		     (GtkAttachOptions) (GTK_FILL),
		     (GtkAttachOptions) (0), 0, 0);
    gtk_label_set_justify(GTK_LABEL(label8), GTK_JUSTIFY_LEFT);
    gtk_misc_set_alignment(GTK_MISC(label8), 0, 0.5);

    label3 = gtk_label_new(_("<big><b>Receive</b></big>"));
    gtk_widget_show(label3);
    gtk_table_attach(GTK_TABLE(table1), label3, 0, 2, 0, 1,
		     (GtkAttachOptions) (GTK_FILL),
		     (GtkAttachOptions) (0), 0, 0);
    gtk_label_set_use_markup(GTK_LABEL(label3), TRUE);
    gtk_label_set_justify(GTK_LABEL(label3), GTK_JUSTIFY_LEFT);
    gtk_misc_set_alignment(GTK_MISC(label3), 0, 0.5);

    label10 = gtk_label_new(_("<big><b>Transmit</b></big>"));
    gtk_widget_show(label10);
    gtk_table_attach(GTK_TABLE(table1), label10, 3, 5, 0, 1,
		     (GtkAttachOptions) (GTK_FILL),
		     (GtkAttachOptions) (0), 0, 0);
    gtk_label_set_use_markup(GTK_LABEL(label10), TRUE);
    gtk_label_set_justify(GTK_LABEL(label10), GTK_JUSTIFY_LEFT);
    gtk_misc_set_alignment(GTK_MISC(label10), 0, 0.5);

    label11 = gtk_label_new(_("0B"));
    gtk_widget_show(label11);
    gtk_table_attach(GTK_TABLE(table1), label11, 1, 2, 1, 2,
		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
		     (GtkAttachOptions) (0), 0, 0);
    gtk_label_set_justify(GTK_LABEL(label11), GTK_JUSTIFY_LEFT);
    gtk_misc_set_alignment(GTK_MISC(label11), 0, 0.5);

    label12 = gtk_label_new(_("0B/s"));
    gtk_widget_show(label12);
    gtk_table_attach(GTK_TABLE(table1), label12, 1, 2, 2, 3,
		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
		     (GtkAttachOptions) (0), 0, 0);
    gtk_label_set_justify(GTK_LABEL(label12), GTK_JUSTIFY_LEFT);
    gtk_misc_set_alignment(GTK_MISC(label12), 0, 0.5);

    label14 = gtk_label_new(_("0B"));
    gtk_widget_show(label14);
    gtk_table_attach(GTK_TABLE(table1), label14, 4, 5, 1, 2,
		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
		     (GtkAttachOptions) (0), 0, 0);
    gtk_label_set_justify(GTK_LABEL(label14), GTK_JUSTIFY_LEFT);
    gtk_misc_set_alignment(GTK_MISC(label14), 0, 0.5);

    label15 = gtk_label_new(_("0B/s"));
    gtk_widget_show(label15);
    gtk_table_attach(GTK_TABLE(table1), label15, 4, 5, 2, 3,
		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
		     (GtkAttachOptions) (0), 0, 0);
    gtk_label_set_justify(GTK_LABEL(label15), GTK_JUSTIFY_LEFT);
    gtk_misc_set_alignment(GTK_MISC(label15), 0, 0.5);

    vseparator1 = gtk_vseparator_new();
    gtk_widget_show(vseparator1);
    gtk_table_attach(GTK_TABLE(table1), vseparator1, 2, 3, 0, 3,
		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
		     (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);


    return vbox1;
}

gboolean net_update(gpointer data)
{
    MainWindow *mainwindow = (MainWindow *) data;
    NetDevice *net;

    if (!mainwindow)
	return FALSE;

    net = hi_scan_net();

    return TRUE;
}

NetDevice *hi_scan_net(void)
{
    FILE *proc_net;
    gchar buffer[256];
    NetDevice *net_dev, *net;
    struct stat st;

    net = NULL;

    if (stat("/proc/net/dev", &st))
	return NULL;

    proc_net = fopen("/proc/net/dev", "r");
    while (fgets(buffer, 256, proc_net)) {
	if (strchr(buffer, ':')) {
	    gint trash;
	    gchar ifacename[4];
	    gchar *buf = buffer;
	    gint i;

	    net_dev = g_new0(NetDevice, 1);
	    net_dev->next = net;
	    net = net_dev;

	    buf = g_strstrip(buf);

	    memset(ifacename, 0, 4);

	    for (i = 0; buffer[i] != ':' && i < 4; i++) {
		ifacename[i] = buffer[i];
	    }

	    walk_until_inclusive(':');

	    /* iface: bytes packets errs drop fifo frame compressed multicast */
	    sscanf(buf, "%d %d %d %d %d %d %d %d %d %d %d",
		   &net_dev->recv_bytes, &net_dev->recv_packets,
		   &net_dev->recv_errors, &trash, &trash, &trash, &trash,
		   &trash, &net_dev->trans_bytes, &net_dev->trans_packets,
		   &net_dev->trans_errors);

	    g_print("%s -> %d %d %d | %d %d %d\n",
		    ifacename, net_dev->recv_bytes, net_dev->recv_errors,
		    net_dev->recv_packets, net_dev->trans_bytes,
		    net_dev->trans_errors, net_dev->trans_packets);

	}
    }
    fclose(proc_net);

    return net;
}