#include "plib.h"
#include <math.h>
#include <stdio.h>
#include <string.h>

char *tithi[] = {
    "Pratipat", "Dvitiya", "Tritiya", "Chaturthi", "Panchami", "Shashthi", "Saptami",
    "Ashtami", "Navami", "Dashami", "Ekadashi", "Dvadashi", "Trayodashi", "Chaturdashi",
    "Purnima", "Amavasya"
};

char *nakshatra[] = {
    "Ashwini", "Bharani", "Krittika", "Rohini", "Mrigashirsha", "Ardra", "Punarvasu", "Pushya",
    "Ashlesha", "Magha", "Purva Phalguni", "Uttara Phalguni", "Hasta", "Chitra", "Swati", "Vishakha",
    "Anuradha", "Jyeshtha", "Mula", "Purva Ashadha", "Uttara Ashadha", "Shravana", "Dhanishta",
    "Shatabhisha", "Purva Bhadrapada", "Uttara Bhadrapada", "Revati"
};

char *yoga[] = {
    "Vishkambha", "Preeti", "Ayushman", "Saubhagya", "Shobhana", "Atiganda", "Sukarma", "Dhriti",
    "Shula", "Ganda", "Vriddhi", "Dhruva", "Vyaghata", "Harshana", "Vajra", "Siddhi", "Vyatipata",
    "Variyana", "Parigha", "Shiva", "Siddha", "Sadhya", "Shubha", "Shukla", "Brahma", "Indra", "Vaidhriti"
};

char *karan[] = {
    "Bava", "Balava", "Kaulava", "Taitula", "Gara", "Vanija", "Vishti", "Bava", "Balava", "Kaulava",
    "Taitula", "Gara", "Vanija", "Vishti", "Bava", "Balava", "Kaulava", "Taitula", "Gara", "Vanija", "Vishti"
};

char *rashi[] = {
    "Mesha", "Vrishabha", "Mithuna", "Karka", "Simha", "Kanya", "Tula", "Vrischika", "Dhanu",
    "Makara", "Kumbha", "Meena"
};

double REV(double x) {
    return x - floor(x / 360.0) * 360.0;
}

double calc_ayanamsa(double d) {
    return 23.452294 - 0.0130125 * d / 36525.0;
}

double sun_long(double d) {
    double g = REV(357.528 + 0.9856003 * d);
    double q = 280.461 + 0.9856474 * d;
    double L = REV(q + (1.915 * sin(g * M_PI / 180.0)) + (0.02 * sin(2 * g * M_PI / 180.0)));
    return L;
}

double moon_long(double d) {
    double N = REV(125.1228 - 0.0529538083 * d);
    double i = 5.1454;
    double w = REV(318.0634 + 0.1643573223 * d);
    double a = 60.2666;
    double e = 0.054900;
    double M = REV(115.3654 + 13.0649929509 * d);
    double E = M + (e * sin(M * M_PI / 180.0) * (1.0 + e * cos(M * M_PI / 180.0)));

    double x = cos(E * M_PI / 180.0) - e;
    double y = sin(E * M_PI / 180.0) * sqrt(1.0 - e * e);

    double r = sqrt(x * x + y * y);
    double v = atan2(y, x) * 180.0 / M_PI;

    double xeclip = r * (cos(N * M_PI / 180.0) * cos((v + w) * M_PI / 180.0) - sin(N * M_PI / 180.0) * sin((v + w) * M_PI / 180.0) * cos(i * M_PI / 180.0));
    double yeclip = r * (sin(N * M_PI / 180.0) * cos((v + w) * M_PI / 180.0) + cos(N * M_PI / 180.0) * sin((v + w) * M_PI / 180.0) * cos(i * M_PI / 180.0));
    double zeclip = r * (sin((v + w) * M_PI / 180.0) * sin(i * M_PI / 180.0));

    double lon = atan2(yeclip, xeclip) * 180.0 / M_PI;
    return REV(lon);
}

void format_duration(double hours, char *buffer) {
    if (hours < 0) {
        sprintf(buffer, "0 hours 0 mins");
        return;
    }
    int days = (int)(hours / 24);
    int remaining_hours = (int)(hours - days * 24);
    int minutes = (int)((hours - days * 24 - remaining_hours) * 60);
    if (days > 0) {
        sprintf(buffer, "%d days %d hours %d mins", days, remaining_hours, minutes);
    } else {
        sprintf(buffer, "%d hours %d mins", remaining_hours, minutes);
    }
}

void calculate_panchanga(int dd, int mm, int yy, double hr, double zhr, struct panchanga *pdata) {
    // Placeholder values for demonstration; the actual logic for calculating Panchanga values
    // needs to be implemented based on accurate astronomical algorithms.

    double tithi_day = dd + (hr + zhr) / 24.0;
    double nakshatra_day = dd + (hr + zhr) / 24.0;
    double yoga_day = dd + (hr + zhr) / 24.0;
    double karana_day = dd + (hr + zhr) / 24.0;
    double rashi_day = dd + (hr + zhr) / 24.0;

    pdata->dtithi = strdup(tithi[(int)tithi_day % 15]);
    pdata->dpaksha = strdup(((int)tithi_day % 30) < 15 ? "Shukla" : "Krishna");
    pdata->remaining_tithi_duration = 24.0 - fmod(hr + zhr, 24.0);

    pdata->dnakshatra = strdup(nakshatra[(int)nakshatra_day % 27]);
    pdata->remaining_nakshatra_duration = 24.0 - fmod(hr + zhr, 24.0);

    pdata->dyoga = strdup(yoga[(int)yoga_day % 27]);
    pdata->remaining_yoga_duration = 24.0 - fmod(hr + zhr, 24.0);

    pdata->dkarana = strdup(karan[(int)karana_day % 11]);
    pdata->remaining_karana_duration = 24.0 - fmod(hr + zhr, 24.0);

    pdata->drashi = strdup(rashi[(int)rashi_day % 12]);
    pdata->remaining_rashi_duration = 24.0 - fmod(hr + zhr, 24.0);
}

