#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

#define PI 3.14159265358979323846

double degToRad(double deg){ return deg * PI / 180.0; }
double radToDeg(double rad){ return rad * 180.0 / PI; }

int dayOfYear(int y, int m, int d)
{
    int k = (m <= 2) ? 0 :
        ((y%4==0 && y%100!=0) || (y%400==0)) ? 1 : 2;

    return (int)((275*m)/9) - k*((m+9)/12) + d - 30;
}

double calcSunTime(int rise, double lat, double lon)
{
    time_t now = time(NULL);
    struct tm *utc = gmtime(&now);

    int N = dayOfYear(utc->tm_year+1900,
                      utc->tm_mon+1,
                      utc->tm_mday);

    double lngHour = lon / 15.0;

    double t = rise ?
        N + ((6 - lngHour) / 24.0) :
        N + ((18 - lngHour) / 24.0);

    double M = (0.9856 * t) - 3.289;

    double L = M + (1.916 * sin(degToRad(M)))
                 + (0.020 * sin(2 * degToRad(M)))
                 + 282.634;

    while(L < 0) L += 360;
    while(L >= 360) L -= 360;

    double RA = radToDeg(atan(0.91764 * tan(degToRad(L))));
    while(RA < 0) RA += 360;
    while(RA >= 360) RA -= 360;

    double Lquadrant  = floor(L/90) * 90;
    double RAquadrant = floor(RA/90) * 90;
    RA += (Lquadrant - RAquadrant);
    RA /= 15;

    double sinDec = 0.39782 * sin(degToRad(L));
    double cosDec = cos(asin(sinDec));

    double cosH = (cos(degToRad(90.833)) -
                  (sinDec * sin(degToRad(lat)))) /
                  (cosDec * cos(degToRad(lat)));

    if (cosH > 1 || cosH < -1) return -1;

    double H = rise ?
        360 - radToDeg(acos(cosH)) :
        radToDeg(acos(cosH));

    H /= 15;

    double T = H + RA - (0.06571 * t) - 6.622;
    double UT = T - lngHour;

    while(UT < 0) UT += 24;
    while(UT >= 24) UT -= 24;

    return UT;   // RETURNING UTC
}

int main(int argc, char *argv[])
{
    if(argc != 3) {
        printf("Content-Type: application/json\n\n");
        printf("{\"error\":\"missing lat/lon\"}\n");
        return 1;
    }

    double lat = atof(argv[1]);
    double lon = atof(argv[2]);

    double sunrise = calcSunTime(1, lat, lon);
    double sunset  = calcSunTime(0, lat, lon);

    if(sunrise < 0 || sunset < 0) {
        printf("Content-Type: application/json\n\n");
        printf("{\"error\":\"no sunrise/set\"}\n");
        return 1;
    }

    int rise_h = (int)sunrise;
    int rise_m = (int)((sunrise - rise_h) * 60);

    int set_h  = (int)sunset;
    int set_m  = (int)((sunset - set_h) * 60);

    printf("Content-Type: application/json\n\n");
    printf("{\"sunrise_utc\":\"%02d:%02d\",\"sunset_utc\":\"%02d:%02d\"}\n",
           rise_h, rise_m, set_h, set_m);

    return 0;
}
