/** @file    <%- compInfo.name %>.hpp 
 *  @author  <%- compInfo.Authors %>
 *  @date    <%= (new Date()).toISOString() %>
 *  @brief   This file declares the <%- compInfo.name %> class; <%- compInfo['Brief Description'] %>
 */

#ifndef <%- compInfo.name.toUpperCase() %>_INCLUDE_GUARD
#define <%- compInfo.name.toUpperCase() %>_INCLUDE_GUARD
#include "rosmod_actor/component.hpp"

#include <actionlib/client/simple_action_client.h>
#include <actionlib/server/simple_action_server.h>

<%
if (compInfo['State Machine_list']) {
  compInfo['State Machine_list'].map(function(hfsm) {
-%>
namespace StateMachine {
  class <%- hfsm.sanitizedName %>;
};
<%
  });
}
-%>

/**
 * Component Message and Service Headers
 */
<%
if (compInfo.Types.length) {
  compInfo.Types.map(function(type) {
-%>
#include "<%- type.Package %>/<%- type.IncludeName || type.TypeName %>.h"
<%
    });
 }
-%>

#include "ros/ros.h"

/**
 * Forward declarations
 */
//::::<%- compInfo.path %>::::Forwards::::
<%- compInfo.Forwards %>

/**
 * @brief <%- compInfo.name %> class
 */
class <%- compInfo.name %> : public Component
{
public:
<%
if (compInfo['State Machine_list']) {
  compInfo['State Machine_list'].map(function(hfsm) {
-%>
  // give HFSM access to this class.
  friend class StateMachine::<%- hfsm.sanitizedName %>;
<%
  });
}
-%>
  
  /**
   * @brief <%- compInfo.name %> Constructor.
   * @param _config Component configuration parsed from deployment JSON
   */
  <%- compInfo.name %>(Json::Value& _config);

 /**
   * @brief <%- compInfo.name %> Destructor
   */ 
  ~<%- compInfo.name %>() override;

 /**
   * @brief Component startup function
   *
   * This function configures all the component ports and timers
   */ 
  void startUp() override;

