/*******************************************************************************
*	ファイル名：DataCollectDoc.cpp
*	用　　　途：ドキュメントクラス実装
*	備　　　考：
*	履　　　歴：
********************************************************************************/

/****************************
*	インクルードファイル	*
****************************/
#include "stdafx.h"
#include "DataCollect.h"
#include "DataCollectDoc.h"
/****************************
*		 定数　定義			*
****************************/
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//***** ガード条件
#define GUARD_RETURN( expr, ret )		{ if( !(expr) )	return (ret) ;		}
#define GUARD_RETURN_VOID( expr )		{ if( !(expr) )	return ;			}
#define GUARD_RETURN_FALSE( expr )		{ if( !(expr) )	return FALSE ;		}
#define GUARD_RETURN_NULL( expr, T )	{ if( !(expr) )	return (T *)NULL ;	}

/****************************
*		 クラス実装			*
****************************/

/*******************************************************************************
*	ク ラ ス名：CDataCollectDoc
*	用　　　途：ドキュメントクラス
*	備　　　考：
********************************************************************************/
//***** 動的生成のサポート
IMPLEMENT_DYNCREATE( CDataCollectDoc, CDocument )

//***** メッセージマップ
BEGIN_MESSAGE_MAP( CDataCollectDoc, CDocument )
END_MESSAGE_MAP()


/*******************************************************************************
*	関　数　名：CDataCollectDoc
*	用　　　途：コンストラクション
*	引　き　数：
*	戻　り　値：
*	備　　　考：
********************************************************************************/
CDataCollectDoc::CDataCollectDoc()
	: CDocument()
{
	// TODO: この位置に 1 度だけ呼ばれる構築用のコードを追加してください。
	m_bInitialize	= FALSE ;
}


/*******************************************************************************
*	関　数　名：
*	用　　　途：デストラクション
*	引　き　数：
*	戻　り　値：
*	備　　　考：
********************************************************************************/
CDataCollectDoc::~CDataCollectDoc()
{
	// 終了ログ
	CDailyLogManagerS::GetInstance().PrintLog( LOG_SYSTEM, _T("%s 終了 Ver %s"), APPTITLE, APPVERSION );
}


/*******************************************************************************
*	関　数　名：Serialize
*	用　　　途：ドキュメントデータのシリアライズ(直列入出力)
*	引　き　数：ストリームオブジェクト
*	戻　り　値：
*	備　　　考：使用しない
********************************************************************************/
void CDataCollectDoc::Serialize( CArchive& ar )
{
	if( ar.IsStoring() ){
		// TODO: 格納するコードをここに追加してください。
	}
	else {
		// TODO: 読み込むコードをここに追加してください。
	}
}

#ifdef _DEBUG

/****************************
*		 診断コード			*
****************************/

/*******************************************************************************
*	関　数　名：AssertValid
*	用　　　途：オブジェクトの正当性評価
*	引　き　数：
*	戻　り　値：
*	備　　　考：
********************************************************************************/
void CDataCollectDoc::AssertValid() const
{
	CDocument::AssertValid() ;
}


/*******************************************************************************
*	関　数　名：Dump
*	用　　　途：オブジェクトのデバッグダンプ
*	引　き　数：ダンプコンテキスト
*	戻　り　値：
*	備　　　考：
********************************************************************************/
void CDataCollectDoc::Dump( CDumpContext& dc ) const
{
	CDocument::Dump( dc ) ;
}


#endif //_DEBUG

/*******************************************************************************
*	関　数　名：OnNewDocument
*	用　　　途：新規ドキュメント生成
*	引　き　数：
*	戻　り　値：
*	備　　　考：SDIの場合は、１度しか呼ばれない
********************************************************************************/
BOOL CDataCollectDoc::OnNewDocument()
{
	if( !CDocument::OnNewDocument() ){
		return FALSE ;
	}

	// TODO: この位置に再初期化処理を追加してください。
	// (SDI ドキュメントはこのドキュメントを再利用します。)

	// 起動ログ
	CDailyLogManagerS::GetInstance().PrintLog( LOG_SYSTEM, _T("%s 起動 Ver %s"), APPTITLE, APPVERSION );

	return TRUE ;
}


