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

//
//	IndividualLogGroupProgressAction
//	変更履歴
//		2004.02.01	新規作成
//

package jp.co.ntt.lms.xms.logsumup.scorm;

import java.util.Date;
import java.util.List;
import java.text.DecimalFormat;

import javax.servlet.http.HttpServletRequest;
import jp.co.ntt.lms.xmo.util.ChangeEncode;
import jp.co.ntt.lms.xmo.util.XMODate;
import jp.co.ntt.lms.xms.framework.Constant;
import jp.co.ntt.lms.xms.framework.XmsException;
import jp.co.ntt.lms.xms.framework.XmsInnerException;
import jp.co.ntt.lms.xms.framework.XmsRequest;
import jp.co.ntt.lms.xms.framework.XmsResponse;
import jp.co.ntt.lms.xms.framework.XmsScreenBean;
import jp.co.ntt.lms.xms.framework.base.AbstractRmiAction;
import jp.co.ntt.lms.xms.framework.base.ActionResultBean;
import jp.co.ntt.lms.xms.framework.base.Logic;
import jp.co.ntt.lms.xms.logsumup.*;

/**
 * ログ集計グループ比較結果フレーム出力用アクション・クラス。<br>
 */
public class IndividualLogGroupProgressAction extends AbstractRmiAction {

    /**
     * リクエストされたLOID
     */
    private String LOID;
    /**
     * リクエストされたグループID
     */
    private String GroupID;
    /**
     * リクエストされたLoType
     */
    private String LOType;
    /**
     * リクエストされたUID
     */
    private String UID;
    /**
     * リクエストされたScormNode
     */
    private ScormItemList itemList;
	/**
	 * リクエストされた配下フラグ
	 */
	private String Reflex;
	/**
	 * リクエストされたモードフラグ
	 */
	private String mode;
	/**
	 * ＣＳＶ出力の有無を判定
	 */
	protected boolean csvFileIsRequired() {
		if ( mode.equals("") ) {
			return false;
		}else{
			return true;
		}
	}
    /**
     * ロジッククラス配列を戻す。<br>
     * @param request リクエストオブジェクト。
     * @return IndividualLogGroupProgressLogicクラスオブジェクト１要素だけの配列。
     * @see IndividualLogGroupProgressLogic
     */
    protected Logic[] getLogics(XmsRequest request) throws XmsException {
        Logic[] logSumUps = null;
        logSumUps = new Logic[1];
        // Logicクラスの派生クラスを生成
        logSumUps[0] =
            new IndividualLogGroupProgressLogic(
                GroupID,
                LOID,
                LOType,
                Reflex,
				mode,
				itemList);
        return logSumUps;
    }

    /**
     * リクエスト初期化処理。<br>
     * パラメータ名称&quot;userid&quot;、&quot;loid&quot;で送信された
     * リクエストパラメータをリスト化して、内部で保持する。
     * @param xmsRequest   HTTPリスエスト
     * @param xmsResponse  HTTPレスポンス
     * @see jp.co.ntt.lms.xms.framework.base.AbstractRmiAction#initProcessRequest(XmsRequest,XmsResponse)
     */
    public void initProcessRequest(
        XmsRequest xmsRequest,
        XmsResponse xmsResponse)
        throws XmsException {
        // スーパークラスのメソッドを呼び出し。
        super.initProcessRequest(xmsRequest, xmsResponse);
        HttpServletRequest request = null;
        request = xmsRequest.getRequest();
        // LoIDをパラメータより取得
        this.LOID = ChangeEncode.setChar(request.getParameter("LoID"));
        // ユーザーIDをパラメータより取得
        this.GroupID = ChangeEncode.setChar(request.getParameter("userId"));
        // LOTypeをパラメータより取得
        this.LOType = ChangeEncode.setChar(request.getParameter("LoType"));
        // 基本LO名をパラメータより取得
        this.UID = ChangeEncode.setChar(request.getParameter("UID"));
		// ＣＳＶ出力の場合の直下か配下のパラメータを取得
		this.Reflex = ChangeEncode.setChar(request.getParameter("reflex"));
		// 画面出力かＣＳＶ出力かのパラメータを取得
		this.mode = ChangeEncode.setChar(request.getParameter("mode"));
        // 教材構造を取得
		ScormDocument scormDocument = (ScormDocument)request.getSession().getAttribute(LOID);
		// 指定ＵＩＤのノードリストにて上書きする
        // パラメータチェック
        if (LOID.equals("")
            || GroupID.equals("")
            || LOType.equals("")
            || UID.equals("")
            || scormDocument == null) {
            throw new XmsInnerException("parameter is null.");
        }
		this.itemList = new ScormItemList(scormDocument, UID);
    }