  /**
   * @brief <%- compInfo.name %> Initializer
   * This operation is executed immediately after startup.
   * @param[in] event a oneshot timer event
   * @see startUp()
   */
  void init_timer_operation(const ros::TimerEvent& event) override;

<%
if (compInfo['State Machine_list']) {
  compInfo['State Machine_list'].map(function(hfsm) {
-%>
  /**
   * @brief <%- hfsm.name %> Timer function
   * This timer has a dynamic period and executes the HFSM's tick()
   * function. It automatically handles consuming the HFSM's event
   * queue and updating its period based on the period of the
   * currently active leaf state.
   *
   * @param[in] event a timer event
   * @see startUp()
   */
  void <%- hfsm.sanitizedName %>_HFSM_timer_operation(const ros::TimerEvent& event);
<%
  });
}
-%>  

<%
if (compInfo.Timer_list) {
  compInfo.Timer_list.map(function(tmr) {
-%>
  /**
   * @brief <%- tmr.name %>_operation; <%- tmr['Brief Description'] %>
   *
   * This operation is executed every time the  
   * <%- tmr.name %> operation request is serviced 
   * @param[in] event a timer event
   *
   * <%- tmr['Detailed Description'] %>
   */
  void <%- tmr.name %>_operation(const ros::TimerEvent& event);
<%
    });
 }
-%>

<%
if (compInfo.Subscriber_list) {
  compInfo.Subscriber_list.map(function(sub) {
-%>
  /**
   * @brief <%- sub.name %>_operation; <%- sub['Brief Description'] %>
   *
   * This operation is executed every time the  
   * <%- sub.name %> operation request is serviced 
   * @param[in] ros::MessageEvent - event - Event information containing the message and headers received.
   *
   * <%- sub['Detailed Description'] %>
   */
      void <%- sub.name %>_operation(const ros::MessageEvent<<%- sub.Message.Package %>::<%- sub.Message.TypeName %> const>& event);
<%
    });
 }
-%>

<%
if (compInfo.Server_list) {
  compInfo.Server_list.map(function(srv) {
-%>
  /**
   * @brief <%- srv.name %>_operation; <%- srv['Brief Description'] %>
   *
   * This operation is executed every time the  
   * <%- srv.name %> operation request is serviced 
   * @param[in] req request received from the client
   * @param[out] res response sent back to the client
   *
   * <%- srv['Detailed Description'] %>
   */
  bool <%- srv.name %>_operation(const <%- srv.Service.Package %>::<%- srv.Service.TypeName %>::Request &req, <%- srv.Service.Package %>::<%- srv.Service.TypeName %>::Response &res);
<%
    });
 }
-%>

<%
if (compInfo['Action Server_list']) {
  compInfo['Action Server_list'].map(function(srv) {
-%>
  /**
   * @brief <%- srv.name %>_execute_cb; <%- srv['Brief Description'] %>
   *
   * This operation is executed every time the  
   * <%- srv.name %> operation request is serviced 
   * @param[in] goal goal received from the action client
   *
   * <%- srv['Detailed Description'] %>
   */
  void <%- srv.name %>_execute_cb(const <%- srv.Action.Package %>::<%- srv.Action.TypeName %>GoalConstPtr &goal);
  /**
   * @brief <%- srv.name %>_goal_cb;
   *
   * This operation is executed every time the  
   * <%- srv.name %> receives a new goal
   */
  void <%- srv.name %>_goal_cb();
  /**
   * @brief <%- srv.name %>_preempt_cb;
   *
   * This operation is executed every time the  
   * <%- srv.name %> is preempted
   */
  void <%- srv.name %>_preempt_cb();
<%
    });
 }
-%>

<%
if (compInfo['Action Client_list']) {
  compInfo['Action Client_list'].map(function(clt) {
-%>
  /**
   * @brief <%- clt.name %>_feedback_cb; <%- clt['Brief Description'] %>
   *
   * This operation is executed every time the  
   * <%- clt.name %> receives feedback from the action server
   * @param[in] feedback feedback received from the action server
   *
   * <%- clt['Detailed Description'] %>
   */
  void <%- clt.name %>_feedback_cb(const <%- clt.Action.Package %>::<%- clt.Action.TypeName %>FeedbackConstPtr &feedback);
  /**
   * @brief <%- clt.name %>_active_cb
   *
   * This operation is executed when the goal becomes active
   */
  void <%- clt.name %>_active_cb();
  /**
   * @brief <%- clt.name %>_done_cb
   *
   * This operation is executed when the goal completes.
   * @param[in] state state received from the action server
   * @param[in] result the result message received from the action server
   */
  void <%- clt.name %>_done_cb(const actionlib::SimpleClientGoalState& state, const <%- clt.Action.Package %>::<%- clt.Action.TypeName %>ResultConstPtr &result);
<%
    });
 }
-%>

private:

<%
if (compInfo['State Machine_list']) {
  compInfo['State Machine_list'].map(function(hfsm) {
-%>
  ros::Timer <%- hfsm.sanitizedName %>_HFSM_timer; /*!< <%- hfsm.name %> HFSM Timer */
<%
  });
}
-%>  

<%
if (compInfo.Timer_list) {
  compInfo.Timer_list.map(function(tmr) {
-%>
  ros::Timer <%- tmr.name %>;  /*!< <%- tmr.name %> Component Timer */
<%
    });
 }
-%>
<%
if (compInfo['Action Server_list']) {
  compInfo['Action Server_list'].map(function(srv) {
-%>
  actionlib::SimpleActionServer<<%- srv.Action.Package %>::<%- srv.Action.TypeName %>Action> <%- srv.name %>;  /*!< <%- srv.name %> Component Action Server */
<%
    });
 }
-%>
<%
if (compInfo['Action Client_list']) {
  compInfo['Action Client_list'].map(function(clt) {
-%>
  actionlib::SimpleActionClient<<%- clt.Action.Package %>::<%- clt.Action.TypeName %>Action> <%- clt.name %>;  /*!< <%- clt.name %> Component Action Client */
<%
    });
 }
-%>
<%
if (compInfo.Server_list) {
  compInfo.Server_list.map(function(srv) {
-%>
  ros::ServiceServer <%- srv.name %>;  /*!< <%- srv.name %> Component Server */
<%
    });
 }
-%>
<%
if (compInfo.Client_list) {
  compInfo.Client_list.map(function(clt) {
 -%>
  ros::ServiceClient <%- clt.name %>;  /*!< <%- clt.name %> Component Client */
<%
    });
 }
-%>
<%
if (compInfo.Publisher_list) {
  compInfo.Publisher_list.map(function(pub) {
 -%>
  ros::Publisher <%- pub.name %>;  /*!< <%- pub.name %> Component Publisher */
<%
    });
 }
-%>
<%
if (compInfo.Subscriber_list) {
  compInfo.Subscriber_list.map(function(sub) {
 -%>
  ros::Subscriber <%- sub.name %>;  /*!< <%- sub.name %> Component Subscriber */
<%
    });
 }
-%>

  /** 
   * User-defined private variables
   */
  //::::<%- compInfo.path %>::::Members::::
  <%- compInfo.Members %>
};

#endif // <%- compInfo.name.toUpperCase() %>_INCLUDE_GUARD

