/*
 * AXMPixcessorIntState.cpp
 */

#include "../../AXMCommon/AXMCommonConfig.hpp"

#include "AXMPixcessorInt.hpp"
#include "../../AXMIsp/AXMIsp.hpp"
#include "../../../project/refkit/AXMIspConfig.hpp"
#include "AXMCommon/AXMCommonBridgeParam.hpp"
//#include "AXMIspAf/AXMIspAf.hpp"


#include "AXMIspTest/proc_def_cmos_eval.h"


extern ULONG  g_pixDriverInControl;
extern ULONG  g_pixDriverInError;

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

// STATUS_RUNNING状態の状態テーブル定義
//      {イベントID, メンバ関数ポインタ}
//      ...
//     {0,NULL}
const AXMPixcessorInt::StateTable AXMPixcessorInt::state_running[] = {
    { AXMPixcessorInt::PIXCESSORINT_EVENT_FAKE_ISR,
      (AXMPixcessorInt::StateFuncPtr) &AXMPixcessorInt::funcFrameIsr },
    { AXMPixcessorInt::PIXCESSORINT_EVENT_FAKE_ISR_START,
      (AXMPixcessorInt::StateFuncPtr) &AXMPixcessorInt::funcFrameIsrStart },
    { AXMPixcessorInt::PIXCESSORINT_EVENT_FAKE_ISR_STOP,
      (AXMPixcessorInt::StateFuncPtr) &AXMPixcessorInt::funcFrameIsrStop },
    { AXMPixcessorInt::PIXCESSORINT_EVENT_NOTIFY_ISR_DATA,
      (AXMPixcessorInt::StateFuncPtr) &AXMPixcessorInt::funcNotifyIsrData},
    { AXMPixcessorInt::PIXCESSORINT_EVENT_GET_AF_EVAL,
      (AXMPixcessorInt::StateFuncPtr) &AXMPixcessorInt::funcGetAfEval },
    {0,NULL}
};


ax::actorFuncStatus AXMPixcessorInt::funcFrameIsr(const void* pParam, int size) {
  // ISP へフレーム割り込みイベントを通知する

  // PCシミュレータでは、フレーム完了割り込みにタイマを使用するので、
  // ここでIRQハンドラを直接呼び出す。
  // 実機では、タイマを使用しないので、IRQハンドラをフレーム完了割り込み用の
  // CPUベクタ・テーブルに登録して呼び出すようにする。
  frameIsrHandler();

#ifdef USE_AXBRIDGE
  //フレーム生成完了通知(DSP->ARM)イベント
  frameGenHandler(EVENT_ISPTONVR_GDU_BANK_SWITCH, m_isrcount, 0);
#endif /* USE_AXBRIDGE */

  m_isrcount++;

  return ax::AXFACTOR_SUCCESS;
}

ax::actorFuncStatus AXMPixcessorInt::funcFrameIsrStart(const void* pParam,
                                                    int size) {
  m_log.write(AXFLOG_DEBUG, "PixcessorInt funcFrameIsrStart()");

  if (true == m_isUseTimer) {
    return ax::AXFACTOR_SUCCESS;
  }
  m_isUseTimer = true;

  m_isrcount = 0;

  // AXシミュレータ擬似フレーム完了割り込み通知用に、1000tick(約16ms)周期タイマーを設定する
  // 1000tick満了で、自アクタ に対し、PIXCESSOR_EVENT_FAKE_ISR を通知させる
  AXFActor::timeSpec timer;
  timer.sec = 0;
  timer.tick = 1000;

  if (AXFActor::TIMER_SUCCESS
      != startIntervalTimer(timer, PIXCESSORINT_EVENT_FAKE_ISR, &m_timerID)) {
    m_log.write(AXFLOG_ERR, "fail addIntervalTimer");
  }

  return ax::AXFACTOR_SUCCESS;
}

ax::actorFuncStatus AXMPixcessorInt::funcFrameIsrStop(const void* pParam,
                                                   int size) {
  m_log.write(AXFLOG_DEBUG, "PixcessorInt funcFrameIsrStop()");

  if (false == m_isUseTimer) {
    return ax::AXFACTOR_SUCCESS;
  }

  m_isUseTimer = false;
  // タイマーの停止
  if (AXFActor::TIMER_SUCCESS != stopIntervalTimer(m_timerID)) {
    m_log.write(AXFLOG_ERR, "fail stopTimer");
  }

  return ax::AXFACTOR_SUCCESS;
}

ax::actorFuncStatus AXMPixcessorInt::funcNotifyIsrData(const void* pParam,
                                                   int size) {
	ST_MSG *p_msg = (ST_MSG*)pParam;

    m_log.write(AXFLOG_DEBUG, "PixcessorInt funcFrameIsrData()");
    if(p_msg) {
    	if(p_msg->data) {
    		imageSensorParam = *(ImageSensorParam *)p_msg->data;
    	}
    }
  return ax::AXFACTOR_SUCCESS;
}

#if 1
ax::actorFuncStatus AXMPixcessorInt::funcGetAfEval(const void* pParam,
                                                   int size) {
	static ST_MSG msg;

    m_log.write(AXFLOG_DEBUG, "PixcessorInt funcGetAfEval()");
	msg.data = afEval;
//	//AFへ評価値送信
//#ifndef PARASOFT_CPPTEST
//	int stat = send(nameIspAf, AXMIspAf::EVENT_AF_EXEC, (void *)&msg, sizeof(msg));
//	if (0 > stat) {
//		m_log.write(AXFLOG_ERR, "fail send AF Eval Data");
//	}
//#endif

	return ax::AXFACTOR_SUCCESS;
}
#endif
