/*
 * AXMIspAfState.cpp
 */

#include "AXMIspAf.hpp"
#include "../AXMIsp/AXMIsp.hpp"
#include "../AXMIspAe/AXMIspAe.hpp"
#ifdef BB_TMP_PASS	/* 一旦コンパイルを通す用 */
#include "../AXMIspConfig.hpp"
#else
#include "../../project/refkit/AXMIspConfig.hpp"
#endif
#include "AXMCommon/AXMCommonStruct.hpp"
#include "AXMImageSensor/AXMImageSensor.hpp"

#ifdef USE_AXFTEST_COMMAND
#include "../AXMTest/AXMScenarioTest.hpp"
#endif /*USE_AXFTEST_COMMAND*/

// 3rdリリースから、「モデルイベント」と「デバイスイベント」の
// 登録が可能となる。
//
// 状態テーブルは、状態ごとに定義し、イベントIDとメンバ関数の紐付けを行う。
// ※状態テーブルの最後は、必ず{0,NULL}で終了する必要がある。

// STATE_SAMPLE_DATA状態の状態テーブル定義
//      {イベントID, メンバ関数ポインタ}
//      ...
//     {0,NULL}
const AXMIspAf::StateTable AXMIspAf::state_waiting[] = {
    { AXMIspAf::EVENT_SPEC_ADDR,
      (AXMIspAf::StateFuncPtr) &AXMIspAf::funcSpecAddr },   //  設定値保存先アドレス通知
    {0,NULL}
};

const AXMIspAf::StateTable AXMIspAf::state_running[] = {
    { AXMIspAf::EVENT_AF_EXEC,
      (AXMIspAf::StateFuncPtr) &AXMIspAf::funcAfExec },
#ifdef USE_AXFTEST_COMMAND
    { AXMIspAf::EVENT_SAMPLE_DATA,
      (AXMIspAf::StateFuncPtr) &AXMIspAf::funcSampleData },
    { AXMIspAf::EVENT_PRIORITY_TEST,
      (AXMIspAf::StateFuncPtr) &AXMIspAf::funcPriorityTest },
    { AXMIspAf::EVENT_AXTORCOMM_TEST,
      (AXMIspAf::StateFuncPtr) &AXMIspAf::funcActorCommTest },
#endif /*USE_AXFTEST_COMMAND*/
    {0,NULL}
};

ax::actorFuncStatus AXMIspAf::funcAfExec(const void *pParam, int size) {
  m_log.write(AXFLOG_DEBUG, "funcAfExec()");
	ST_MSG *p_msg = (ST_MSG *)pParam;
	if(base && p_msg) {
		base->notifyAfEval((long *)p_msg->data);
		base->setAfSpec();

		base->AfExec();
		
		static ST_MSG sndMsg;
		sndMsg.data = &base->controlAF;
		int stat = send(nameImageSensor, AXFEVENT_MODEL(AXMImageSensor::ISP_EVENT_FOCUSCONTROL), (void *)&sndMsg, sizeof(ST_MSG));
		if (0 > stat) {
			m_log.write(AXFLOG_ERR, "fail send AE Sample Data");
		}
	}
	return ax::AXFACTOR_SUCCESS;
}

