/*
* wmacpimon v0.2.1
* (C) 2002 Costantino Pistagna (valvoline@vrlteam.org)
* wmacpimon homepage: http://www.vlrteam.org/wmacpimon
*
* 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 <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>

#include "wmacpimon.h"

#ifdef ACPI
extern ACPInfo *acpinfo;

/* see if we have ACPI support and check version */
int power_init(void) {
    FILE *acpi;
    char buf[4096];
    int acpi_ver = 0;
    if (!(acpi = fopen("/proc/acpi/info", "r"))) {
		fprintf(stderr, "This system does not support ACPI\n");
		return 1;
    }

    /* okay, now see if we got the right version */
    fread(buf, 4096, 1, acpi);
    acpi_ver = strtol(buf + 25, NULL, 10);
    fprintf(stderr, "ACPI version detected: %d\n", acpi_ver);
    if (acpi_ver < 20020214) {
		fprintf(stderr, "This version requires ACPI subsystem version 20020214 or later\n");
		fclose(acpi);
		return 1;
    }
    /* yep, all good */
    fclose(acpi);

    /* tell user some info */
    fprintf(stderr, "wmacpimon: successfully started!\n"); 
    return 0;
}

void init_acpinfo(void) {
	acpinfo->percentage=0;
    strcpy(acpinfo->speed, "\0");
	acpinfo->cooling=0;
	acpinfo->crit_level=10;
	acpinfo->state=0;
	acpinfo->batt=0;
	acpinfo->load=0;
	acpinfo->charge=0;
	acpinfo->remain=0;
	acpinfo->currcap=0;
}

void acquire_info() {
    FILE *fd;
    char *ptr;
	float tmp;
	char *buf, *t2;
	
	buf=(char *)malloc(sizeof(char)*512);
	t2=(char *)malloc(sizeof(char)*10);
	
	/* search for thermal_zone_state OK */	
   	if ((fd = fopen("/proc/acpi/thermal_zone/THRM/state", "r"))) {
		bzero(buf, 512);
		fscanf(fd, "state: %s", buf);
		fclose(fd);
		if (strstr(buf, "active")) acpinfo->state=1;
	}
   	else if ((fd = fopen("/proc/acpi/thermal_zone/THM0/state", "r"))) {
		bzero(buf, 512);
		fscanf(fd, "state: %s", buf);
		fclose(fd);
		if (strstr(buf, "active")) acpinfo->state=1;
	}
	
	/* get acpi thermal cpu info */
	if ((fd = fopen("/proc/acpi/thermal_zone/THRM/temperature", "r"))) {
		fscanf(fd, "temperature: %d", &acpinfo->percentage);
		fclose(fd);
	}

	/* search for current speedstep setting */ 
   	if ((fd = fopen("/proc/acpi/processor/CPU0/performance", "r"))) {
		bzero(buf, 512);
		bzero(t2, 10);
		fread(buf, 512, 1, fd);
		fclose(fd);
		ptr = strstr(buf, "active state");
   		if(ptr != NULL) {
			ptr += 25;
			t2[0]=ptr[0];
			t2[1]=ptr[1];
			t2[2]=':';
			t2[3]='\0';
			ptr = strstr(buf, t2);
			if(ptr != NULL) {
				ptr += 21;
				sscanf(ptr, "%s", acpinfo->speed);
			}
		}
	}
	
	/* check for FAN state */
   	if ((fd = fopen("/proc/acpi/thermal_zone/THRM/cooling_mode", "r"))) {
		bzero(buf, 512);
		fscanf(fd, "cooling mode: %s", buf);
		fclose(fd);
		if(strstr(buf, "active")) acpinfo->cooling=1;
	}

	/* check for BATT or AC mode */
	if ((fd = fopen("/proc/acpi/ac_adapter/ACAD/state", "r"))) {
		bzero(buf, 512);
		fscanf(fd, "state: %s", buf);
		fclose(fd);
		if(strstr(buf, "on-line") != NULL) acpinfo->batt=0;
		if(strstr(buf, "off-line") != NULL) acpinfo->batt=1;
	}
	
	/* check for cpu load average */
	if ((fd = fopen("/proc/loadavg", "r"))) {
		bzero(buf, 512);
	   	fscanf(fd, "%f", &tmp);
		fclose(fd);
		acpinfo->load=(tmp*100);
	}

}

void acquire_info2() {
    FILE *fd, *fp;
    char *ptr;
	char *buf, *buf2, *t2;
	int capacity,remain;

	buf=(char *)malloc(sizeof(char)*512);
	buf2=(char *)malloc(sizeof(char)*512);
	t2=(char *)malloc(sizeof(char)*10);
	
	/* get info about battery charge */
	if ((fd = fopen("/proc/acpi/battery/BAT0/state", "r"))) {
		bzero(buf, 512);
		bzero(buf2, 512);
	   	fread(buf, 512, 1, fd);
		fclose(fd);
		if ((fp = fopen("/proc/acpi/battery/BAT0/info", "r"))) {
		   	fread(buf2, 512, 1, fp);
			fclose(fp);
			ptr = strstr(buf, "remaining capacity");
			if(ptr != NULL) {
				ptr += 25;
				acpinfo->currcap = remain = atoi(strtok(ptr, " "));
			}
			else remain = 0;
			ptr = strstr(buf2, "last full capacity");
			if(ptr != NULL) {
				ptr += 25;
				capacity = atoi(strtok(ptr, " "));
			}
			else capacity=0;
			ptr = strstr(buf, "charging state");
			if(ptr != NULL) {
				ptr +=25;
				if(strstr(ptr, "discharging")) {
					if(acpinfo->batt == 0) {
						acpinfo->charge=2; /*it's full*/
						acpinfo->remain=100;
					}
					if(acpinfo->batt == 1) {
						acpinfo->charge=1; /*discharging...*/
						acpinfo->remain=(100*remain)/capacity;
					}
				}
				else {
					acpinfo->charge=0; /* charging mode...*/
					acpinfo->remain=(100*remain)/capacity;
				}
			}
		}
	}
}

#endif /* ACPI */