/*******************************************************************************
*	関　数　名：GetFirstView
*	用　　　途：ビューリスト先頭のビューを取得する
*	引　き　数：
*	戻　り　値：
*	備　　　考：
********************************************************************************/
CView* CDataCollectDoc::GetFirstView() const
{
	POSITION	pos ;					// リストポジション
	CView*		pFirstView ;			// リスト先頭のビュー

	//***** 先頭のビューを取得
	pos			= CDocument::GetFirstViewPosition() ;
	pFirstView	= CDocument::GetNextView( pos ) ;

	return pFirstView ;
}

/*******************************************************************************
*	関　数　名：InitialUpdateView
*	用　　　途：ビューの初回更新を通知する
*	引　き　数：ビューへのポインタ
*	戻　り　値：
*	備　　　考：
********************************************************************************/
void CDataCollectDoc::InitialUpdateView( CView* pView /* 対象ビュー */ )
{
	CView*		pFirstView ;			// リスト先頭のビュー

	//***** 先頭ビューの取得
	pFirstView	= GetFirstView() ;
	ASSERT( pFirstView != NULL ) ;

	//***** 先頭ビューの場合は、初回ドキュメント更新を行う
	if ( pFirstView == pView ) { 
		OnInitDocument() ;
	}
}

/*******************************************************************************
*	関　数　名：OnInitDocument
*	用　　　途：ドキュメントの初期化処理
*	引　き　数：
*	戻　り　値：
*	備　　　考：メインフレーム・ドキュメント・ビューがすべて生成済み
*				の状態であるビューのOnInitialUpdate()より呼び出される
********************************************************************************/
void CDataCollectDoc::OnInitDocument()
{
	INT32	nError ;
	WORD	wError = 0x0000 ;
	BOOL	bRet ;

	// パラメータ管理クラス初期化(パラメータ読込も行う)
	nError = CParameterManager::GetInstance().InitParam() ;
	switch( nError ){
		case PARAM_INIT_ERR_LOAD_INIT	: wError |= INIT_ERROR_PARAM_LOAD_INIT		; goto INIT_END ;
	}

	// データ格納キューの初期化
	bRet  = TRUE ;
	bRet &= m_MiningQueue		 .SetDataSize( sizeof( MINING_DATA		), MINING_QUEUE_SIZE		) ;
	bRet &= m_SETTING1Queue		 .SetDataSize( sizeof( SETTING1_DATA		), SETTING1_QUEUE_SIZE		) ;
	bRet &= m_SETTING2Queue		 .SetDataSize( sizeof( SETTING2_DATA		), SETTING2_QUEUE_SIZE		) ;
	bRet &= m_SETTING3Queue		 .SetDataSize( sizeof( SETTING3_DATA	), SETTING3_QUEUE_SIZE	) ;
	bRet &= m_SETTING4Queue		 .SetDataSize( sizeof( SETTING4_DATA	), SETTING4_QUEUE_SIZE	) ;
	bRet &= m_ProductsInfoQueue	 .SetDataSize( sizeof( PRODUCTSINFO_DATA), PRODUCTSINFO_QUEUE_SIZE);
	if( !bRet ){
		wError = INIT_ERROR_QUEUE ;
		goto INIT_END ;
	}

	// データ収集クラス初期化
	bRet  = TRUE ;
	bRet &= CCollectMining			::GetInstance().Initialize( &m_MiningQueue ) ;
	bRet &= CCollectSETTING1		::GetInstance().Initialize( &m_SETTING1Queue ) ;
	bRet &= CCollectSETTING2		::GetInstance().Initialize( &m_SETTING2Queue ) ;
	bRet &= CCollectSETTING3		::GetInstance().Initialize( &m_SETTING3Queue ) ;
	bRet &= CCollectSETTING4		::GetInstance().Initialize( &m_SETTING4Queue ) ;
	bRet &= CCollectProductInfo		::GetInstance().Initialize(	&m_ProductsInfoQueue);
	if( !bRet ){
		wError = INIT_ERROR_COLLECT ;
		goto INIT_END ;
	}

	// データ格納クラス初期化
	bRet = CDataToDB::GetInstance().Initialize( 
												&m_MiningQueue			,
												&m_SETTING1Queue			,
												&m_SETTING2Queue			,
												&m_SETTING3Queue	,
												&m_SETTING4Queue,
												&m_ProductsInfoQueue
											  ) ;
	if( !bRet ){
		wError = INIT_ERROR_DATA_TO_DB ;
		goto INIT_END ;
	}

INIT_END:

	m_bInitialize = ( wError == 0x0000 ) ? TRUE : FALSE ;
	SetInitError( wError ) ;

	if( !m_bInitialize ){
		CDailyLogManagerS::GetInstance().PrintLog( LOG_SYSTEM, _T("初期化異常のため終了") ) ;
	}

	ASSERT( m_bInitialize ) ;
}