#ifdef USE_AXFTEST_COMMAND
ax::actorFuncStatus AXMIspAf::funcSampleData(const void *pParam, int size) {
  m_log.write(AXFLOG_DEBUG, "funcSampleData()");
  ST_MSG *rcvMsg;
  rcvMsg = (ST_MSG *)pParam;
  std::string buf("AF funcSampleData() receive data=");
  std::string rcvstr((char *)rcvMsg->data);
  buf += rcvstr;
  m_log.write(AXFLOG_DEBUG, buf);
#ifdef USE_AXFTEST_COMMAND_COMPLOG
  if(0 != rcvstr.compare(afSampleData)){
    AXMScenarioTest::getInstance()->writeLog(&m_log, AXMScenarioTest::RESULT_FAILED, AXMScenarioTest::E_RECVFAILED);
    return ax::AXFACTOR_SUCCESS;
  }
#endif /* USE_AXFTEST_COMMAND_COMPLOG */

  if (m_count > AXM_SAMPLE_SEND_MAX_COUNT) {
    m_count = 0;
    return ax::AXFACTOR_SUCCESS;
  }
  m_count++;

#ifdef USE_AXFTEST_COMMAND_COMPLOG
  if(m_count % 10 == 0){
    std::ostringstream cntStr;
    cntStr << m_count;
    m_log.write(AXFLOG_SCENARIO, "actorComm count=" + cntStr.str());
  }
#endif /* USE_AXFTEST_COMMAND_COMPLOG */


  // AE宛てに、サンプルデータを送信する
  ST_MSG sndMsg;
  sndMsg.cmd  = m_count;
  sndMsg.data = (void *)aeSampleData.c_str();
  int stat = send(nameIspAe, AXMIspAe::EVENT_SAMPLE_DATA, (void *)&sndMsg, sizeof(ST_MSG));
  if (0 > stat) {
    m_log.write(AXFLOG_ERR, "fail send AE Sample Data");
  }

  return ax::AXFACTOR_SUCCESS;
}

ax::actorFuncStatus AXMIspAf::funcPriorityTest(const void *pParam, int size) {
  m_log.write(AXFLOG_SCENARIO, "AF PriorityTest");
#ifndef PARASOFT_CPPTEST
  pthread_pri_dbgprint();
#endif  //  PARASOFT_CPPTEST

  //受信データからカウンタ値を取得
  int count = 0;
  if(pParam != NULL){
    count = *((int*)pParam);
  }

  //Ispへ結果送信
  int stat = send(nameIsp, AXMIsp::EVENT_PRISCHED_END, (void *)&count, sizeof(count));
  if (0 > stat) {
    m_log.write(AXFLOG_ERR, "fail send Isp AF Prisched End");
  }
  return ax::AXFACTOR_SUCCESS;
}

ax::actorFuncStatus AXMIspAf::funcActorCommTest(const void *pParam, int size) {
  m_log.write(AXFLOG_SCENARIO, "AF ActorCommTest");

  if (AXM_SAMPLE_SEND_MAX_COUNT) {
#ifdef USE_AXFTEST_COMMAND_COMPLOG
    //テスト開始を設定
    AXMScenarioTest::getInstance()->setTestCase(AXMScenarioTest::TEST_ACTORCOMM);
#endif /* USE_AXFTEST_COMMAND_COMPLOG */
    m_count = 0;
    // AE宛てに、サンプルデータを送信する
    ST_MSG sndMsg;
    sndMsg.cmd  = m_count;
    sndMsg.data = (void *)aeSampleData.c_str();
    int stat;
    stat = send(nameIspAe, AXMIspAe::EVENT_SAMPLE_DATA,
                (void *) &sndMsg, sizeof(ST_MSG));
    if (0 > stat) {
      m_log.write(AXFLOG_ERR, "fail send AF Sample Data");
    }
  }
  return ax::AXFACTOR_SUCCESS;
}
#endif /*USE_AXFTEST_COMMAND*/

ax::actorFuncStatus AXMIspAf::funcSpecAddr(const void *pParam, int size) {
  if((0 < size) && (pParam != 0x00000000ul)) {
    ST_MSG *msg = (ST_MSG *)pParam;
	if(base) {

		base->initAfSpec((ST_SPEC *)msg->data);

		base->setAfSpec();

    	state = STATE_RUNNING;
#ifndef PARASOFT_CPPTEST
	    setNextState(state);
#endif  //  PARASOFT_CPPTEST
	}
  }

  return ax::AXFACTOR_SUCCESS;
}

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

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

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

#endif	// PARASOFT_CPPTEST

