/*
 * $RCSfile: device_control.c,v $  $Revision: 1.5 $  $Name:  $
 * $Id: device_control.c,v 1.5 2006/10/04 05:21:42 bpaauwe Exp $
 * $Author: bpaauwe $
 * $Date: 2006/10/04 05:21:42 $
 * ----------------------------------------------------------------------------
 *
 *  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 device control 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 "device_control.h"
#include "scenes.h"
#include "progress_bar.h"

static int current_level;
static void set_status(int sel);

void initialize_device_control(GladeXML *xml)
{
	dc_dialog = glade_xml_get_widget(xml, "dc_dialog");
	dc_selector = glade_xml_get_widget(xml, "dc_selector");
	dc_device_type = glade_xml_get_widget(xml, "dc_device_type");
	dc_status = glade_xml_get_widget(xml, "dc_status");
	dc_on_level = glade_xml_get_widget(xml, "dc_on_level");
	dc_dimmer = glade_xml_get_widget(xml, "dc_dimmer");
	dc_local_level = glade_xml_get_widget(xml, "dc_local_level");
	dc_local_ramp = glade_xml_get_widget(xml, "dc_local_ramp");
}

void on_device_control_activate(GtkWidget *widget, gpointer user_data)
{
	gtk_widget_show(dc_dialog);
}

void on_dc_selector_changed(GtkWidget *widget, gpointer user_data)
{
	int sel;
	char *device_type;
	int status;
	int level;
	int ramp;
	char *device_label;

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

	progress_bar_open("Reading device...", 5);

	/* set the device type label */
	device_type = device_type_name(
			((device_array[sel].device_type & 0xff00) >> 8),
			(device_array[sel].device_type & 0xff));
	status = insteon_read_byte(iplc, device_array[sel].device_id, 0x0002);
	progress_bar_update(20);

	device_label = malloc(strlen(device_type) + 12);
	if (device_label == NULL) {
		printf("Memory allocation failure\n");
		return;
	}
	memset(device_label, 0, sizeof(device_label));
	sprintf(device_label, "%s Rev. %d.%d\n", device_type,
			((status >> 4) & 0x0f), (status & 0x0f));
	gtk_label_set_text((GtkLabel *)dc_device_type, device_label);

	set_status(sel);
	current_level = status & 0xff;
	progress_bar_update(40);

	level = insteon_read_byte(iplc, device_array[sel].device_id, 0x0020);
	progress_bar_update(60);
	gtk_spin_button_set_value((GtkSpinButton *)dc_local_level,
			(gdouble)(level & 0xff));
	ramp = insteon_read_byte(iplc, device_array[sel].device_id, 0x0021);
	progress_bar_update(80);
	gtk_spin_button_set_value((GtkSpinButton *)dc_local_ramp,
			(gdouble)(ramp & 0xff));

#if 0
	status = insteon_read_byte(iplc, device_array[sel].device_id, 0x0001);
	progress_bar_update(50);
	printf("EEProm size = 0x%04x\n", (status * 256));
	status = insteon_read_byte(iplc, device_array[sel].device_id, 0x0002);
	printf("Firmware Rev = 0x%02x\n", (status & 0xff));
	status = insteon_read_byte(iplc, device_array[sel].device_id, 0x0030);
	progress_bar_update(60);
	printf("X10 House Code 0x%02x\n", (status & 0xff));
	status = insteon_read_byte(iplc, device_array[sel].device_id, 0x0031);
	progress_bar_update(70);
	printf("X10 Unite Code 0x%02x\n", (status & 0xff));
#endif

	progress_bar_close();
	free(device_label);
}

void on_dc_set_level_clicked(GtkWidget *widget, gpointer user_data)
{
	int sel;
	unsigned char level;

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

	level = (unsigned char)gtk_range_get_value((GtkRange *)dc_dimmer);
	current_level = level;

	insteon_send_msg(iplc, ON, level, device_array[sel].device_id);
	set_status(sel);
}


void on_dc_up_clicked(GtkWidget *widget, gpointer user_data)
{
	int sel;

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

	insteon_send_msg(iplc, START_MANUAL_CHNG, 0x01, device_array[sel].device_id);
	/* set_status(sel); */
}

void on_dc_up_released(GtkWidget *widget, gpointer user_data)
{
	int sel;

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

	insteon_send_msg(iplc, STOP_MANUAL_CHNG, 0x00, device_array[sel].device_id);
	set_status(sel);
}

void on_dc_down_clicked(GtkWidget *widget, gpointer user_data)
{
	int sel;

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

	insteon_send_msg(iplc, START_MANUAL_CHNG, 0x00, device_array[sel].device_id);
	/* set_status(sel); */
}

void on_dc_down_released(GtkWidget *widget, gpointer user_data)
{
	int sel;

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

	insteon_send_msg(iplc, STOP_MANUAL_CHNG, 0x00, device_array[sel].device_id);
	set_status(sel);
}




void on_dc_off_clicked(GtkWidget *widget, gpointer user_data)
{
	int sel;

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

	/* send off */
	insteon_send_msg(iplc, OFF, 0x00, device_array[sel].device_id);

	/* update status */
	set_status(sel);
}

void on_closebutton2_clicked(GtkWidget *widget, gpointer user_data)
{
	gtk_widget_hide(dc_dialog);
}

void on_dc_dialog_delete_event(GtkWidget *widget, gpointer user_data)
{
	gtk_widget_hide(dc_dialog);
}


void on_dc_apply_clicked(GtkWidget *widget, gpointer user_data)
{
	int sel;
	int level;
	int ramp;

	sel = gtk_combo_box_get_active((GtkComboBox *)dc_selector);
	if (sel == -1) {
		printf("No device selected!\n");
		return;
	}
	/* Write new levels to device */
	level = gtk_spin_button_get_value_as_int((GtkSpinButton *)dc_local_level);
	insteon_write_byte(iplc, device_array[sel].device_id, 0x0020,
			(level & 0xff));
	ramp = gtk_spin_button_get_value_as_int((GtkSpinButton *)dc_local_ramp);
	insteon_write_byte(iplc, device_array[sel].device_id, 0x0021,
			(ramp & 0xff));

	/* Save new values in device record */
	device_array[sel].local_on_level = (level & 0xff);
	device_array[sel].local_ramp_rate = (ramp & 0xff);
}

static void set_status(int sel)
{
	char status_str[40];
	unsigned int status;

	/* update status */
	status = insteon_send_msg(iplc, STATUS_REQUEST, 0x00,
			device_array[sel].device_id);

	sprintf(status_str, "On level = %d (%d%%)", (status & 0xff),
			((status & 0x0ff) * 100) / 255);
	gtk_entry_set_text((GtkEntry *)dc_status, status_str);
	gtk_range_set_value((GtkRange *)dc_dimmer, (gdouble)(status & 0xff));
}
