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

//
//	Offline教材 オフラインログユーティリティクラス
//			変更履歴
//				2004.01.08	新規作成	二條　智文
//
package jp.co.ntt.lms.lo.Offline.OfflineLog;

import java.util.*;
import java.text.*;
import org.w3c.dom.*;

/**
 * Offline教材 オフラインログユーティリティクラス<BR>
 * 各種汎用メソッドを提供します。
 */
public class OfflineUtil {

	/**
	 * HHHH:MM:SS.SS 形式の文字列をlong型のミリ秒に変換します
	 * @param strTime HHHH:MM:SS.SS形式の文字列
	 * @return long ミリ秒に変換した値
	 * @exception OfflineLogFormatException 変換に失敗した場合
	 */
	public static long parseTime( String strTime )
		throws OfflineLogFormatException
	{
		StringTokenizer token = new StringTokenizer( strTime, ":" );

		long lngHour = 0;
		long lngMinute = 0;
		float fltSecond = 0;

		int intCount = 0;
		try {
			while( token.hasMoreTokens() ) {

				String strValue = token.nextToken();
				switch( intCount ) {
					case 0:
						// 時間
						lngHour = Long.parseLong( strValue );
						break;
					case 1:
						// 分
						lngMinute = Long.parseLong( strValue );
						break;
					case 2:
						// 秒
						fltSecond = Float.parseFloat( strValue );
						break;
					default:
						throw new OfflineLogFormatException();
				}

				// カウントアップ
				intCount++;
			}
		}
		catch( NumberFormatException ne ) {
			throw new OfflineLogFormatException(ne.getMessage());
		}

		if( intCount != 3 ) {
			throw new OfflineLogFormatException();
		}

		long lngRes = 0;

		lngRes = (lngHour * 3600000L) + (lngMinute * 60000L) + (long)(fltSecond * 1000L);

		return lngRes;
	}

	/**
	 * long型のミリ秒をHHHH:MM:SS.SS 形式の文字列に変換します
	 * @param lngTime ミリ秒に変換した値
	 * @return String HHHH:MM:SS.SS形式の文字列
	 */
	public static String formatTime( long lngTime ) {

		// 余りを保持する
		long lngRem = 0;

		// 時間の算出
		int intHour = (int)(lngTime / 3600000L);
		lngRem = lngTime % 3600000L;

		// 分の算出
		int intMinute = (int)(lngRem / 60000L);
		lngRem = lngRem % 60000L;

		// 秒の算出
		float fltSecond = lngRem / 1000F;

		// 時間のフォーマット
		DecimalFormat objHourFormat = new DecimalFormat( "0000" );
		String strHour = objHourFormat.format( intHour );

		// 分のフォーマット
		DecimalFormat objMinuteFormat = new DecimalFormat( "00" );
		String strMinute = objMinuteFormat.format( intMinute );

		// 秒のフォーマット
		DecimalFormat objSecondFormat = new DecimalFormat( "00.##" );
		String strSecond = objSecondFormat.format( fltSecond );


		return strHour + ":" + strMinute + ":" + strSecond;
	}


	/**
	 * yyyy:mm:ss HH:MM:SS 形式の文字列を日付型に変換します
	 * @param strDate yyyy:mm:ss HH:MM:SS形式の文字列
	 * @return Date 日付に変換した値
	 * @exception OfflineLogFormatException 変換に失敗した場合
	 */
	public static Date parseDate( String strDate )
		throws OfflineLogFormatException
	{
		Date objDate = null;

		// 日付文字列からカレンダーオブジェクトを生成する
		DateFormat objFormat = new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss" );
		objFormat.setLenient( false );
		try {
			objDate = objFormat.parse( strDate );
		}
		catch( ParseException pe ) {
			throw new OfflineLogFormatException( pe.getMessage() );
		}

		return objDate;
	}

