/*
 * Copyright (C) 2005 Alex Murray <pragmatine@gmail.com>
 *
 * 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
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */

#include "i8k-sensors-interface.h"
#include "sensors-applet.h"

#define I8K_DEVICE_PATH "/proc/i8k"
#define I8K_DEVICE_FILE "i8k"

/* for error handling */
#define I8K_DEVICE_FILE_ERROR (i8k_sensors_interface_device_file_error_quark())

enum {
	I8K_DEVICE_FILE_OPEN_ERROR,
	I8K_DEVICE_FILE_READ_ERROR
};


static void i8k_sensors_interface_setup_manually(SensorsApplet *sensors_applet) {
	if (g_file_test(I8K_DEVICE_PATH, G_FILE_TEST_EXISTS)) {
		/* with i8k have only 3 fixed sensors, all accessed
		   from the I8K_DEVICE_PATH */
		sensors_applet_add_sensor(sensors_applet,
					  I8K_DEVICE_PATH,
					  "temp1",
					  _("CPU"),
					  I8K,
					  TRUE,
					  TEMP_SENSOR,
					  CPU_ICON);
		sensors_applet_add_sensor(sensors_applet,
					  I8K_DEVICE_PATH,
					  "fan1",
					  _("FAN1"),
					  I8K,
					  FALSE,
					  FAN_SENSOR,
					  FAN_ICON);
		sensors_applet_add_sensor(sensors_applet,
					  I8K_DEVICE_PATH,
					  "fan2",
					  _("FAN2"),
					  I8K,
					  FALSE,
					  FAN_SENSOR,
					  FAN_ICON);
	}
}
/* to be called externally to setup for i8k sensors */
void i8k_sensors_interface_init(SensorsApplet *sensors_applet) {
	sensors_applet_register_sensors_interface(sensors_applet,
						  I8K,
						  i8k_sensors_interface_get_sensor_value);
	i8k_sensors_interface_setup_manually(sensors_applet);
		
}

/* for error handling */
static GQuark i8k_sensors_interface_device_file_error_quark(void) {
	static GQuark quark = 0;
	gchar *string;

	if (quark == 0) {
		string = g_strdup_printf("%s-device-file-error", sensor_interface[I8K]);
		quark = g_quark_from_string(string);
		g_free(string);
	}

	return quark;
}

gdouble i8k_sensors_interface_get_sensor_value(const gchar *path, 
					      const gchar *id, 
					      SensorType type,
					      GError **error) {

	/* to open and access the value of each sensor */
	FILE *fp;
	gint cpu_temp, fan1_status, fan2_status, fan1_rpm, fan2_rpm;
	gint sensor_value;
	gint space_count, file_length;
	
	if (NULL == (fp = fopen(path, "r"))) {
		g_set_error(error, I8K_DEVICE_FILE_ERROR, I8K_DEVICE_FILE_OPEN_ERROR, "Error opening sensor device file %s", path);
		return;
	}

	space_count = 0;
	file_length = 0;

	/* count spaces but stop if have counted 100 characters and
	   still not found a space (to avoid infinite loop if file
	   format error) */
	while (file_length < 100 && space_count < 3) {
		if (fgetc(fp) == ' ') {
			space_count++;
		}
		file_length++;
	}

	if (fscanf(fp, "%d %d %d %d %d", &cpu_temp, &fan1_status, &fan2_status, &fan1_rpm, &fan2_rpm) != 5) {
		g_set_error(error, I8K_DEVICE_FILE_ERROR, I8K_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path);
		fclose(fp);
		return;
	}
	fclose(fp);

	switch (type) {
	case TEMP_SENSOR:
		sensor_value = cpu_temp;
		break;
	case FAN_SENSOR:
		switch (id[3]) {
		case '1':
			sensor_value = fan1_rpm;
			break;
		case '2':
			sensor_value = fan2_rpm;
			break;
		default:
			g_assert_not_reached();			
		}
		break;

	default:
		g_assert_not_reached();			
	} // end switch (sensor_type)

	return (gdouble)sensor_value;

}


syntax highlighted by Code2HTML, v. 0.9.1