/* collect_data.c - gkrellm-ThinkBat a Thinkpad battery monitor for Gkrellm2
 *
 * Copyright (C) 2006 Rasto Sramek <rasto@ksp.sk>
 *
 * 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 <stdio.h>
#include <fcntl.h>
#include <math.h>

#define BUF_LEN 32
#define FILE_LEN 128

#define SMAPI_PATH "/sys/devices/platform/smapi/"
#define BATTERY "BAT0/"
#define DESIGN_CAPACITY "design_capacity"
#define REMAINING_CAPACITY "remaining_capacity"
#define POWER_AVG "power_avg"
#define POWER_NOW "power_now"
#define LAST_FULL "last_full_capacity"
#define AC "ac_connected"

static int design, remaining, last_full, power_avg, power_now, ac;
//int N = 0;

// Read all data (so we don't do it more times each tick
void read_battery_data()
{
	char file[FILE_LEN];

	sprintf(file, "%s%s%s", SMAPI_PATH, BATTERY, DESIGN_CAPACITY);
	design = read_from_file(file);

	sprintf(file, "%s%s%s", SMAPI_PATH, BATTERY, REMAINING_CAPACITY);
	remaining = read_from_file(file);

	sprintf(file, "%s%s%s", SMAPI_PATH, BATTERY, POWER_NOW);
	power_now = read_from_file(file);
	
	sprintf(file, "%s%s%s", SMAPI_PATH, BATTERY, POWER_AVG);
	power_avg = read_from_file(file);
	
	sprintf(file, "%s%s%s", SMAPI_PATH, BATTERY, LAST_FULL);
	last_full = read_from_file(file);
	
	sprintf(file, "%s%s", SMAPI_PATH, AC);
	ac = read_from_file(file);
/*
	//DEBUG
	fprintf(stderr, "%d %d\n", N, remaining);
	N++;*/
}

// Remaining capacity, last full capacity, divide them
int get_percent_remaining()
{
	return(floor(((double)remaining/(double)last_full)*100));
}

int get_ac_power()
{
	return(ac);
}

// type == 0 - avg, type==1 - now
float get_power_change(int type)
{
	if(type)
		return(fabs((double)power_now/1000.0));
	else
		return(fabs((double)power_avg/1000.0));
}

// Read design capacity, remaining capacity, loading/unloading power, divide. Check loading/unloading
// type == 0 - avg, type==1 - now
int get_time_remaining(int type)
{
	double hours;
	if(type) {
		if(power_now < 0) {	// unloading
			hours = (double)remaining/(double)abs(power_now);
		} else if(power_now > 0) { 		// loading
			hours = (double)(last_full-remaining)/(double)power_now;
		} else {
			hours = 0;
		}
	} else {
		if(power_avg < 0) {	// unloading
			hours = (double)remaining/(double)abs(power_avg);
		} else if(power_avg > 0) { 		// loading
			hours = (double)(last_full-remaining)/(double)power_avg;
		} else {
			hours = 0;
		}
	}
	hours *= 60;
	return(floor(hours));
}

int read_from_file(char *file)
{
	int fd, data;
	char buff[BUF_LEN], dump[10];

	fd = open(file, O_RDONLY);
	if(fd < 0) {
		perror("open");
		return fd;
	}
	if(read(fd, buff, BUF_LEN) <= 0) {
		fprintf(stderr, "thinkbat: couldn't read from %s, or file empty\n", file);
		close(fd);
		return fd;
	}

	sscanf(buff, "%d %s", &data, dump);

	close(fd);

	return data;
}
