/*
 * AXMIsp.cpp
 */

#include "AXMCommon/AXMCommonParam.hpp"
#include "AXMCommon/AXMCommonConfig.hpp"
#include "AXMIsp.hpp"
#include "AXFStage.hpp"
#include <sstream>
#include <string>
#ifndef BB_TMP_PASS	/* 一旦コンパイルを通す用 */
#include "../../project/refkit/AXMIspConfig.hpp"
#endif
#include "AXMIspAwb/AXMIspAwbTypedefine.hpp"
#include "AXMIspAwb/AXMIspAwbOPDConfig.hpp"

#ifdef PTHREAD_PRI_DEBUG
#include <pthread.h>
#include <stdio.h>
#include <limits.h>
#include <unistd.h>
#endif /* PTHREAD_PRI_DEBUG */

#ifdef USE_AXFTEST_COMMAND
//const int AXM_SAMPLE_SEND_MAX_COUNT = 0;
const int AXM_SAMPLE_SEND_MAX_COUNT = 100;
//const bool isUsedTimer = false;
const bool isUsedTimer = true;
//const bool isUsedPriorityCheck = false;
const bool isUsedPriorityCheck = true;
#endif /* USE_AXFTEST_COMMAND */

AXMIsp::AXMIsp(AXFObjectName& name)
    : AXModelActor(name),
      m_log(name),
      m_name(name),
      m_count(0) {
  m_log.write(AXFLOG_DEBUG, "ISP Constractor");

  ispAWBMode = 0;                       //  AWBモード(ATWモード)
  ispATWSceaneMode = 0;                 //  ATWシーンモード(屋内モード)
  ispMode = 0;                          //  動作モード(通常モード)

  p_spec = 0x00000000ul;

  state = STATE_0;
  status = Status_Waiting;

#ifdef USE_AXFTEST_COMMAND
  m_prischecSuccess = 0; // 試験成功数
  m_prischecCount = 0;   // 試験総数
#endif  //  USE_AXFTEST_COMMAND

  isWdrMode = AXM_wdrMode_Init;
  isLinearMode = AXM_linearMode_Init;
#if defined(AXM_ISP_CT_AWB) || defined(AXM_ISP_CT_AE)
  isWdrMode = false;
#endif
  ispCorrect.Mode = CorrectMode_OFF;
  ispCorrect.AEMode = E_AeNone;
  ispCorrect.AESlowShutterMode = AXH_AE_SlowShutter_ON;
  ispCorrect.IRIS.Mode = 0;
  ispCorrect.IRIS.adjVal = 0x00;
  ispCorrect.frameCnt = 0;
  Luminance = AWB_Bright_Init;
  f_init = false;
  ispLensKind = 0;

#ifdef  PARASOFT_CPPTEST
  //  c++testパスケース確認用変数 初期化
  event = 0;
  msg.cmd = 0;
  msg.data = 0;
  msg.rid = 0;
  msg.sid = 0;
#endif  //  PARASOFT_CPPTEST
#ifdef PARASOFT_CPPTEST
  return_stub_send = 0;
  return_stub_setStateInfo = 0;
#endif	// PARASOFT_CPPTEST

}

AXMIsp::~AXMIsp() {
  m_log.write(AXFLOG_DEBUG, "ISP Destractor");
}

