root/main.c

#include <curl/curl.h>
#include <locale.h>
#include <ncurses.h>
#include <pthread.h>
#include <unistd.h>
#include "TvShows.h"
#include "EpisodePage.h"
#include "Player.h"
#include "Colors.h"
#include "ServerEvents.h"

void printServerShit(const char* event, const char* data, void* userdata) {
    printf("ev: %s\n dataa: %s\n userdata:%p", event, data, userdata);
}

struct NetworkThreadData {
    struct ServerEvents* se;
    const char* url;
    bool* quit;
    CURLM* multiHandle;
};

void* networkThreadFn(void* userdata) {
    struct NetworkThreadData* data = userdata;
    ServerEvents_connect(data->se, data->url, data->multiHandle);
    int runningHandles = 0;
    while (!(*data->quit)) {
        curl_multi_perform(data->multiHandle, &runningHandles);
        usleep(100000);
    }
    return userdata;
}

int main(int argc, const char* argv[]) {
    char* url = NULL;
    if (argc >= 2) {
        url = (char*)argv[1];
    } else {
        url = "localhost:8082";
    }

    /* lib init */
    curl_global_init(CURL_GLOBAL_SSL);

    setlocale(LC_ALL, "");
    initscr();
    if (!has_colors()) {
        puts("terminal doesn't support colors\n");
    }
    start_color();
    Colors_init();
    Colors_set(Colors_Default);

    // init ncurses io settings
    cbreak(); // allow ctrl-Z, ctrl-C and other keys to keep their default actions
    noecho();
    keypad(stdscr, TRUE);

    printw("%s fetching lists...\n", url);
    refresh();

    /* page init */
    struct TvShows shows;
    TvShows_init(&shows);

    struct Player player;
    Player_init(&player);

    struct EpisodePage epPage;
    EpisodePage_init(&epPage);
    epPage.baseUrl = url;

    epPage.startPage = &shows;
    shows.episodePage = &epPage;

    void* activePage = &shows;
    epPage.activePage = &activePage;
    shows.activePage = &activePage;

    /* network thread */
    bool quit = false;
    CURLM* multiHandle = curl_multi_init();
    struct ServerEvents se;
    ServerEvents_init(&se);
    ServerEvents_addCallback(&se, Player_onServerEvent, &player);
    ServerEvents_addCallback(&se, EpisodePage_onServerEvent, &epPage);

    pthread_t networkThread;
    struct NetworkThreadData ntdata = {
        .se = &se,
        .url = url,
        .quit = &quit,
        .multiHandle = multiHandle
    };
    int threadError = pthread_create(&networkThread, NULL, networkThreadFn, &ntdata);
    if (threadError) {
        return 1;
    }

    /* update */
    TvShows_fetch(&shows, url);
    refresh();

    Player_fetch(&player, url);
    refresh();

    TvShows_printAll(&shows, NULL);
    /* main loop */
    do {
        int c = getch();
        if (c == 27 || c == 'q') {
            quit = true;
        } else if (c == KEY_RESIZE) {
            refresh();
        }
        bool handled = false;
        handled = TvShows_handleInput(&shows, c);
        handled = handled ? handled : EpisodePage_handleInput(&epPage, c);
        handled = handled ? handled : Player_handleInput(&player, c);

        Player_draw(&player);
        refresh();
    } while (!quit);

    pthread_cancel(networkThread);
    curl_multi_cleanup(multiHandle);
    ServerEvents_destroyMembers(&se);
    /* pthread_join(networkThread, NULL); */

    TvShows_destroyMembers(&shows);
    endwin();
    return 0;
}