/*
 * $RCSfile: controlinc.c,v $  $Revision: 1.3 $  $Name:  $
 * $Id: controlinc.c,v 1.3 2006/04/07 01:28:21 bpaauwe Exp $
 * $Author: bpaauwe $
 * $Date: 2006/04/07 01:28:21 $
 * ----------------------------------------------------------------------------
 *
 *  Copyright (c) Bob Paauwe (2006)
 *
 *  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
 *
 * ----------------------------------------------------------------------------
 *
 *  Description:
 *    Functions to handle the controlinc configuration dialog box.
 * ----------------------------------------------------------------------------
 */

#include <string.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <glade/glade.h>
#include <glade/glade-build.h>

#ifdef WITH_GNOME
#  include <libgnomeui/libgnomeui.h>
#endif
#include "globals.h"
#include "controlinc.h"
#include "scenes.h"

static int translate[2000];
static int cl_cnt;
static int initializing;

static void update_progress(float amount);
void update_controlinc();

unsigned char address[5] = {0x31, 0x33, 0x35, 0x37, 0x39};
unsigned char active[5]  = {0x41, 0x43, 0x45, 0x47, 0x49};

void initialize_controlinc(GladeXML *xml)
{
	cl_dialog = glade_xml_get_widget(xml, "cl_dialog");
	cl_selector = glade_xml_get_widget(xml, "cl_selector");
	cl_progress = glade_xml_get_widget(xml, "cl_progress");
	cl_x10b1 = glade_xml_get_widget(xml, "cl_x10b1");
	cl_x10b2 = glade_xml_get_widget(xml, "cl_x10b2");
	cl_x10b3 = glade_xml_get_widget(xml, "cl_x10b3");
	cl_x10b4 = glade_xml_get_widget(xml, "cl_x10b4");
	cl_x10b5 = glade_xml_get_widget(xml, "cl_x10b5");
	cl_x10u1 = glade_xml_get_widget(xml, "cl_x10u1");
	cl_x10u2 = glade_xml_get_widget(xml, "cl_x10u2");
	cl_x10u3 = glade_xml_get_widget(xml, "cl_x10u3");
	cl_x10u4 = glade_xml_get_widget(xml, "cl_x10u4");
	cl_x10u5 = glade_xml_get_widget(xml, "cl_x10u5");
	cl_beep = glade_xml_get_widget(xml, "cl_beep");
	cl_led = glade_xml_get_widget(xml, "cl_led");

	cl_x10[0][0] = glade_xml_get_widget(xml, "cl_x10b1");
	cl_x10[1][0] = glade_xml_get_widget(xml, "cl_x10b2");
	cl_x10[2][0] = glade_xml_get_widget(xml, "cl_x10b3");
	cl_x10[3][0] = glade_xml_get_widget(xml, "cl_x10b4");
	cl_x10[4][0] = glade_xml_get_widget(xml, "cl_x10b5");
	cl_x10[0][1] = glade_xml_get_widget(xml, "cl_x10u1");
	cl_x10[1][1] = glade_xml_get_widget(xml, "cl_x10u2");
	cl_x10[2][1] = glade_xml_get_widget(xml, "cl_x10u3");
	cl_x10[3][1] = glade_xml_get_widget(xml, "cl_x10u4");
	cl_x10[4][1] = glade_xml_get_widget(xml, "cl_x10u5");
	cl_x10[0][2] = glade_xml_get_widget(xml, "cl_x10e1");
	cl_x10[1][2] = glade_xml_get_widget(xml, "cl_x10e2");
	cl_x10[2][2] = glade_xml_get_widget(xml, "cl_x10e3");
	cl_x10[3][2] = glade_xml_get_widget(xml, "cl_x10e4");
	cl_x10[4][2] = glade_xml_get_widget(xml, "cl_x10e5");

	cl_cnt = 0;
}



void on_cfg_controlinc_activate(GtkWidget *widget, gpointer user_data)
{
	int i;

	initializing = 1;
	for (i = 0; i < cl_cnt; i++) {
		gtk_combo_box_remove_text((GtkComboBox *)cl_selector, 0);
	}

	cl_cnt = 0;

	for (i = 0; i <= last_device; i++) {
		if (device_array[i].device_type == 0x0004) { /* controlinc */
			gtk_combo_box_append_text((GtkComboBox *)cl_selector,
					device_array[i].device_name);
			translate[cl_cnt++] = i;
		}
	}

	gtk_widget_show(cl_dialog);
	initializing = 0;
}

