/*
このファイルの中身は、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) ______________________________________.
*/

//
//機能名称 
//			  データモデル初期化の直前クラス
//	  変更履歴
//				  2003.11.26	zcj  新規作成		
//

package jp.co.ntt.lms.lo.scorm.cbtcom;

//import java.util.StringTokenizer;

/**
 * データモデル初期化の直前クラス
 * @author zhaicj
 *
 */

public class BeforeInitializer implements IBeforeInitializer {
	/**
	 * データモデル区分
	 */
    private String strModal = null;
   
	/**
     * BeforeInitializerクラスのコンストラクタ<br>
     * @param inModal データモデル
     */
    public BeforeInitializer(String inModal) {
		this.strModal = inModal;
    }

	/**
	 * データモデル用の初期化の直前処理<br>
	 * @param element 初期化されたデータモデル
	 */
	public void before_Initializer(CMIElement element) {
		if ( "binit_Attempt_number".equals( strModal ) ) {
			binit_Attempt_number( element );
		} else if ( "binit_LessonStatus".equals( strModal ) ) {
			binit_LessonStatus( element );
		} else if ( "binit_Entry".equals( strModal ) ) {
			binit_Entry( element );
		} else if ( "binit_TotalTime".equals( strModal ) ) {
			binit_TotalTime( element );
		} else if ( "binit_ObjAttempts".equals( strModal ) ) {
			binit_ObjAttempts( element );
		}
	}
   
	/**
     * Attempt_numberの初期化の直前処理<br>
     * @param element 初期化されたデータモデル
     */
	private void binit_Attempt_number(CMIElement element) {
		String buf;
		String strvalue = element.getLessonValue();
		if (strvalue == null) {
			element.setLocalValue("0");
			element.setLessonValue("0");
		}

		if (strvalue != null) {
			long lValue;
			try {
				lValue = Float.valueOf(strvalue).longValue();
			} catch (NumberFormatException ex) {
				lValue = 0;
			}
			lValue++;
			buf = Long.toString(lValue);		
			element.setLocalValue(buf);
			element.setLessonValue(buf);
		}
	}
   
	/**
	 * LessonStatusの初期化の直前処理<br>
	 * LessonStatusの初期化の直前処理<br>
	 * @param element 初期化されたデータモデル
	 */
	private void binit_LessonStatus(CMIElement element) {
		CMICBT cbt = element.getCBT();
		
		// CBTバージョンの取得
		String value = element.getLessonValue();
		if (value != null) {
			element.setLocalValue(value);
		}

		if (element.isSetValue()) {
			// 無処理
			element.resetSetValue();
		} else {
			// core.lesson_modeの値を確認して"browse"であれば、
			// lesson_statusの値を"browsed"に変更する
			CMIElement cmiElement = cbt.getNChild("core.lesson_mode");
			String value_Mode = cmiElement.getLocalValue();
			if (value_Mode != null) { 
				String strvalue = value_Mode;
				strvalue = strvalue.toLowerCase();
				
				// lesson_modeの値が"browse"の場合、"browsed"をセットして終了
				if (strvalue.startsWith("b")) {
					element.setLocalValue("Browsed");
	
					//	CBTCOMセッションクローズ時のログ出力対応
					// レッスンステータスを更新したので、更新フラグを立てる
					cbt.updateFlag(true);
					return;
				}
			}
	
			cmiElement = cbt.getNChild("core.credit");
			String value_Credit = cmiElement.getLocalValue();
			if (value_Credit != null) {
				String strct = value_Credit;
				strct = strct.toLowerCase();
				if ( !strct.startsWith("n") ) {
	
					// mastery_score と score を比較し lesson_status を更新する
					cmiElement = cbt.getNChild("student_data.mastery_score");
					String value_Mastery = cmiElement.getLocalValue();

					// 比較対象のスコアモデル名を取得する
					// 　AICC2.xの場合、score.raw
					// 　SCORM1.3の場合、score.scaled
					String strScoreName = CMIS13ModelUtil.getCheckScoreName();
					cmiElement = cbt.getNChild(strScoreName);
					String value_Score = cmiElement.getLessonValue();
					if (((value_Mastery != null) &&
							("".equals(value_Mastery) != true))
						&& ((value_Score != null) &&
							("".equals(value_Score) != true))) {

						// lesson_status の初期値
						boolean blnComp;
						try {
							blnComp = 
								Float.valueOf(value_Mastery).longValue() <= 
									Float.valueOf(value_Score).longValue();
						} catch (NumberFormatException e) {
							blnComp = false;
						}
						if ( blnComp ) {
							element.setLocalValue("passed");
	
							// レッスンステータスを更新したので、更新フラグを立てる
							cbt.updateFlag(true);
						// cmi.core.lesson_status に Failedを設定する
						} else if ( !blnComp ) {
							element.setLocalValue("failed");
							// レッスンステータスを更新したので、更新フラグを立てる
							cbt.updateFlag(true);
						}
					}
				}
			}
		}
	}

   
   /**
	* Entry用の初期化の直前処理<br>
	* @param element 初期化されたデータモデル
	*/
   private void binit_Entry(CMIElement element) {
   		CMICBT cbt = element.getCBT();
   		CMIElement cmielement = cbt.getNChild("core.exit");
   		String value = cmielement.getLessonValue();
   		if  ( value == null )  {
   			int version = element.getVersion();// バージョン情報取得
		
   			if ( (3500 <= version) || (CMIS13ModelUtil.isScorm13() == true) ) {// バージョンが3.5以降の場合
   				element.setLocalValue("ab-initio");
   			}else {// バージョンが3.5以前の場合
   				element.setLocalValue("Ab initio");// entry の初期値
   			}
   		} else {
   			String strvalue = value;
   			strvalue = strvalue.toLowerCase();
   			if ("suspend".equals(strvalue)) {// exit が suspend だった場合
   				element.setLocalValue("resume");
   			}else if("logout".equals(strvalue)){
   				element.setLocalValue("resume");
   			}
   			// 2010.10.12 taku-harada add >>
   			else if("time-out".equals(strvalue)){// exit が time-out だった場合
   				element.setLocalValue("ab-initio");
   			}
   			// 2010.10.12 taku-harada add <<   			
   			// 2011.01.12 taku-harada add >>   			
   			else if("normal".equals(strvalue)){// exit が normal だった場合
   				element.setLocalValue("ab-initio");
   			}
   			// 2011.01.12 taku-harada add <<
   			// 2011.01.12 taku-harada mod >>   			
   			else {								// exit が 空 だった場合
   				//element.setLocalValue("");
   				element.setLocalValue("ab-initio");
   			}
   			// 2011.01.12 taku-harada mod <<
   		}
   		// 処理がすんだので初期化
   		cmielement.setLocalValue("");
   }
   