ax::actorFuncStatus AXMIsp::onCreate() {
  m_log.write(AXFLOG_DEBUG, "ISP onCreate()");

  // StateMachine に必要な情報を登録する
  //      自オブジェクト,
  //      初期状態,
  //      状態の最大数
  if (0 > setStateInfo(this, STATE_0, STATE_MAX)) {
//#ifndef PARASOFT_CPPTEST
    m_log.write(AXFLOG_ERR, "fail registHandle");
    return ax::AXFACTOR_ERROR;
//#endif  //  APRASOFT_CPPTEST
  }

  // STATE_0状態の状態テーブルを登録する
  //      状態テーブルで登録する状態,
  //      状態テーブルのポインタ,
  setStateTable(STATE_0, state_0);
  setStateTable(STATE_FRAME_1ST, state_1);                  //  通常モード : 1フレーム目
  setStateTable(STATE_FRAME_2ND, state_2);                  //  通常モード : 2フレーム目
  setStateTable(STATE_FRAME_3RD, state_3);                  //  通常モード : 3フレーム目
  setStateTable(STATE_FRAME_4TH, state_4);                  //  通常モード : 4フレーム目
  setStateTable(STATE_FRAME_5TH, state_5);                  //  通常モード : 5フレーム目
  setStateTable(STATE_FRAME_6TH, state_6);                  //  通常モード : 6フレーム目
  setStateTable(STATE_FRAME_7TH, state_7);                  //  通常モード : 7フレーム目
  setStateTable(STATE_FRAME_8TH, state_8);                  //  通常モード : 8フレーム目
  setStateTable(STATE_FRAME_9TH, state_9);                  //  通常モード : 9フレーム目
  setStateTable(STATE_FRAME_10TH, state_10);                //  通常モード : 10フレーム目
  setStateTable(STATE_ADJUST_WB   , state_1000);            //  調整モード : WB調整
  setStateTable(STATE_ADJUST_IRIS , state_1100);            //  調整モード : IRIS調整
  setStateTable(STATE_ADJUST_SHADE, state_1200);            //  調整モード : シェーディング補正
  setStateTable(STATE_ADJUST_KIZU , state_1300);            //  調整モード : キズ補正

  // STATE_100状態の状態テーブルを登録する
  //      状態テーブルで登録する状態,
  //      状態テーブルのポインタ,
  //setStateTable(STATE_100, state_100);

  return ax::AXFACTOR_SUCCESS;
}

  ax::actorFuncStatus AXMIsp::onStart() {
  m_log.write(AXFLOG_DEBUG, "ISP onStart()");

#ifndef PARASOFT_CPPTEST
#if 0
  // AF へ開始要求を行う
  if (0 > send(nameIspAf, AXFEVENT_LIFECYCLE_START, NULL, 0)) {
    m_log.write(AXFLOG_ERR, "fail send AF START");
  }

  // AE へ開始要求を行う
  if (0 > send(nameIspAe, AXFEVENT_LIFECYCLE_START, NULL, 0)) {
    m_log.write(AXFLOG_ERR, "fail send AE START");
  }

  // AWB へ開始要求を行う
  if (0 > send(nameIspAwb, AXFEVENT_LIFECYCLE_START, NULL, 0)) {
    m_log.write(AXFLOG_ERR, "fail send AWB START");
  }

  // PixcessorInt へ開始要求を行う
  if (0 > send(namePixessorInt, AXFEVENT_LIFECYCLE_START, NULL, 0)) {
    m_log.write(AXFLOG_ERR, "fail send PixcessorInt START");
  }
#endif
#endif  //  PARASOFT_CPPTEST

  return ax::AXFACTOR_SUCCESS;
}

ax::actorFuncStatus AXMIsp::onStop() {
  m_log.write(AXFLOG_DEBUG, "ISP onStop()");

#ifndef PARASOFT_CPPTEST
#if 0
  // 1. AWB終了要求
  //    1.1. AWB へ停止要求を行う
  if (0 > send(nameIspAwb, AXFEVENT_LIFECYCLE_STOP, NULL, 0)) {
    m_log.write(AXFLOG_ERR, "fail send AWB STOP");
  }

  //    1.1. AWB へ終了要求を行う
  if (0 > send(nameIspAwb, AXFEVENT_LIFECYCLE_EXIT, NULL, 0)) {
    m_log.write(AXFLOG_ERR, "fail send AWB EXIT");
  }

  //    1. 1. AWB の終了待ち
  AXFActor *awbObjRef;
  AXFStage::getInstance()->getActorInfo(nameIspAwb, &awbObjRef);
  awbObjRef->join();

  // 2. AE終了要求
  //    2.1. AE へ停止要求を行う
  if (0 > send(nameIspAe, AXFEVENT_LIFECYCLE_STOP, NULL, 0)) {
    m_log.write(AXFLOG_ERR, "fail send AE STOP");
  }

  //    2.2. AE へ終了要求を行う
  if (0 > send(nameIspAe, AXFEVENT_LIFECYCLE_EXIT, NULL, 0)) {
    m_log.write(AXFLOG_ERR, "fail send AE EXIT");
  }

  //    2.2. AE の終了待ち
  AXFActor *aeObjRef;
  AXFStage::getInstance()->getActorInfo(nameIspAe, &aeObjRef);
  aeObjRef->join();

  // 3. AF終了要求
  //    3.1. AF へ停止要求を行う
  if (0 > send(nameIspAf, AXFEVENT_LIFECYCLE_STOP, NULL, 0)) {
    m_log.write(AXFLOG_ERR, "fail send AF STOP");
  }

  //    3.2. AF へ終了要求を行う
  if (0 > send(nameIspAf, AXFEVENT_LIFECYCLE_EXIT, NULL, 0)) {
    m_log.write(AXFLOG_ERR, "fail send AF EXIT");
  }

  //    3.3. AF の終了待ち
  AXFActor *afObjRef;
  AXFStage::getInstance()->getActorInfo(nameIspAf, &afObjRef);
  afObjRef->join();

  // 5. PixcessorInt終了要求
  //    5.1. PixcessorInt へ停止要求を行う
  if (0 > send(namePixessorInt, AXFEVENT_LIFECYCLE_STOP, NULL, 0)) {
    m_log.write(AXFLOG_ERR, "fail send PixcessorInt STOP");
  }

  //    5.2. PixcessorInt へ終了要求を行う
  if (0 > send(namePixessorInt, AXFEVENT_LIFECYCLE_EXIT, NULL, 0)) {
    m_log.write(AXFLOG_ERR, "fail send PixcessorInt EXIT");
  }

  //    5.3. PixcessorInt の終了待ち
  AXFActor *intObjRef;
  AXFStage::getInstance()->getActorInfo(namePixessorInt, &intObjRef);
  intObjRef->join();
#endif
#endif  //  PARASOFT_CPPTEST

  return ax::AXFACTOR_SUCCESS;
}

