/* soldertimer.c */

#include <stdio.h>
#include <stdint.h>

#include <stddef.h>
#include <string.h>
#include <time.h>


typedef struct profile_line {
    int32_t temperature; /* store degrees C * 4096 */
    unsigned int time;
} profile_line_t;

typedef struct profile {
    char name[21];
    int32_t start_temp;
    profile_line_t lines[6];
} profile_t;

#define DEGREES * 4096

profile_t profile = {"Lead-free solder", 25 DEGREES, {
	{ 150 DEGREES, 100 },
	{ 200 DEGREES, 100 },
	{ 250 DEGREES,  40 },
	{ 250 DEGREES,  30 },
	{ 100 DEGREES,  30 },
	{ 0, 0 } }
    };

static int32_t expand_profile_temperature(uint8_t row)
{
    int32_t temp;

    if (row > 1)
	temp = profile.lines[row-2].temperature;
    else
	temp = profile.start_temp;

    return temp;
}

static uint32_t profile_time(uint8_t line)
{
    uint32_t time = profile.lines[line].time;
    return time;
}

static int finished;

static int32_t temperature_at_time(uint32_t time) {
    uint32_t time0, time1;
    int32_t temp0, temp1;
    uint8_t i;

    temp1 = expand_profile_temperature(1);
    time1 = 0;

    i = 0;
    do {
	uint32_t ptime;
	temp0 = temp1;
	time0 = time1;
	ptime = profile_time(i);
	if (ptime > 0) {
	    temp1 = expand_profile_temperature(2+i);
	    time1 += ptime;
	}
	i++;
	if (i >= 6)
	    break;
    } while (time > time1);

    if (time > time1) {
	finished = 1;
	temp0 = temp1;
	time0 = time1;
	time1 += 60; /* Arbitrary number here */
	temp1 = expand_profile_temperature(1);
    }

    if (time > time1)
	return expand_profile_temperature(1);

    return temp0 + (temp1 - temp0) * (int32_t)(time - time0) / (int32_t)(time1 - time0);
}

int main(void) {
    time_t start;
    time_t now;
    time_t end;

    finished = 0;

    time(&start);

    start = start + 10;

    while (!finished) {
	int32_t temp;
	struct timespec interval = {0, 2000000};
	time(&now);
	if (now < start)
	    temp = temperature_at_time(0);
	else
	    temp = temperature_at_time(now - start);
	printf("\r%4ds       %.1f degrees", (int)(now - start), (double)temp / 4096);
	fflush(stdout);
	nanosleep(&interval, NULL);
    }
    printf("\n");
}

