#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <libacpi.h>

#include "error.h"


void emit_ts(void)
{
	time_t now = time(NULL);

	printf("%s", ctime(&now));
}

void header(char *header_shown)
{
	if (!*header_shown)
	{
		emit_ts();
		*header_shown = 1;
	}
}

void emit_battery(global_t *globals, char *header_shown)
{
	int loop;
	static int *prevs = NULL;

	if (!prevs)
	{
		int bytes = sizeof(int) * globals -> batt_count;
		prevs = malloc(bytes);
		memset(prevs, 0x00, bytes);
	}

	for(loop=0; loop<globals -> batt_count; loop++)
	{
		int rc = read_acpi_batt(loop);

		if (rc == ITEM_EXCEED)
			break;
		if (rc == ALLOC_ERR)
			error_exit("reac_acpi_batt(%d) failed\n", loop);

		if (prevs[loop] != batteries[loop].percentage)
		{
			header(header_shown);
			printf("%s remaining capacity: %d%% (%d minutes)\n", batteries[loop].name, batteries[loop].percentage, batteries[loop].remaining_time);
			prevs[loop] = batteries[loop].percentage;
		}
	}
}

char * power_state_str(power_state_t ps)
{
	switch(ps)
	{
		case P_AC:
			return "AC";

		case P_BATT:
			return "batteries";

		case P_ERR:
			return "error";
	}

	return "?";
}

void emit_acstate(global_t *globals, char *header_shown)
{
	static int prev_state = -1;

	read_acpi_acstate(globals);

	if (prev_state != globals -> adapt.ac_state)
	{
		header(header_shown);
		printf("Adapter %s: %s\n", globals -> adapt.name, power_state_str(globals -> adapt.ac_state));
		prev_state = globals -> adapt.ac_state;
	}
}

char * thermal_state_str(thermal_state_t ts)
{
	switch(ts)
	{
		case T_CRIT:
			return "critical temperature, will switch to S4";

		case T_HOT:
			return "high temperature, will shutdown immediately";

		case T_PASS:
			return "passive cooling";

		case T_ACT:
			return "active cooling";

		case T_OK:
			return "ok";

		case T_ERR:
			return "error";
	}

	return "?";
}

void emit_zone(global_t *globals, char *header_shown)
{
	int loop;
	static int *prevs = NULL;
	static int *prevs_ts = NULL;

	if (!prevs)
	{
		int bytes = sizeof(int) * globals -> thermal_count;
		prevs = malloc(bytes);
		prevs_ts = malloc(bytes);
		memset(prevs, 0x00, bytes);
		memset(prevs_ts, 0x00, bytes);
	}

	for(loop=0; loop<globals -> thermal_count; loop++)
	{
		int rc = read_acpi_zone(loop, globals);

		if (rc == ITEM_EXCEED)
			break;
		if (rc == ALLOC_ERR)
			error_exit("reac_acpi_zone(%d) failed\n", loop);

		if (prevs[loop] != thermals[loop].temperature ||
		    prevs_ts[loop] != thermals[loop].therm_state)
		{
			header(header_shown);
			printf("temperature %s: %d (%s)\n", thermals[loop].name, thermals[loop].temperature, thermal_state_str(thermals[loop].therm_state));
			prevs[loop] = thermals[loop].temperature;
			prevs_ts[loop] = thermals[loop].therm_state;
		}
	}
}

char * fan_state_str(fan_state_t fs)
{
	switch(fs)
	{
		case F_ON:
			return "on";

		case F_OFF:
			return "off";

		case F_ERR:
			return "error state";
	}

	return "?";
}

void emit_fan(global_t *globals, char *header_shown)
{
	int loop;
	static int *prevs = NULL;

	if (!prevs)
	{
		int bytes = sizeof(int) * globals -> fan_count;
		prevs = malloc(bytes);
		memset(prevs, 0x00, bytes);
	}

	for(loop=0; loop<globals -> fan_count; loop++)
	{
		int rc = read_acpi_fan(loop);

		if (rc == ITEM_EXCEED)
			break;
		if (rc == ALLOC_ERR)
			error_exit("reac_acpi_fan(%d) failed\n", loop);

		if (prevs[loop] != fans[loop].fan_state)
		{
			header(header_shown);
			printf("fan %s: %s\n", fans[loop].name, fan_state_str(fans[loop].fan_state));
			prevs[loop] = fans[loop].fan_state;
		}
	}
}