void on_cl_selector_changed(GtkWidget *widget, gpointer user_data)
{
	int sel;
	int ret;
	device_t *dev;
	float p;
	int i;

	if (initializing) {
		return;
	}

	sel = gtk_combo_box_get_active((GtkComboBox *)cl_selector);
	if (sel == -1) {
		printf("No device selected!\n");
		return;
	}

	dev = &device_array[translate[sel]];

	update_progress(0.0);
	gtk_progress_bar_set_text((GtkProgressBar *)cl_progress,
			"Loading Config...");

	/* Update fields in dialog box */
	ret = salad_send_message(iplc, SET_ADDR_MSB, 0x00, dev->device_id);
	update_progress(0.08);
	ret = salad_send_message(iplc, PEEK_INTERNAL, 0x11, dev->device_id);
	update_progress(0.16);
	if (ret != -1) {
		gtk_toggle_button_set_active((GtkToggleButton *)cl_beep, (ret & 0x01));
		gtk_toggle_button_set_active((GtkToggleButton *)cl_led, (ret & 0x08));
	}

	p = 0.16;
	for (i = 0; i < 5; i++) {
		ret = salad_send_message(iplc, PEEK_INTERNAL, active[i],
				dev->device_id);
		p += 0.08;
		update_progress(p);
		if ((ret != -1) && (ret & 0xff)) {
			ret = salad_send_message(iplc, PEEK_INTERNAL, address[i],
					dev->device_id);
			p += 0.08;
			update_progress(p);
			gtk_combo_box_set_active((GtkComboBox *)cl_x10[i][0],
					((ret & 0xf0) >> 8));
			gtk_combo_box_set_active((GtkComboBox *)cl_x10[i][1],
					(ret & 0x0f));
			gtk_toggle_button_set_active((GtkToggleButton *)cl_x10[i][2], 1);
		} else {
			gtk_combo_box_set_active((GtkComboBox *)cl_x10[i][0], -1);
			gtk_combo_box_set_active((GtkComboBox *)cl_x10[i][1], -1);
			gtk_toggle_button_set_active((GtkToggleButton *)cl_x10[i][2], 0);
		}
	}

	update_progress(1.0);
	gtk_progress_bar_set_text((GtkProgressBar *)cl_progress,
			"Config Loaded...");
}


void on_cl_apply_clicked(GtkWidget *widget, gpointer user_data)
{
	update_controlinc();
}


void on_cl_ok_clicked(GtkWidget *widget, gpointer user_data)
{

	update_controlinc();
	gtk_widget_hide(cl_dialog);
}


void on_cl_cancel_clicked(GtkWidget *widget, gpointer user_data)
{
	gtk_widget_hide(cl_dialog);
}


void on_cl_dialog_delete_event(GtkWidget *widget, gpointer user_data)
{
	gtk_widget_hide(cl_dialog);
	return;
}


void update_controlinc()
{
	int sel;
	int ret;
	device_t *dev;
	unsigned char x10, set;
	GtkWidget *msg;
	float p = 0.0;
	int i;

	sel = gtk_combo_box_get_active((GtkComboBox *)cl_selector);
	if (sel == -1) {
		printf("No Controlinc selected!\n");
		return;
	}

	dev = &device_array[translate[sel]];

	update_progress(p);
	gtk_progress_bar_set_text((GtkProgressBar *)cl_progress,
			"Writing Config...");

	x10 = 0;
	if (gtk_toggle_button_get_active((GtkToggleButton *)cl_beep)) {
		x10 |= 0x01;
	}
	if (gtk_toggle_button_get_active((GtkToggleButton *)cl_led)) {
		x10 |= 0x08;
	}

	ret = salad_send_message(iplc, SET_ADDR_MSB, 0x00, dev->device_id);
	update_progress((p += 0.04));
	ret = salad_send_message(iplc, PEEK_INTERNAL, 0x11, dev->device_id);
	update_progress((p += 0.04));
	ret = salad_send_message(iplc, POKE_INTERNAL, x10, dev->device_id);
	update_progress((p += 0.04));

	/* FIXME: Need to set X10 values here.... */
	for (i = 0; i < 5; i++) {
		if (gtk_toggle_button_get_active((GtkToggleButton *)cl_x10[i][2])) {
			x10 = gtk_combo_box_get_active((GtkComboBox *)cl_x10[i][0]);
			x10 = x10 << 4;
			x10 |= gtk_combo_box_get_active((GtkComboBox *)cl_x10[i][1]);
			set = 0xff;
		} else {
			x10 = 0x00;
			set = 0x00;
		}
		ret = salad_send_message(iplc, PEEK_INTERNAL, address[i],
				dev->device_id);
		update_progress((p += 0.04));
		ret = salad_send_message(iplc, POKE_INTERNAL, x10, dev->device_id);
		update_progress((p += 0.04));
		ret = salad_send_message(iplc, PEEK_INTERNAL, active[i],
				dev->device_id);
		update_progress((p += 0.04));
		ret = salad_send_message(iplc, POKE_INTERNAL, set, dev->device_id);
		update_progress((p += 0.04));
	}

	salad_send_message(iplc, DO_READ_EE, 0x00, dev->device_id);
	update_progress(1.0);
	gtk_progress_bar_set_text((GtkProgressBar *)cl_progress,
			"Config Written...");

	msg = gtk_message_dialog_new(GTK_WINDOW(main_window),
			GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING,
			GTK_BUTTONS_CLOSE,
			"Unplug and re-plug ControLinc for changes to take effect!");
	gtk_dialog_run (GTK_DIALOG (msg));
	gtk_widget_destroy (msg);
}


static void update_progress(float amount)
{
	gtk_progress_bar_set_fraction((GtkProgressBar *)cl_progress, amount);
	gtk_widget_queue_draw(cl_progress);
	/* gtk_widget_queue_draw(cl_dialog); */
	while (gtk_events_pending()) {
		gtk_main_iteration();
	}
}

