/*
このファイルの中身は、NTT オープンソースライセンス　バージョン 1.0（「本
契約」という）の適用を受けます。
本契約を遵守しない限り、このファイルを使用してはなりません。
本契約のコピーは、次のＵＲＬから入手できます。
【配布サイトのURL】 http://www.oss.ecl.ntt.co.jp/lms/

本契約に基づき頒布されるソフトウェアは、現状のまま、明示又は黙示のあらゆ
る種類の保証なしで、頒布されます。本契約に基づく権利及び制限を律する特定
の文言については、本契約を参照してください。

「オリジナルコード」は、 NTT Cyber Space Laboratories Code です。 
「オリジナルコード」の「初期開発者」は、日本電信電話株式会社です。  
日本電信電話株式会社により創作された部分は、Copyright (C) 2004 
日本電信電話株式会社 です。
全ての権利が留保されます。 
「コントリビュータ」：_____________________________________ 


The contents of this file are subject to the NTT Opensource License
Version 1.0 (the License); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
【配布サイトのURL】 http://www.oss.ecl.ntt.co.jp/lms/

Software distributed under the License is distributed on an AS IS
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.

The Original Code is NTT Cyber Space Laboratories Code .

The Initial Developer of the Original Code is NIPPON TELEGRAPH AND 
TELEPHONE CORPORATION.
Portions created by the NIPPON TELEGRAPH AND TELEPHONE CORPORATION 
are Copyright (C) 2004 NIPPON TELEGRAPH AND TELEPHONE CORPORATION. 
All Rights Reserved.

Contributor(s) ______________________________________.
*/

//
//	Perceptionログ操作クラス
//			変更履歴
// 				2004.01.08 新規作成		suzuki
//

package jp.co.ntt.lms.lo.Perception;


// Java API
import java.util.*;
import java.text.*;
import java.net.URL;
import java.io.IOException;
import java.sql.SQLException;

// xml API
import org.xml.sax.SAXException;

// XMS API
import jp.co.ntt.lms.xmo.util.*;
import jp.co.ntt.lms.xmo.*;
import jp.co.ntt.lms.lo.*;
import jp.co.ntt.lms.Common.status.*;
import jp.co.ntt.lms.xmo.Lo.LoClient;


/**
 * Perceptionログ操作クラス
 *
 * <PRE>
 *   Perceptionログレコードリストを取得。
 *   上位にログ操作インタフェースクラスを持つ。
 * </PRE>
 *
 */