	/**
	 * 検索結果をＣＳＶ文字列に変換する。<br>
	 * このメソッドは渡されるbeanがActionResultBeanであり、
	 * 内部にIndividualLogGroupProgressResultを保持していることを期待しています。
	 *
	 * @param bean アクション実行結果オブジェクト。
	 * @return beanの中からIndividualLogGroupProgressResultを取得し、CSVに変換した文字列。
	 * @see ActionResultBean
	 * @see IndividualLogGroupProgressResult
	 * @throws 渡されたbeanが不正などCSV変換に問題が発生した場合。
	 */
	public String convertToCSV(XmsScreenBean bean) {

		// 戻り値
		String retVal = null;
		// 戻り値作成用バッファ
		StringBuffer buffer = null;
		// リザルトクラス
		ActionResultBean resultBean = null;
		// グループログ集計結果専用クラス
		IndividualLogGroupProgressResult logResult = null;
		LoLogCommon_inc cominc = new LoLogCommon_inc();
		DecimalFormat objDecFormat = new DecimalFormat( "#######0.0" );
		DecimalFormat objIntFormat = new DecimalFormat( "#######0" );

		try {
			buffer = new StringBuffer();
			resultBean = (ActionResultBean) bean;
			// 先頭要素となっているロジック結果を取得
			logResult =
				(IndividualLogGroupProgressResult) resultBean.getFirstLogResult();

			// =================================================================
			// CSVレポート部
			// #レポート
			// 進捗状況(グループ指定)
			buffer.append(
				 IndividualLogGroupProgressConstant.STR_REPORT_o + "," );
			// ＬＯ
			buffer.append( IndividualLogGroupProgressConstant.STR_LO_o + ":");
			// LO名
			buffer.append( logResult.strLOName );
			// セクション名
			buffer.append("/" + logResult.strSectionName );
			// LO外部ID
			buffer.append("(" + logResult.strForeignLOID + "),");
			// グループ
			buffer.append( IndividualLogGroupProgressConstant.STR_GROUP_o + ":");
			// グループ名
			buffer.append( logResult.strGroupName );
			// グループ外部ID
			buffer.append("(" + logResult.strGroupForeignId + "),");
			// 集計対象者数
			buffer.append( IndividualLogGroupProgressConstant.STR_CANDIDATE_TOTAL_COUNT_o + ":");
			if ( Reflex.equals("") ) {
				// 直下ユーザ数（取得レコード数が直下ユーザ数と一致する）
				buffer.append( IndividualLogGroupProgressConstant.STR_DIRECTLY_UNDER_USER_o + logResult.flUserCount + IndividualLogGroupProgressConstant.STR_PERSON_o );
			} else {
				// 配下ユーザ数（取得レコード数が配下ユーザ数と一致する）
				buffer.append( IndividualLogGroupProgressConstant.STR_SUBORDINATE_USER_o + logResult.flUserCount + IndividualLogGroupProgressConstant.STR_PERSON_o );
			}
			// 行区切り文字
			buffer.append(Constant.LINE_SEPARATOR);

			// =================================================================
			// CSV個別ヘッダ部
			// 学習者
			buffer.append( IndividualLogGroupProgressConstant.STR_STUDENT_o );
			buffer.append(",");
			// 学習者外部ID
			buffer.append( IndividualLogGroupProgressConstant.STR_FOREIGN_ID_o );
			buffer.append(",");
			// 所属グループ
			buffer.append( IndividualLogGroupProgressConstant.STR_GROUPS_o );
			buffer.append(",");
			// グループ外部ID
			buffer.append( IndividualLogGroupProgressConstant.STR_FOREIGN_ID_o );
			buffer.append(",");
			// 学習回数
			buffer.append( IndividualLogGroupProgressConstant.STR_STUDY_COUNT_o );
			buffer.append(",");
			// 学習開始日時
			buffer.append( IndividualLogGroupProgressConstant.STR_DATE_START_o );
			buffer.append(",");
			// 最終アクセス日時
			buffer.append( IndividualLogGroupProgressConstant.STR_DATE_LAST_o );
			buffer.append(",");
			// アクセス回数
			buffer.append( IndividualLogGroupProgressConstant.STR_ACCESS_COUNT_o );
			buffer.append(",");
			// 累積滞在時間
			buffer.append( IndividualLogGroupProgressConstant.STR_TOTAL_LEARN_TIME_o );
			buffer.append(",");
			// 正規化得点（最新）
			buffer.append( IndividualLogGroupProgressConstant.STR_NEWEST_SCALED_SCORE_o );
			buffer.append(",");
			// 得点（最新）
			buffer.append( IndividualLogGroupProgressConstant.STR_NEWEST_SCORE_o );
			buffer.append(",");
			// 正規化得点（最高）
			buffer.append( IndividualLogGroupProgressConstant.STR_HIGH_SCALED_SCORE_o );
			buffer.append(",");
			// 得点（最高）
			buffer.append( IndividualLogGroupProgressConstant.STR_HIGH_SCORE_o );
			buffer.append(",");
			// 完了ユニット数
			buffer.append( IndividualLogGroupProgressConstant.STR_COMPLETE_UNIT_o );
			buffer.append(",");
			// 合格ユニット数
			buffer.append( IndividualLogGroupProgressConstant.STR_PASS_UNIT_o );
			buffer.append(",");
			// アサイン
			buffer.append( IndividualLogGroupProgressConstant.STR_ASSIGN_o );
			// 行区切り文字
			buffer.append(Constant.LINE_SEPARATOR);

			// =================================================================
			// データ部
			// 集計結果データリストを取得
			List UserList = logResult.getLog();
			// レコード数ループ
			for (int i = 0; i < UserList.size();i++) {
				Date datStartDate = null;
				Date datEndDate = null;
				String strUserName = null;
				String strUserForeignId = null;
				String strGroups = null;
				String strGroupForeignId = null;
				String strStudySessionCount = null;
				String strStartDate = null;
				String strEndDate = null;
				String strAccessCount = null;
				String strResidanceTime = null;
				String strNewestScaledScore = null;
				String strNewestScore = null;
				String strHighScaledScore = null;
				String strHighScore = null;
				String strCompPercent = null;
				String strPassPercent = null;
				String strAssign = null;

				// レコード情報取得
				IndividualLogGroupProgressStoreData dat = (IndividualLogGroupProgressStoreData)UserList.get(i);
				// ユーザー
				strUserName = dat.strUserName;
				// 外部ID
				strUserForeignId = dat.strUserID;
				// 所属グループ
				strGroups = dat.strGroupName;
				// 外部ID
				strGroupForeignId = dat.strGroupID;
				// 学習回数
				strStudySessionCount = Long.toString(dat.lngStudySessionCnt);
				// 学習開始日時
				datStartDate = dat.datStartDate;
				// 最終アクセス日時
				datEndDate = dat.datEndDate;
				// アクセスが存在するか判定
				if (datStartDate != null) {
					// 学習開始日時 日付型データをyyyy/mm/dd HH:mm:ss型に変換
					strStartDate = XMODate.parseTime(datStartDate);
					// 最終アクセス日時 日付型データをyyyy/mm/dd HH:mm:ss型に変換
					strEndDate = XMODate.parseTime(datEndDate);
					// アクセス回数
					strAccessCount = Long.toString(dat.lngAccessCount);
					// 累積滞在時間
					strResidanceTime = objDecFormat.format(dat.dwResidanceTime/60);
					// 正規化得点（最新）
					if ( dat.dwStoreScaledNewScore > 0 ) {
						// 正規化得点最新
						strNewestScaledScore = objIntFormat.format(dat.dwStoreScaledNewScore) + "/" + objIntFormat.format(logResult.flActCount * 100);
						// 得点最新
						strNewestScore = objIntFormat.format(dat.dwStoreNewScore);
						// 正規化得点最高
						strHighScaledScore = objIntFormat.format(dat.dwStoreScaledMaxScore) + "/" + objIntFormat.format(logResult.flActCount * 100);
						// 得点最高
						strHighScore = objIntFormat.format(dat.dwStoreMaxScore);
					}
					else {
						// 得点が無いので空文字
						strNewestScaledScore = "";
						strNewestScore = "";
						strHighScaledScore = "";
						strHighScore = "";
					}
					// 完了ユニット数
					strCompPercent = Long.toString(dat.lngUnitComplete) + "/" + objIntFormat.format(logResult.flActCount);
					// 合格ユニット数
					strPassPercent = Long.toString(dat.lngUnitPass) + "/" + objIntFormat.format(logResult.flActCount);
				} else {
					// アクセスがないので全て空文字
					strStudySessionCount="";
					strStartDate = "";
					strEndDate = "";
					strAccessCount = "";
					strResidanceTime = "";
					strNewestScaledScore = "";
					strNewestScore = "";
					strHighScaledScore = "";
					strHighScore = "";
					strCompPercent = "";
					strPassPercent = "";
				}
				// アサイン
				if(dat.blAssign){
					strAssign = "1";
				}else{
					strAssign = "0";
				}
				// CSV生成
				buffer.append( strUserName );
				buffer.append(",");
				buffer.append( strUserForeignId );
				buffer.append(",");
				buffer.append( strGroups );
				buffer.append(",");
				buffer.append( strGroupForeignId );
				buffer.append(",");
				buffer.append( strStudySessionCount);
				buffer.append(",");
				buffer.append( strStartDate );
				buffer.append(",");
				buffer.append( strEndDate );
				buffer.append(",");
				buffer.append( strAccessCount );
				buffer.append(",");
				buffer.append( strResidanceTime );
				buffer.append(",");
				buffer.append( strNewestScaledScore );
				buffer.append(",");
				buffer.append( strNewestScore );
				buffer.append(",");
				buffer.append( strHighScaledScore );
				buffer.append(",");
				buffer.append( strHighScore );
				buffer.append(",");
				buffer.append( strCompPercent );
				buffer.append(",");
				buffer.append( strPassPercent );
				buffer.append(",");
				buffer.append( strAssign );
				// 行区切り文字
				buffer.append(Constant.LINE_SEPARATOR);
			}
			// カーソルを先頭行の直前の行に移動する。
			logResult.beforeFirst();

			// =================================================================
			// CSV合計部生成
			buffer.append(IndividualLogGroupProgressConstant.STR_SUM_o);
			buffer.append(",");
			buffer.append(",");
			buffer.append(",");
			buffer.append(",");
			buffer.append(",");
			buffer.append(",");
			buffer.append(",");
			// アクセス回数合計
			buffer.append( objDecFormat.format(logResult.flAccessCountCnt));
			buffer.append(",");
			// 累積滞在時間合計
			buffer.append( objDecFormat.format(logResult.dwResidanceTimeCnt / 60));
			buffer.append(",");
			buffer.append(",");
			buffer.append(",");
			buffer.append(",");
			buffer.append(",");
			buffer.append(",");
			buffer.append(",");
			// 行区切り文字
			buffer.append(Constant.LINE_SEPARATOR);

			// =================================================================
			// CSV平均部
			String strAvgAccessCount		= "0.0";
			String strAvgResidanceTime		= "0.0";
			String strAvgNewestScaledScore	= "0.0/100";
			String strAvgNewestScore		= "0.0";
			String strAvgHighScaledScore	= "0.0/100";
			String strAvgHighScore			= "0.0";
			String strAvgCompPercent		= "0.0%";
			String strAvgPassPercent		= "0.0%";
			// アクセス回数平均（アクセス回数合計／データのあるレコード数）
			if(logResult.flAccessCountCnt > 0){
				strAvgAccessCount = objDecFormat.format(logResult.flAccessCountCnt / logResult.flRecValidCount);
			}
			// 累積滞在時間平均（累積滞在時間合計／データのあるレコード数）
			if(logResult.dwResidanceTimeCnt > 0){
				strAvgResidanceTime = objDecFormat.format(logResult.dwResidanceTimeCnt / 60 /logResult.flRecValidCount);
			}
			// 正規化得点（最新）平均（正規化得点（最新）合計／得点したユーザ数）
			if(logResult.dwStoreScaledNewScore > 0){
				strAvgNewestScaledScore	= objDecFormat.format(logResult.dwStoreScaledNewScore / logResult.flActCount / logResult.flRecValidCount) + "/100";
			}
			// 得点（最新）平均（得点（最新）合計／得点したユーザ数）
			if(logResult.dwStoreNewScore > 0){	
				strAvgNewestScore = objDecFormat.format(logResult.dwStoreNewScore / logResult.flRecValidCount);
			}
			// 正規化得点（最高）平均（得点（最新）合計／得点したユーザ数）
			if(logResult.dwStoreScaledMaxScore > 0){
				strAvgHighScaledScore = objDecFormat.format(logResult.dwStoreScaledMaxScore / logResult.flActCount / logResult.flRecValidCount) + "/100";
			}
			// 得点（最高）平均（得点（最高）合計／得点したユーザ数）
			if(logResult.dwStoreMaxScore > 0){
				strAvgHighScore = objDecFormat.format(logResult.dwStoreMaxScore / logResult.flRecValidCount);
			}
			// 完了率平均（完了ユニット数合計／全ユーザのAU数の合計*100）
			if(logResult.flUnitComplete > 0){
				strAvgCompPercent = objDecFormat.format(logResult.flUnitComplete / logResult.flActCount / logResult.flRecValidCount * 100) + "%";
			}
			// 合格率平均（合格ユニット数合計／全ユーザのAU数の合計*100）
			if(logResult.flUnitPass > 0){
				strAvgPassPercent = objDecFormat.format(logResult.flUnitPass / logResult.flActCount / logResult.flRecValidCount * 100) + "%";
			}
			// CSV生成
			buffer.append(IndividualLogGroupProgressConstant.STR_AVG_o);
			buffer.append(",");
			buffer.append(",");
			buffer.append(",");
			buffer.append(",");
			buffer.append(",");
			buffer.append(",");
			buffer.append(",");
			// アクセス回数平均
			buffer.append( strAvgAccessCount );
			buffer.append(",");
			// 累積滞在時間平均
			buffer.append( strAvgResidanceTime );
			buffer.append(",");
			// 正規化得点（最新）平均
			buffer.append( strAvgNewestScaledScore );
			buffer.append(",");
			// 得点（最新）平均
			buffer.append( strAvgNewestScore );
			buffer.append(",");
			// 正規化得点（最高）平均
			buffer.append( strAvgHighScaledScore );
			buffer.append(",");
			// 得点（最高）平均
			buffer.append( strAvgHighScore );
			buffer.append(",");
			// 完了ユニット数平均
			buffer.append( strAvgCompPercent );
			buffer.append(",");
			// 合格ユニット数平均
			buffer.append( strAvgPassPercent );
			buffer.append(",");
			// 行区切り文字
			buffer.append(Constant.LINE_SEPARATOR);
			// 取得したBufferを文字列に変換
			retVal = buffer.toString();
		} catch (Exception e) {
			e.printStackTrace();
			retVal = "";
		}
		return retVal;
	}
}
