/*******************************************************************************
 * Copyright (c) 2015-2017 ONERA and IRT AESE (IRT Saint Exupéry).
 * Ce logiciel est la propriété de l’ONERA (the French Aerospace Lab) et de
 * l'IRT AESE (IRT Saint Exupéry).
 * Tous droits réservés.
 *
 * Ce programme et les éléments qui l'accompagnent sont mis à disposition
 * aux conditions définies par le contrat de licence logiciel CeCILL-C soumise
 * au droit français et respectant les principes de diffusion des logiciels libres.
 * Vous pouvez utiliser, modifier et/ou redistribuer ce programme
 * sous les conditions de la licence CeCILL-C (http://www.cecill.info).

 * This software is property of ONERA (the French Aerospace Lab) and of
 * the IRT AESE (IRT Saint Exupéry).
 * All rights reserved.
 *
 * This program and the accompanying materials are made available under
 * the terms of the CeCILL-C license under French law and
 * abiding by the rules of distribution of free software.
 * You can  use, modify and/ or redistribute the software under the terms of
 * the CeCILL-C license (http://www.cecill.info).
 *
 * Contributeurs/contributors:
 *     Guillaume Infantes (ONERA - Centre de Toulouse) - initial API and implementation
 *     Alexandre Albore (IRT Saint-Exupéry) - Altarica/Fiacre translation
 *
 *******************************************************************************/

#ifndef ALTA_EVENT_H_
#define ALTA_EVENT_H_

#include <set>
#include <vector>
#include <string>

namespace epoch {
  namespace altarica {

    class Node;
    class Transition;
    class Synchronisation;
    class MetaEvent;
    class AltaricaState;
    class MemberAccess;
    class EventLaw;
    class AltaricaModel;

    //! EVENT
    /*!
      Stucture pour stocker les event et leur priorite
    */
    class Event {

    protected:

      //!
      //      std::string *name_;
      //! full qualified name
      MemberAccess *ma_;
      std::set<Event*> uppers_;
      std::set<Event*> lowers_;
      std::vector<std::string> attributes_;
      EventLaw * law_;

      Node * node_;
      std::vector<Transition *>  trans_;
      std::vector<Synchronisation*> syncs_;

    public:

      //!
      //      Event(std::string *name);
      Event(MemberAccess *ma);

      void addUppers(std::set<Event*>* b);
      void addUpper(Event *b);
      void addLowers(std::set<Event*>* b);
      void addLower(Event* b);
      void addAttribute(const std::string a);
      void addAttributes(const std::vector<std::string> *va);
      void setLaw(EventLaw* el);
      const EventLaw * getLaw() const;

      void setNode(Node* n);
      const Node* getNode();
      
      std::vector<const Node *>* getPath() const;
      std::string getFullName() const;

      const MemberAccess* getMA() const;

      void addTrans(Transition* t);
      const std::vector<Transition *> * getTrans() const {return &trans_;}
      void addSync(Synchronisation* s);

      int nSynchros();

      // void addPath(std::string* p);
      // void addPathIndexed(std::string* p, int i);

      std::set<Event*> const * getUppers();
      Event * clone();

      bool isMorePriorThan(Event*e);
      bool isLessPriorThan(Event*e);

      bool isEnabled(const AltaricaModel *am, AltaricaState *s);
      bool isDirac() const;

      void doEvent(const AltaricaModel *am, AltaricaState *s, AltaricaState *ns);

      std::string toString();
      ~Event();

      void deleteExprs() ;
      
    };
  }
}

#endif
