//
// anyRemote
// a wi-fi or bluetooth remote for your PC.
//
// Copyright (C) 2006-2016 Mikhail Fedotov <anyremote@mail.ru>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
//

//
// Main loop
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

#include "lib_wrapper.h"

#include "conf.h"
#include "utils.h"
#include "alarm.h"
#include "queue.h"
#include "dispatcher.h"
#include "peer.h"
#include "pr_frontend.h"

extern void aboutToExit();

boolean_t adminRoutine(pointer_t data)
{
    int *mi = (int*) queuePop(Q_MAIN);

    if (mi != NULL) {

        int m = *mi;
        free(mi);

        if (m == M_ABORT) {
            logger(L_DBG,"[ML]: got exit request");
        
            addKeepalive("-1");
            
            aboutToExit();    // exit here

        } else if (m == M_DISCONNECT) {
            logger(L_DBG,"[ML]: got disconnect request");
        
            addKeepalive("-1");

            if (!autoConnect() && 
                needExit() == EXIT_OK) {   // no active connection (and all peers are clients)
                logger(L_DBG,"[ML]: Exit because of disconnect");
                aboutToExit();    // exit here
            }
        }
    }
    
    keepaliveTest();
    
    return BOOL_YES;
}

#ifdef USE_GLIB

static GMainLoop *loop      = NULL;

gboolean alarmTimeout(gpointer data)
{
    //logger(L_DBG,"[ML]: alarmTimeout");
    manageAlarms(ALARM_CHECK);
    return TRUE;
}

void loopStart()
{
    loop = g_main_loop_new(NULL, FALSE);
 
    g_timeout_add(100,   adminRoutine,   NULL);    // 1/10 of second
    g_timeout_add(15000, alarmTimeout,   NULL);

    //logger(L_DBG,"g_main_loop_run");
    g_main_loop_run(loop);
}

void loopStop()
{
    g_main_loop_quit(loop);
}

void loopDestroy()
{
    g_main_loop_unref(loop);
}

#else

static int _alarmTimer       = 0;
static int _frontendTimer    = 0;

void loopStart()
{
    while (1) {      
    
        if (queueCanPop(Q_MAIN)) {
            adminRoutine(NULL);
        }

        // about 15 seconds
        _alarmTimer++;
        if (_alarmTimer > 150) {
            manageAlarms(ALARM_CHECK);
            _alarmTimer = 0;
        }

        // about 1/10 seconds
        keepaliveTest();
        
        // Main loop timer (1/10 of second)
        usleep(100000);
    }  
}


void loopStop()     // do nothing
{
}

void loopDestroy()     // do nothing
{
}

#endif
