#include <stdio.h>
#include <stdlib.h>
#include <math.h> /* link against math lib */
#include "calculate.h"

#define R 8314.3 //J/(kmol*K) (universelle Gaskonstante)
#define mw 18.016 //kg/kmol (Molekulargewicht des Wasserdampfes)

/*
Bezeichnungen:
r = relative Luftfeuchte
T = Temperatur in °C
TK = Temperatur in Kelvin (TK = T + 273.15)
TD = Taupunkttemperatur in °C
DD = Dampfdruck in hPa
SDD = Sättigungsdampfdruck in hPa

Parameter:
a = 7.5, b = 237.3 für T >= 0
a = 7.6, b = 240.7 für T < 0 über Wasser (Taupunkt)
a = 9.5, b = 265.5 für T < 0 über Eis (Frostpunkt)

R* = 8314.3 J/(kmol*K) (universelle Gaskonstante)
mw = 18.016 kg/kmol (Molekulargewicht des Wasserdampfes)
AF = absolute Feuchte in g Wasserdampf pro m3 Luft

Formeln:

    SDD(T) = 6.1078 * 10^((a*T)/(b+T))
    DD(r,T) = r/100 * SDD(T)
    r(T,TD) = 100 * SDD(TD) / SDD(T)
    TD(r,T) = b*v/(a-v) mit v(r,T) = log10(DD(r,T)/6.1078)
    AF(r,TK) = 10^5 * mw/R* * DD(r,T)/TK; AF(TD,TK) = 10^5 * mw/R* * SDD(TD)/TK
*/

static float sdd(float temperature) {
  //select constant based on input temperature
  float a = 7.5, b = 237.3;
  if (temperature >= 0) {
    a = 7.6;
    b = 240.7;
  }
  return 6.1078 * pow(10, (a * temperature) / (b + temperature));
}

static float dd(float relativeHumidity, float temperature) {
  return relativeHumidity / 100 * sdd(temperature);
}

/* CURRENTLY UNUSED

static float r(float temperature, float dewTemperature) {
  // This is optional. Necessary with dew point measurements.
  return 100 * sdd(dewTemperature) / sdd(temperature);
}

static float v(float relativeHumidity, float temperature) {
  log10(dd(relativeHumidity, temperature)/6.1078);
}

static float td(float relativeHumidity, float temperature) {
  //select constant based on input temperature
  float a = 7.5, b = 237.3;
  if (temperature >= 0) {
    a = 7.6;
    b = 240.7;
  }
  return b * v(relativeHumidity, temperature) / (a - v(relativeHumidity, temperature));
}
*/
static float af(float relativeHumidity, float temperature) {
    float tk = temperature + 273.15;
    return pow(10, 5) * mw/R * dd(relativeHumidity, temperature) / tk;
}

float absoluteHumidity(sensor *sensor) {
    return af(sensor->humidity, sensor->temperature);
}

float absoluteHumidityFloat(float temperature, float humidity) {
    return af(humidity, temperature);
}

int compareSensors(sensor *inside, sensor *outside) {
        //returns 1 if window should be opened
	if (absoluteHumidity(inside) <= absoluteHumidity(outside)) return 1;
	return 0;
}
  
