/**
 * @file   AXCTaskFreeRTOS.hpp
 * @brief  AXCTaskFreeRTOSクラスヘッダ
 *
 * @par    Programming Language
 *         C++
 */

#ifndef AXCTASKFREERTOS_HPP_
#define AXCTASKFREERTOS_HPP_

#include "AXCTask.hpp"
#include "AXCConditionVariableFreeRTOS.hpp"
#include "task.h"

/**
 * @class AXCTaskFreeRTOS
 * @brief AXFTask に対し、プリミティブなスレッド機能を提供する
 *
 * @n     AXM層は AXCTaskFreeRTOS を使用せず、AXFActor を継承し、OS依存しないようにする。
 *
 */
class AXCTaskFreeRTOS : public AXCTask {
 public:
  /**
   * @brief AXCTaskFreeRTOSコンストラクタ
   */
  AXCTaskFreeRTOS(AXCConditionVariableFreeRTOS* cond = NULL, bool gtest = false);

  /**
   * @brief AXCTaskFreeRTOSデストラクタ
   */
  virtual ~AXCTaskFreeRTOS();

  /**
   * @brief 新しいタスクを生成する。
   * @param [in] name 生成するタスクの名前
   * @param [in] priority 生成するタスクの優先度
   * @param [in] stackSize 生成するタスクのスタックサイズ
   * @param [in] start_routine 生成するタスク関数ポインタ
   * @param [in] arg 生成するタスク関数へ渡す引数
   */
  taskStatus create(const std::string& name, taskPriority priority,
                    size_t stackSize, void *(*start_routine)(void *),
                    void *arg);

  /**
   * @brief タスクの終了を待つ。
   */
  taskStatus join();

  /**
   * @brief タスクにキャンセル要求する。
   */
  virtual taskStatus cancel();
  
  /**
   * @brief 自タスクを終了する。
   */
  void exitSelf();
 
private:
  /** 
   * @brief xTaskCreateによって生成されるタスク
   * @param [in] exinf xTaskCreate で指定するタスク拡張情報
   */
    static void SubFunc( void* exinf );

  /** 
   * @brief *start_routineを private な領域で保持
   */
    void* (*m_func)(void *); 

    void *m_param;
		xTaskHandle m_tskId;
    bool m_isCreated;
    AXCConditionVariableFreeRTOS *m_Cond;
    std::string m_Name;
    bool m_gtest;

  static const int taskMaxPriority = AXF_PRIORITY_HIGH_MAX;

  // インスタンスのコピーは想定しない(Klockwork指摘対応:CL.FFM.ASSIGN)
  AXCTaskFreeRTOS& operator=(const AXCTaskFreeRTOS&) {
    return *this;
  }

  // インスタンスのコピーは想定しない(Klockwork指摘対応:CL.FFM.COPY)
  AXCTaskFreeRTOS(const AXCTaskFreeRTOS& obj)
    : m_func(obj.m_func),
      m_param(obj.m_param),
      m_tskId(obj.m_tskId),
      m_isCreated(obj.m_isCreated),
      m_Cond(obj.m_Cond),
      m_Name(obj.m_Name),
      m_gtest(obj.m_gtest) {
  }
};

#endif /* AXCTASKFREERTOS_HPP_ */
