/****************************************************************************
 * This file is part of the project Gwenhywfar.
 * Gwenhywfar (c) by 2023 Martin Preuss, all rights reserved.
 *
 * The license for this file can be found in the file COPYING which you
 * should have received along with this file.
 ****************************************************************************/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "./eventhandler_p.h"

#include <gwenhywfar/debug.h>



GWEN_INHERIT_FUNCTIONS(AQH_EVENT_HANDLER)
GWEN_LIST_FUNCTIONS(AQH_EVENT_HANDLER, AQH_EventHandler)




AQH_EVENT_HANDLER *AQH_EventHandler_new()
{
  AQH_EVENT_HANDLER *evh;

  GWEN_NEW_OBJECT(AQH_EVENT_HANDLER, evh);
  GWEN_INHERIT_INIT(AQH_EVENT_HANDLER, evh);
  GWEN_LIST_INIT(AQH_EVENT_HANDLER, evh);

  evh->timerList=AQH_EventTimer_List_new();
  evh->subscriptionList=AQH_EventSubscription_List_new();

  return evh;
}



void AQH_EventHandler_free(AQH_EVENT_HANDLER *evh)
{
  if (evh) {
    GWEN_LIST_FINI(AQH_EVENT_HANDLER, evh);
    GWEN_INHERIT_FINI(AQH_EVENT_HANDLER, evh);

    AQH_EventSubscription_List_free(evh->subscriptionList);
    AQH_EventTimer_List_free(evh->timerList);
    GWEN_FREE_OBJECT(evh);
  }
}



AQH_EVENT_TIMER_LIST *AQH_EventHandler_GetTimerList(const AQH_EVENT_HANDLER *evh)
{
  return evh?evh->timerList:NULL;
}



void AQH_EventHandler_AddTimer(AQH_EVENT_HANDLER *evh, AQH_EVENT_TIMER *evt)
{
  if (evh && evt) {
    AQH_EventTimer_SetId(evt, ++(evh->lastTimerId));
    AQH_EventTimer_List_Add(evt, evh->timerList);
  }
}



AQH_EVENT_SUBSCRIPTION_LIST *AQH_EventHandler_GetSubscriptionList(const AQH_EVENT_HANDLER *evh)
{
  return evh?evh->subscriptionList:NULL;
}



void AQH_EventHandler_AddSubscription(AQH_EVENT_HANDLER *evh, AQH_EVENT_SUBSCRIPTION *evs)
{
  if (evh && evs)
    AQH_EventSubscription_List_Add(evs, evh->subscriptionList);
}



void AQH_EventHandler_HandleTimeTick(AQH_EVENT_HANDLER *evh, uint64_t t)
{
  if (evh) {
    AQH_EVENT_TIMER *evt;

    evt=AQH_EventTimer_List_First(evh->timerList);
    while(evt) {
      AQH_EVENT_TIMER *evtNext;

      evtNext=AQH_EventTimer_List_Next(evt);
      if (AQH_EventTimer_CheckWhetherTickTriggers(evt, t)) {
        AQH_EventHandler_HandleEvent(evh, AQH_EventTimer_GetEventType(evt), AQH_EventTimer_GetId(evt), 0.0);
        if (AQH_EventTimer_GetFlags(evt) & AQH_EVENT_TIMER_FLAGS_DELETE_IF_TRIGGERED) {
          DBG_INFO(AQH_LOGDOMAIN, "Deleting timer after trigger");
          AQH_EventTimer_List_Del(evt);
          AQH_EventTimer_free(evt);
        }
      }
      evt=evtNext;
    }
  }
}



void AQH_EventHandler_HandleEvent(AQH_EVENT_HANDLER *evh, int eventType, uint64_t objectId, double data)
{
  if (evh) {
    AQH_EVENT_SUBSCRIPTION *evs;

    evs=AQH_EventSubscription_List_First(evh->subscriptionList);
    while(evs) {
      if (AQH_EventSubscription_GetEventType(evs)==eventType) {
        int objectIdFromSubscription;

        objectIdFromSubscription=AQH_EventSubscription_GetObjectId(evs);
        if (objectIdFromSubscription==0 || objectIdFromSubscription==objectId)
          AQH_EventSubscription_CallHandler(evs, eventType, objectId, data);
      }

      evs=AQH_EventSubscription_List_Next(evs);
    }
  }
}