	/**
	 * ステータス文字列(String)をステータス文字(char)に変換します。
	 * 以下の文字以外はエラーとします。
	 * <PRE>
	 *    n    not attemptedを意味する。
	 *    i    incompleteを意味する。
	 *    f    failedを意味する。
	 *    c    completedを意味する。
	 *    p    passedを意味する。
	 *    b    browasedを意味する。	 * </PRE>
	 * @param strStatus ステータス文字列
	 * @return char ステータス文字
	 * @exception OfflineLogFormatException
	 */
	public static char parseStatus( String strStatus )
		throws OfflineLogFormatException
	{

		if( strStatus.length() != 1 ) {
			throw new OfflineLogFormatException( "Invalid Status : " + strStatus );
		}

		char chrStatus = strStatus.charAt(0);
		if( chrStatus != OfflineLogConst.NOT_ATTEMPT_STATUS &&
			chrStatus != OfflineLogConst.INCOMPLETE_STATUS &&
			chrStatus != OfflineLogConst.FAILED_STATUS &&
			chrStatus != OfflineLogConst.COMPLETED_STATUS &&
			chrStatus != OfflineLogConst.PASSED_STATUS &&
			chrStatus != OfflineLogConst.BROWASED_STATUS
		) {

			throw new OfflineLogFormatException( "Invalid Status : " + strStatus );
		}

		return chrStatus;

	}

	/**
	 * エレメント種別文字列(String)をエレメント種別文字(char)に変換します。
	 * 以下の文字以外はエラーとします。
	 * <PRE>
	 *    b    ブロックを意味する
	 *    s    SCOを意味する
	 *    a    AUを意味する。
	 *    t    assetを意味する
	 *    c    SACを意味する
	 * </PRE>
	 * @param strElementType エレメント種別文字列
	 * @return char エレメント種別文字
	 * @exception OfflineLogFormatException
	 */
	public static char parseElementType( String strElementType )
		throws OfflineLogFormatException
	{

		if( strElementType.length() != 1 ) {
			throw new OfflineLogFormatException( "Invalid ElementType : " + strElementType );
		}

		char chrElementType = strElementType.charAt(0);
		if( chrElementType != OfflineLogConst.BLOCK_TYPE &&
			chrElementType != OfflineLogConst.SCO_TYPE &&
			chrElementType != OfflineLogConst.AU_TYPE &&
			chrElementType != OfflineLogConst.ASSET_TYPE &&
			chrElementType != OfflineLogConst.SAC_TYPE
		) {

			throw new OfflineLogFormatException( "Invalid ElementType : " + strElementType );
		}

		return chrElementType;

	}

	/**
	 * ノードに設定されている値を取得します。
	 * 取得出来ない場合はnullを返します。
	 * @param objNode ノード
	 * @return String ノードの値
	 */
	static String getNodeValue( Node objNode ) {
		// テキストの取得
		NodeList objNodeList = objNode.getChildNodes();
		if( objNodeList != null ) {
			for( int i = 0; i < objNodeList.getLength(); i++ ) {
				//#TEXTセクションまたは#CDATAセクションのみ取得
				if( objNodeList.item(i).getNodeType() == Node.TEXT_NODE ||
					objNodeList.item(i).getNodeType() == Node.CDATA_SECTION_NODE )
				{
					return objNodeList.item(i).getNodeValue();
				}
			}
		}

		return null;
	}

	/**
	 * ノード配下から指定されたノード名を持つノードを検索し、その値を取得して返します。
	 * もし同一ノード名を持つノードが複数存在した場合はツリーの上位が優先されます。
	 * ノードが存在しない場合はnullを返します。
	 * @param String strNodeName ノード名
	 * @param objNode ノードオブジェクト
	 */
	static String getNodeValueFromNodeName( String strNodeName, Element objElm ) {

		NodeList objNodeList = objElm.getElementsByTagName( strNodeName );

		if( objNodeList.getLength() > 0 ) {

			return OfflineUtil.getNodeValue( objNodeList.item(0) );
		}

		return null;
	}

	/**
	 * 指定されたノードの配下の子ノードから指定されたノード名のノードを取得して返します。
	 * @param objNode ノード
	 * @param strName ノード名
	 * @return Node[] ノード配列
	 */
	static Node[] getNodeList( Node objNode, String strName ) {

		Vector vecNodeList = new Vector();

		// 子ノードリストの取得
		NodeList objNodeList = objNode.getChildNodes();
		if( objNodeList != null ) {
			for( int i = 0; i < objNodeList.getLength(); i++ ) {
				Node objNodeTemp = objNodeList.item(i);
				if( objNodeTemp.getNodeName().equals( strName ) ) {
					vecNodeList.add( objNodeTemp );
				}
			}
		}

		Node[] objNodes = new Node[vecNodeList.size()];
		vecNodeList.copyInto( objNodes );

		return objNodes;

	}
}