#if 0
ax::actorFuncStatus AXMIsp::onPause() {
  m_log.write(AXFLOG_DEBUG, "ISP onPause()");
  return ax::AXFACTOR_SUCCESS;
}

ax::actorFuncStatus AXMIsp::onResume() {
  m_log.write(AXFLOG_DEBUG, "ISP onResume()");
  return ax::AXFACTOR_SUCCESS;
}

ax::actorFuncStatus AXMIsp::onRestart() {
  m_log.write(AXFLOG_DEBUG, "ISP onRestart()");
  return ax::AXFACTOR_SUCCESS;
}
#endif

#ifndef PARASOFT_CPPTEST
void pthread_pri_dbgprint() {
#ifdef PTHREAD_PRI_DEBUG
  pthread_attr_t attr;
  struct sched_param param;
  size_t stack_size = 0;
  size_t guard_size = 0;
  int thread_policy = 0;

  pthread_attr_init(&attr);

  pthread_attr_getschedpolicy(&attr, &thread_policy);
  printf("@@@ now policy:[%d] FIFO(%d):RR(%d):OTHER(%d)\n", thread_policy,
      SCHED_FIFO, SCHED_RR, SCHED_OTHER);

  pthread_attr_getschedparam(&attr, &param);
  printf("@@@ now priority:[%d]\n", param.sched_priority);
#ifdef NEVER
  printf("@@@ sched_get_priority_min( SCHED_FIFO ):[%d]\n",
      sched_get_priority_min(SCHED_FIFO));
  printf("@@@ sched_get_priority_max( SCHED_FIFO ):[%d]\n",
      sched_get_priority_max(SCHED_FIFO));
  printf("@@@ sched_get_priority_min( SCHED_RR )  :[%d]\n",
      sched_get_priority_min(SCHED_RR));
  printf("@@@ sched_get_priority_max( SCHED_RR )  :[%d]\n",
      sched_get_priority_max(SCHED_RR));
#endif /* NEVER */

  pthread_attr_getstacksize(&attr, &stack_size);
  pthread_attr_getguardsize(&attr, &guard_size);
  printf("@@@ stack size %zd[%zdM]; guard size %zd "
      "minimum is %u[%uK]\n",
      stack_size, stack_size >> 20, guard_size, PTHREAD_STACK_MIN,
      PTHREAD_STACK_MIN >> 10);
  pthread_attr_destroy(&attr);
  printf("\n");
#endif /* PTHREAD_PRI_DEBUG */
}
#endif  //  PARASOFT_CPPTEST
/**
 *      C++testスタブ
 *
 *
 */

#ifdef PARASOFT_CPPTEST
// C++test sendスタブ
int AXMIsp::send(AXFObjectName& name, AXFEvent_t eventId, void* data, int size)
{
	return return_stub_send;
}

// C++test setStateInfoスタブ
int AXMIsp::setStateInfo(AXFActor* obj, int initState, int maxState)
{
	return return_stub_setStateInfo;
}

void AXMIsp::setStateTable(int registState, const StateTable* stateTable)
{
	return;
}

#endif	// PARASOFT_CPPTEST