public class PerceptionLoLogControl
	implements PerceptionPropertyDef
{

	/** 学習開始時間を保持します */
	private Date mobjStartDate = null;

	private String mstrUserID = null;
	private String mstrLoID = null;
	private String mstrSessionID = null;

	/**
	 * コンストラクタです。
	 * @param strUserID ユーザID
	 * @param strLoID LOID
	 * @param strSessionID セッションID
	 */
	public PerceptionLoLogControl( String strUserID, String strLoID, String strSessionID ) {
		mstrUserID = strUserID;
		mstrLoID = strLoID;
		mstrSessionID = strSessionID;
	}

	/**
	 * Aiccログを解析して、Aiccの各テーブルに登録処理を行います。
	 *
	 * 処理内容：ステータスログクラスに
	 *           データを設定する。
	 * @param strAiccLogXml AiccLog
	 * @exception LOException Lo固有の例外エラー
	 */
	public void insertLog( Hashtable htbParam, DataAccess objDataAccess )
		throws LOException
	{
		try {
			// 共通ログデータを取得します
			String strUserID = (String)htbParam.get( USER_ID );						// UserID
			String strAssessmentID = (String)htbParam.get( TEST_ID );				// アセスメントID
			String strTestMax = (String)htbParam.get( TEST_MAX );					// 最大点
			String strLessonTime = (String)htbParam.get( LESSON_TIME );				// 試験終了時刻
			String strLessonDate = (String)htbParam.get( LESSON_DATE );				// 試験年月日
			String strLessonScoreband = (String)htbParam.get( LESSON_SCOREBAND );	// AssessmentOutcom
			String strTestTimeElasped = (String)htbParam.get( TEST_TIME_ELASPED );	// 滞在時間
			String strTestScore = (String)htbParam.get( TEST_SCORE );				// 得点

			// LoLogSessionテーブルの取得処理
			LoLogSessionDataAccess objSessionDataAccess = new LoLogSessionDataAccess();

			LoLogSessionRecord objSession = objSessionDataAccess.getLoLog(	mstrUserID,
																	mstrLoID,
																	mstrSessionID,
																	objDataAccess );

			// レコード存在チェック
			boolean newFlag = false;
			// 累積滞在時間
			long lngOldResidanceTime = 0;

			// 開始日時をLOLogテーブルより取得
			LoLogDataAccess objLoLogDataAccess = new LoLogDataAccess();
			mobjStartDate = (Date)objLoLogDataAccess.getLastAccess( mstrUserID, mstrLoID, objDataAccess );

			if( objSession == null ) {
				objSession = new LoLogSessionRecord();
				newFlag = true;
			}

			// LoLogテーブルの取得処理
			LoLogRecord objRecord = objLoLogDataAccess.getLoLog(	mstrUserID,
																	mstrLoID,
																	objDataAccess );

			if( objRecord == null ) {
				objRecord = new LoLogRecord();
			}

			// ユーザID設定
			objRecord.setUserID( mstrUserID );

			// LOID設定
			objRecord.setLoID( mstrLoID );

			// 開始日付を設定する
			String strStartDate = objRecord.getStudyStartDate();
			if( strStartDate == null ||
				strStartDate.equals( "" ) )
			{
				objRecord.setStudyStartDate(XMODate.parseTime(mobjStartDate));
			}

			// 累積滞在時間の計算
			String strResidentTime = objRecord.getResidanceTime();
			long lngResidanceTime = 0;
			if( strResidentTime != null &&
				!strResidentTime.equals( "" ) )
			{
				// 現在時間の取得
				lngResidanceTime = new Float( strResidentTime ).longValue();
			}
			lngResidanceTime += Long.parseLong(strTestTimeElasped) * 1000;
			objRecord.setResidanceTime( lngResidanceTime + "" );

			//Perceptionが返す日付の書式が固定でないので、システムより現在日時を取得するように変更します
			// 修正：2006/01/18 NTT Resonant M.Kitahara
			// 学習終了日時を取得
			//Locale objLocale = new Locale("EN", "US");
			//SimpleDateFormat formatter1 = new SimpleDateFormat ("dd MMMM yyyy HH:mm", objLocale);
			//Date dtStudyEndDate = formatter1.parse(strLessonDate + " " + strLessonTime, new ParsePosition(0));
			//SimpleDateFormat formatter2 = new SimpleDateFormat ("yyyy/MM/dd HH:mm:ss");
			//String strEndDate = formatter2.format(dtStudyEndDate);
			String strEndDate = XMODate.parseTime( new java.util.Date() );

			///////////////////////////////////////////////////////////////
			// LoLogSessionテーブルの更新処理
			///////////////////////////////////////////////////////////////

			// ユーザID設定
			objSession.setUserID( mstrUserID );

			// LOID設定
			objSession.setLoID( mstrLoID );

			// 開始日
			if( newFlag == true ) {
				// 新規の場合のみ更新
				objSession.setStudyStartDate(XMODate.parseTime( mobjStartDate ));
			}

			// 累積滞在時間
			if(strTestTimeElasped.equals("0")){
				objSession.setResidanceTime(strTestTimeElasped);
			}
			else{
				objSession.setResidanceTime( Long.parseLong(strTestTimeElasped) * 1000 + "" );
			}
			//LoLogSessionの合格日、修了日の設定
			// ステータスを決定
			if(strLessonScoreband != null && !strLessonScoreband.equals("")){
				if((strLessonScoreband.length()>=2 && strLessonScoreband.substring(0, 2).equals("合格")) || (strLessonScoreband.length()>=4 && strLessonScoreband.substring(0, 4).equalsIgnoreCase("pass"))){
					// 既存ステータスから合格日を取得する
					String strPassdate = objRecord.getPassday();
					if( strPassdate == null ||
						strPassdate.equals( "" ) )
					{
						// 今まで、合格していない場合はレコードに本日日付を設定
						objSession.setPassday( strEndDate );
					}
				}
			}

			// 既存ステータスから修了日を取得する
			String strStudyEndDate = objRecord.getStudyEndDate();
			if( strStudyEndDate == null ||
				strStudyEndDate.equals( "" ) )
			{
				// 修了していた場合は試験日付を設定
				objSession.setStudyEndDate( strEndDate );
			}

			// 最高得点、最低得点、満点の設定
			if( strTestScore != null &&
				!strTestScore.equals( "" ) )
			{
				objSession.setHighScore( strTestScore );
				objSession.setLowScore( strTestScore );
				objSession.setExecisePoint( strTestScore );
			}
			// 満点の設定
			if( strTestMax != null &&
				!strTestMax.equals( "" ) )
			{
				objSession.setFullScore( strTestMax );
			}

			// セッションIDの設定
			objSession.setSessionID( mstrSessionID );

			// 学習回数の設定
			objSession.setLunchTimes( mstrSessionID );

			// 登録処理
			objSessionDataAccess.insertUpdate( objSession, mstrUserID, mstrLoID, mstrSessionID, objDataAccess );

			///////////////////////////////////////////////////////////////
			// LoLogテーブルの更新処理
			///////////////////////////////////////////////////////////////

			//LoLogレコードの合格日、修了日の設定
			// ステータスを決定
			if(strLessonScoreband != null && !strLessonScoreband.equals("")){
				if((strLessonScoreband.length()>=2 && strLessonScoreband.substring(0, 2).equals("合格")) || (strLessonScoreband.length()>=4 && strLessonScoreband.substring(0, 4).equalsIgnoreCase("pass"))){
					// 既存ステータスから合格日を取得する
					String strPassdate = objRecord.getPassday();
					if( strPassdate == null ||
						strPassdate.equals( "" ) )
					{
						// 今まで、合格していない場合はレコードに本日日付を設定
						objRecord.setPassday( strEndDate );
					}
				}
			}
			// 既存ステータスから修了日を取得する
			strStudyEndDate = objRecord.getStudyEndDate();
			if( strStudyEndDate == null ||
				strStudyEndDate.equals( "" ) )
			{
				// 修了していた場合は試験日付を設定
				objRecord.setStudyEndDate( strEndDate );
			}

			// LoLogSessionの一番大きいhighscoreを設定
			objRecord.setHighScore( objSessionDataAccess.getMaxHighScore( mstrUserID, mstrLoID, objDataAccess ) );
			// LoLogSessionの一番小さいlowscoreを設定
			objRecord.setLowScore( objSessionDataAccess.getMinLowScore( mstrUserID, mstrLoID, objDataAccess ) );
			// 直近のexecise_pointを設定
			objRecord.setExecisePoint( strTestScore );
			// LoLogSessionの一番大きいfullScoreを設定
			objRecord.setFullScore( objSessionDataAccess.getMaxFullScore( mstrUserID, mstrLoID, objDataAccess ) );

			// LoLogテーブルの更新処理
			// 登録または更新処理を行います
			objLoLogDataAccess.insertUpdate(	objRecord,
												mstrUserID,
												mstrLoID,
												objDataAccess );

			// 参照LOIDリストを取得します
			LoClient objLoClient = new LoClient();
			if(!objLoClient.getListFromRealLOID( mstrLoID )){
				new LOException("参照LOIDリストの取得失敗しました。");
			}

			String[] strRefList = objLoClient.getRefListResult();
			
			// 参照リスト分ステータス伝播
			for(int i = 0; i < strRefList.length; i++){
				// ステータス伝搬処理
				StatusPropagation objStatus = new StatusPropagation( mstrUserID, strRefList[i] );
				PropagateControl.getInstance().addPropagate(objStatus);
			}

		}
		catch(SQLException se) {
			DebugLog.write( this.getClass(), se, DebugLog.HIGHT );
			throw new LOException( se.getMessage() );
		}
		catch(Exception xe ) {
			DebugLog.write( this.getClass(), xe, DebugLog.HIGHT );
			throw new LOException( xe.getMessage() );
		}
	}

}