/*******************************************************************************
*	関　数　名：SetInitError
*	用　　　途：初期化エラー
*	引　き　数：
*	戻　り　値：
*	備　　　考：
********************************************************************************/
void CDataCollectDoc::SetInitError( WORD wError )
{
	if( wError & INIT_ERROR_PARAM_LOAD_INIT ) {
		CDailyLogManagerS::GetInstance().PrintLog( LOG_ERROR, _T("初期化パラメータ設定異常") ) ;
	}

	if( wError & INIT_ERROR_QUEUE ) {
		CDailyLogManagerS::GetInstance().PrintLog( LOG_ERROR, _T("データ格納キューメモリ確保失敗") ) ;
	}

	if( wError & INIT_ERROR_COLLECT ) {
		CDailyLogManagerS::GetInstance().PrintLog( LOG_ERROR, _T("データ収集初期化失敗") ) ;
	}

	if( wError & INIT_ERROR_DATA_TO_DB ) {
		CDailyLogManagerS::GetInstance().PrintLog( LOG_ERROR, _T("データ格納初期化失敗") ) ;
	}
}

/*******************************************************************************
*	関　数　名：OnTermDocument
*	用　　　途：ドキュメントの終了処理を行う
*	引　き　数：
*	戻　り　値：
*	備　　　考：スレッドの終了等に使用
********************************************************************************/
void CDataCollectDoc::OnTermDocument()
{
	// スレッド終了
	CCollectMining			::GetInstance().End() ;
	CCollectSETTING1		::GetInstance().End() ;
	CCollectSETTING2		::GetInstance().End() ;
	CCollectSETTING3		::GetInstance().End() ;
	CCollectSETTING4		::GetInstance().End() ;
	CCollectProductInfo		::GetInstance().End();
	CDataToDB				::GetInstance().End() ;

	// キューの解放
	m_MiningQueue			.RemoveAll() ;
	m_SETTING1Queue			.RemoveAll() ;
	m_SETTING2Queue			.RemoveAll() ;
	m_SETTING3Queue			.RemoveAll() ;
	m_SETTING4Queue			.RemoveAll() ;
	m_ProductsInfoQueue		.RemoveAll();
}

/*******************************************************************************
*	関　数　名：OnCloseDocument
*	用　　　途：ドキュメントを閉じる
*	引　き　数：
*	戻　り　値：
*	備　　　考：※Viewの終了後にドキュメントの終了処理を行う必要があるため
*				　ここでは終了処理は行わない
********************************************************************************/
void CDataCollectDoc::OnCloseDocument()
{
	CDocument::OnCloseDocument() ;
}


/*******************************************************************************
*	関　数　名：UpdateDocument
*	用　　　途：ドキュメントの更新
*	引　き　数：送信元、通知コード
*	戻　り　値：成功(TRUE) / 失敗(FALSE)
*	備　　　考：
********************************************************************************/
void CDataCollectDoc::UpdateDocument( CObject* pSender, LPARAM lNotifCode )
{
	//switch( lNotifCode ){
		//case NTCD_UPDATE_PARAM :		// パラメータ更新
		//case NTCD_CHANGE_KIND  :		// 品種切替
		//{
		//	break ;
		//}

	//	default	:
	//		break ;
	//}

	UpdateAllViews( NULL, lNotifCode, pSender ) ;
}

/*******************************************************************************
*	関　数　名：PreTermDocument
*	用　　　途：終了前準備
*	引　き　数：
*	戻　り　値：
*	備　　　考：
********************************************************************************/
void CDataCollectDoc::PreTermDocument()
{
}