	/**
	 * TotalTime用 の初期化前処理<br>
	 * @param element 初期化されたデータモデル
	 */
	private void binit_TotalTime(CMIElement element) {
		CMICBT cbt = element.getCBT();
		long lngHour = 0;
		long lngMin = 0;
		double dSec = 0;
		double dTotalSec = 0;
		double dZanSec = 0;
		CMITokenizer tokenizer;
		String strTempValue;
		StringBuffer sbBuf = new StringBuffer();
	
		// 2011.01.12 taku-harada add >>
		// entry が ab-initio だった場合totaltimeは 0
   		CMIElement cmielement_entry = cbt.getNChild("core.entry");
   		String value = cmielement_entry.getLocalValue();
   		if(value != null && "ab-initio".equals(value)){
   			element.setLocalValue("");
   		}
		// 2011.01.12 taku-harada add <<
   			
   		// session_time の値を取得する
		CMIElement cmielement = cbt.getNChild("core.session_time");
		String strValue = cmielement.getLessonValue();

		// 2011.01.07 taku-harada mod >>
//		if (strValue == null) {
//			return;
//		}
		// 2011.01.07 taku-harada mod <<

		try {
			// 2011.01.07 taku-harada mod >>
//			if ("".equals(strValue) != true)
			if (strValue != null && "".equals(strValue) != true)
			// 2011.01.07 taku-harada mod <<
			{
				dTotalSec = CMIS13ModelUtil.parseTimeintervalToLong(strValue);
			}
		}
		catch(S13LogFormatException ex){
			element.setError(CMIError.ERR_INCORRECT_DATA_TYPE);
			element.setVendorError("total_time initialize error(Session_Time Data Type)");
			return;
		}

		// total_time の値を取得する
		strValue = element.getLocalValue();
		if (strValue != null) {
			lngHour = 0; lngMin = 0; dSec = 0;
			strTempValue = strValue;

			try {
				if ("".equals(strValue) != true)
				{
					dTotalSec = dTotalSec + CMIS13ModelUtil.parseTimeintervalToLong(strValue);
				}
			}
			catch(S13LogFormatException ex){
				element.setError(CMIError.ERR_INCORRECT_DATA_TYPE);
				element.setVendorError("total_time initialize error(Total_Time Data Type)");
				return;
			}
		}

		if (dTotalSec != 0)
		{
			String strTime;
			strTime = CMIS13ModelUtil.formatS13Timespan((long)dTotalSec);
			element.setLocalValue(strTime);
		}
	}
   
   /**
	* ObjStatus用の初期化前処理<br>
	* @param element 初期化されたデータモデル
	*/
   private void binit_ObjAttempts(CMIElement element) {
		CMINode node = (CMINode)element;

		// setValueを行っていない場合、attempts以下のデータ要素を初期化するように修正
		if (node != null) {
			int nCount = node.getChildCount();
			if ( 0 < nCount) {
				// attempts.0 を取得する。
				CMINode child_n = (CMINode)node.getChild(0);
				if ( child_n != null ) {
					// 初期化実行フラグにfalseを代入
					boolean bInit = false;		
					// attempts.0.status にsetValueを行ったか判定する。
					CMILeafElement attempts_status = (CMILeafElement)child_n.getChild("status");
					if (attempts_status != null) {
						if (!attempts_status.isSetValue()) {
							// 初期化実行フラグをtrueに変更する
							bInit = true;	 
						}
					}
					// attempts.0.score.rawにsetValueを行ったか判定する。
					CMINode attempts_score = (CMINode)child_n.getChild("score");
					CMILeafElement raw = (CMILeafElement)attempts_score.getChild("raw");
					if (raw != null) {
						if (!raw.isSetValue()) {
							// 初期化実行フラグをtrueに変更する
							bInit = true;	
						} else {
							// attempts.0.statusの判定により、初期化実行フラグが
							// trueの可能性がある
							// 初期化実行フラグをfalseに戻す
							bInit = false;	
						}
					}
					
					if ( bInit ) {	
						// 初期化実行フラグがtrueならattempts以下のデータを
						// 初期化する
						init_ArrayClear(element);
					}
				}
			}
		}
	}
	/**
	 * ArrayClear用 の初期化メソッド<br>
	 * @param element 初期化されたデータモデル
	 */
	private void init_ArrayClear(CMIElement element) {
		CMINode node = (CMINode)element;
		if (node != null) {
			node.deleteChild();
		} 
	}
	
}
