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

//
//	メニュー作成クラス
//			変更履歴
//				2004.01.08	 新規作成   ishizaki
//				2004.02.05	 進捗表示メニュー追加   Katsuhiko.Sakurai(UNITEC)
//

package jp.co.ntt.lms.xmo.Lo;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Hashtable;
import java.util.Vector;

import jp.co.ntt.lms.Common.Bean.xmo.Base.BaseVo;
import jp.co.ntt.lms.lo.LoComData;
import jp.co.ntt.lms.lo.LoPropertyDef;
import jp.co.ntt.lms.lo.LoTop;
import jp.co.ntt.lms.lo.LoTopClient;
import jp.co.ntt.lms.lo.progress.LearningProgressManager;
import jp.co.ntt.lms.xmo.Environment;
import jp.co.ntt.lms.xmo.MenuData;
import jp.co.ntt.lms.xmo.XMOClient;
import jp.co.ntt.lms.xmo.XMOPropertyDef;
import jp.co.ntt.lms.xmo.Base.XMSBase;
import jp.co.ntt.lms.xmo.Base.XMSBaseClient;
import jp.co.ntt.lms.xmo.RoleAssignments.RoleAssignmentsClient;
import jp.co.ntt.lms.xmo.util.DebugLog;
import java.net.URLEncoder;

//ADD 2005/02/15 START Katsuhiko Kagami(UNITEC) [拡張メニュー表示]
import jp.co.ntt.lms.lo.MenuMakerExtend;
//ADD 2005/02/15 END Katsuhiko Kagami(UNITEC) [拡張メニュー表示]

/**
 * メニュー取得クラス<br>
 *
 * <pre>
 * このクラスにはメニュー作成に必要なxmoパラメータ、loパラメータ、xmoメニューリスト、
 * loメニューリストを提供します
 * 
 * xmoパラメータ,LoReturnURLの形式が合わない場合はgetXmoMenuListメソッドgetLoMenuListメソッドを
 * の引数、xmoParam,loReturnURLに形式の合うパラメータを指定してgetXmoMenuListメソッドgetLoMenuListメソッド
 * を実行してください
 *
 *	//xmoメニューの取得
 *	MenuData[] xmoMenu getXmoMenuList(tree_view_type,selectIniMenu,userId,selectId,<b>newParam</b>,popupType);
 *	//LOメニューの取得
 *	MenuData[] loMenu = getLoMenuList(userId,loginId,groupUserId,<b>newParam</b>,loId,password);
 *
 * </pre>
 *
 *
 * @author ishizaki
 *
 */
public class GetMenu {
	/** LOType */
	private String loType;
	/** RealLoID */
	private String realLoId;
	/** 前提条件 */
	private String prere;
	
	/**
	 * コンストラクタ
	 */
	public GetMenu() {
	}

	/**
	 * xmoメニューとloメニューの結合したメニューリストを返す<br>
	 *
	 * PopupTypeが指定されていなければxmoメニューは作成しない<br>
	 * 
	 * <pre>
	 * BaseVoオブジェクトでセットされているプロパティの(例)
	 * [getParentID:LO1]
	 * [getTreepath:/LO0/LO1/LO3/:/LO3]
	 * [getLoId:LO3]
	 * [getUserId:PE000000]
	 * [getLearner:NO]
	 * [getLoginId:root]
	 * [getPopupType:4]
	 * [getSelectId:LO3]
	 * [getTreeViewType:2]
	 * [getReturnURL:http://localhost:80/xms2/jsp/xmo/Base/frameset_g.jsp]
	 * [getLoType:5]
	 * </pre>
	 * 
	 * @param baseVo Baseで使用パラメータ格納オブジェクト
	 *
	 * @return xmoメニューとloメニューの結合したメニューリスト
	 */
	public MenuData[] getMenuList(BaseVo baseVo) throws Exception{
		//返却用一時格納リストxmoメニューとloメニューを格納する
		ArrayList list = new ArrayList();	

		//ポップアップ種別が指定されている場合のみxmoメニューを作成
		if(baseVo.getPopupType() != null && !baseVo.getPopupType().equals("")){
			//XMOメニューの取得
			MenuData[] xmodata = getXmoMenuList(baseVo);
			//返却用一時格納リストにxmoメニューを追加
			list.addAll(Arrays.asList(xmodata));
		}

		//Loメニューの作成
		MenuData[] loData = getLoMenuList(baseVo);
		//返却用一時格納リストにloメニューを追加		
		list.addAll(Arrays.asList(loData));
		
		// 20050205 ADD start Katsuhiko.Sakurai 進捗表示メニュー追加
		LearningProgressManager manager = new LearningProgressManager();
		MenuData progressMenu = manager.getMenu(baseVo);
		if ( progressMenu != null ) list.add(progressMenu);
		// 20050205 ADD end Katsuhiko.Sakurai 進捗表示メニュー追加
		
//		ADD 2005/02/15 START Katsuhiko Kagami(UNITEC) [コース管理メニュー追加]
		MenuMakerExtend extMenu = new MenuMakerExtend();
		String strUserID = baseVo.getUserId();
		// MOD 2005/03/15 START Katsuhiko Kagami(UNITEC) [メニュー修正]
		String strLOID = baseVo.getLoId();

		//返却用一時格納リストにコース管理メニューを追加		
		MenuData[] courseMenu = extMenu.makeMenu(strUserID, strLOID);
		
		if (courseMenu != null) {
			list.addAll(Arrays.asList(courseMenu));
		}
		// MOD 2005/03/15 START Katsuhiko Kagami(UNITEC) [メニュー修正]
//		ADD 2005/02/15 END Katsuhiko Kagami(UNITEC) [コース管理メニュー追加]
		
		//リストに格納していたMenuDataオブジェクトを配列に戻して返却
		return (MenuData[])list.toArray(new MenuData[list.size()]);
	}


	//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< xmo >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
	/***
	 * ユーザが使用可能なXMOのメニューを取得する<br>
	 *
	 * <pre>
	 * popupType popupTypeがXMOClientオブジェクトから取得したMenuDataオブジェクトのpopupTypeに見つから
	 * ない場合は返却されるユーザが使用可能なXMOメニューオブジェクトには含まれません
	 * 
	 * データベースから検索後、MenuDataオブジェクトに下記の情報を編集してsetしています
	 * (getURL)
	 * 返却されたMenuDataオブジェクトのgetURL()には次の画面遷移先URL +
	 * 引数で指定したxmoParam + "&xmo_id=" + xmoId(ユーザが使用可能なxmoId)が返却されます
	 *
	 * (getTargetWindow)
	 * 返却されたMenuDataオブジェクトのgetTargetWindow()は"xmo"が返却されます
	 * (memo:既存のGetMenu.jspではxmoParamに"$xmo$"($でスピリットしている)を追加しているこれは
	 * windowのTarget指定をしている為ここではMenuDataオブジェクトのsetTargetWindowに直接"xmo"を指定することにした)
	 * 
	 * (windowのサイズ)
	 * xmoではウィンドウのサイズは固定の為何もセットされません
	 * </pre>
	 * 
	 * 
	 *
	 * @param tree_view_type ツリービュータイプ(メニュー取得の検索条件)
	 * @param selectIniMenu　初期メニュー名称(null,空文字の場合は検索条件に設定しない(メニュー取得の検索条件))
	 * @param userId	UserID
	 * @param selectId	選択されたLoID
	 * @param xmoParam xmo戻りURL(メソッドgetXmoParameterを参照)
	 * @param popupType ポップアップタイプ
	 *
	 * @return ユーザが使用可能なXMOメニューオブジェクト
	 * 
	 */
	public MenuData[] getXmoMenuList(
		String tree_view_type,
		String selectIniMenu,
		String userId,
		String selectId,
		String xmoParam,
		String popupType)
		throws Exception {

		//ユーザに割り当てられているXmoIDリストの取得
		ArrayList list = getAssignXmoList(userId,selectId);

		XMSBaseClient xmsBaseClient = new XMSBaseClient();

		//検索条件の設定
		xmsBaseClient.setWhereTreeViewType(tree_view_type);
		//初期メニューが設定されている場合のみ検索条件に入れる
		if (selectIniMenu != null && !selectIniMenu.equals("")) {
			xmsBaseClient.setWhereIniMenu(selectIniMenu);
		}

		//検索失敗
		if (xmsBaseClient.select() == false) {
			throw new Exception("select Method of XMSBaseClient Class returned false.");
		}

		//MenuData保持用一時バッファ
		ArrayList listBuffer = new ArrayList();
		while (xmsBaseClient.next()) {
			String xmoId = xmsBaseClient.getXmoID();		//xmoId
			String className = xmsBaseClient.getClassName();//実行クラス名

			// ユーザに割り当てられているXmoIDリストの取得にみつからなかった
			if(list.contains(xmoId) == false){
				continue;
			}

			//クラス名が取得できてないか学習権限XMOでないかログ参照権限XMOでない
			if (className == null ||
				className.equals("") ||
				className.equals(XMOPropertyDef.LEARN_XMO) ||
				className.equals(XMOPropertyDef.LOG_XMO)) {
				continue;
			}

			//XMOの取得 
			XMOClient objXMO = new XMOClient(className);

			// メニュー取得用のHashtableを作成して、パラメータを設定する
			Hashtable htbParam = new Hashtable();
			htbParam.put(XMOPropertyDef.PARAM_ID, selectId);
			htbParam.put(LoPropertyDef.USER, userId);
			htbParam.put(LoPropertyDef.LOID, selectId);
				
			//getMenuListの返却Vectorを一時格納
			Vector vec = objXMO.getMenuList(htbParam);
			for(int i=0;i<vec.size();i++){
				MenuData data = (MenuData)vec.get(i);

				// 該当するポップアップ種別がみつからない場合はメニューリストに追加しない
				if(  data.getPopupType().indexOf( popupType ) >= 0 ) {
					String url = data.getURL();
					//urlにパラメータを追加する
					data.setURL(url + "?" + xmoParam + "&xmo_id=" + xmoId);
					//Tagegetをセットする
					data.setTargetWindow("xmo");
					//MenuData保持用一時バッファにMenuDataオブジェクトを追加
					listBuffer.add(data);
				}

			}				
		}

		//while文で蓄積されたデータをMenuData[]に変換して返却
		return (MenuData[])listBuffer.toArray(new MenuData[listBuffer.size()]);
	}

	/**
	 * ユーザが使用可能なXMOのメニューを取得する<br>
	 *
	 * 詳細はgetXmoMenuList(tree_view_type,selectIniMenu,userId,selectId,xmoParam,popupType)
	 * を参照
	 *
	 * @param baseVo Baseで使用パラメータ格納オブジェクト
	 *
	 * @return ユーザが使用可能なXMOメニューオブジェクト
	 *
	 */
	public MenuData[] getXmoMenuList(BaseVo baseVo)throws Exception{
		return getXmoMenuList(
								baseVo.getTreeViewType(),
								baseVo.getIniMenu(),
								baseVo.getUserId(),
								baseVo.getSelectId(),
								getXmoParameter(baseVo),
								baseVo.getPopupType()
							 );
	}


	
	/***
	 * XMOメニューパラメータの取得<br>
	 * 
	 * 引数を元にした作成したxmoパラメータを返します<br>
	 * 
	 * 返却される値は次のフォーマットになります<br>
	 * <pre>
	 * parentID=LO1&selectID=LO3&tree_view_type=2	 * 
	 * </pre>
	 *
	 * @param parentId 親ID
	 * @param selectId 選択されたID
	 * @param tree_view_type tree_view_type 
	 *
	 * @return xmoメニューパラメータ
	 */
	public String getXmoParameter(
		String parentId,
		String selectId,
		String tree_view_type
		) {
			StringBuffer buffer = new StringBuffer();
			buffer.append("parentID=");
			buffer.append(parentId);
			buffer.append("&selectID=");
			buffer.append(selectId);
			buffer.append("&tree_view_type=");
			buffer.append(tree_view_type);
			return buffer.toString();
	}

	/***
	 * XMOメニューパラメータの取得<br>
	 * 
	 * BaseVoを元にした作成したxmoパラメータを返します<br>
	 * 
	 * 詳細はgetXmoParameter(parentId,selectId,tree_view_type)
	 * を参照
	 *
	 * @param baseVo Baseパラメータ格納オブジェクト
	 * @return XMOメニューパラメータ
	 *  
	 */
	public String getXmoParameter(BaseVo baseVo) {
		return getXmoParameter(
								baseVo.getParentID(),
								baseVo.getSelectId(),
								baseVo.getTreeViewType()
							  );
	}

	/**
	 * ユーザID、選択したIDを元にユーザに割り当てられているXmoIDリストを返却します<br>
	 * 
	 * <pre>
	 * 選択されたもの(selectId)が人,グループ、LO以外（教材構造）の場合、メニューをださないため
	 * サイズが0のArryListが返却されます
	 * </pre>
	 * 
	 * @param userId ユーザID
	 * @param selectId 選択されたID
	 *
	 * @return ユーザに割り当てられているXmoIDのリスト
	 */
	public ArrayList getAssignXmoList(String userId, String selectId)throws Exception {

		//選択されたものが人グループLO以外（教材構造）の場合、メニューをださない。
		if (selectId.indexOf("GR") == -1
			&& selectId.indexOf("PE") == -1
			&& selectId.indexOf("LO") == -1) {
			return new ArrayList();
		}

		// 権限割当からユーザに割り当てられている権限を取得する
		RoleAssignmentsClient roleAss = new RoleAssignmentsClient();

		// searchXmoListメソッドの第２引数は選択対象がLOの場合はnullを入力パラメータとする
		if ((roleAss.searchXmoList(
				userId,
				((selectId.indexOf("LO") == -1)) ? selectId : null))
			== false) {
			//検索失敗
			throw new Exception("searchXmoList Method of RoleAssignmentsClient Class returned false.");
		}

		//getXmoListの戻りがString[]なのでArryListに変換して返却
		return new ArrayList(Arrays.asList(roleAss.getXmoList()));

	}

	//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Lo >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
	/**
	 * ユーザが使用可能なLoのメニューオブジェクトを取得します<br>
	 * 
	 * LOIDをもとにLoType,RealLOID,Prere(前提条件)を取得しそれを元にユーザが使用可能な
	 * LOのメニューを取得します
	 *
	 * LoTypeがコンテナ以外の場合はウィンドウサイズの取得を行います
	 * 
	 * @param userId ユーザID
	 * @param loginId ログインID
	 * @param groupUserId グループユーザID(groupUserIdがnullまたは空文字の場合はuserIdを検索条件とします)
	 * @param loId LOID
	 * @param password パスワード
	 *
	 * @return ユーザが使用可能なLoのメニューオブジェクトを取得します
	 */
	public MenuData[] getLoMenuList(
		String userId,
		String loginId,
		String groupUserId,
		String loId,
		String password)throws Exception {
		String winWidth = ""; 	//ウインドウのサイズwidth
		String winHeight = "";	//ウインドウのサイズheight
			
		//LOIDをキーに検索しLoType,RealLOID,Prereをプロパティにセット
		setLoProperty(loId);

		// 取得したLo種別を元にLoTopClientをインスタンス化
		Environment Env = new Environment();
		String serverName = Env.getLoServerName();
		LoTopClient loTopClient = new LoTopClient(serverName,this.loType);			
			
		//LoTypeがコンテナ以外の場合はウィンドウサイズの取得を行う
		if(this.loType.equals("0") == false){
			// Windowサイズの取得を行う。
			if(loTopClient.getData(this.realLoId) == false ) {
				//検索失敗
				throw new Exception("getData Method of LoTopClient Class returned false.");
			}
			LoComData loComData = loTopClient.getDataInfo(0);
			winWidth = loComData.getWinWidth();
			winHeight= loComData.getWinHeight();

		}
			
		//検索条件の設定
		loTopClient.setLoID(loId);
		loTopClient.setRealLoID(this.realLoId);
		loTopClient.setLoType(this.loType);
		loTopClient.setUserID(userId);
		loTopClient.setValue("LOGIN_ID",loginId);
		loTopClient.setPassword(password);

		//前提条件があった場合はパラメータに追加する
		if(this.prere != null && !this.prere.equals("")){
			loTopClient.setValue("Prere",this.prere);
		}		
			
		//groupUserIdがなければuserIdをセット
		if((groupUserId == null) || (groupUserId.equals(""))){
			loTopClient.setTargetID(userId);
		}else{
			loTopClient.setTargetID(groupUserId);
		}

			
		if(loTopClient.getMenuList() == false){
			//検索に失敗した
			throw new Exception("getMenuList Method of LoTopClient Class returned false.");
		}
		//ウィンドウサイズの設定
		MenuData[] menuData = loTopClient.getMobjMenuList();
		for(int i=0;i<menuData.length;i++){
			menuData[i].setWidth(winWidth);
			menuData[i].setHeight(winHeight);
		}
		return menuData;
			
	}

	/**
	 * ユーザが使用可能なLoのメニューオブジェクトを取得します<br>
	 * 
	 * 詳細はgetLoMenuList(userId,loginId,groupUserId,returnUrl,loId,password)を参照<br>
	 * 
	 * @param baseVo Baseパラメータオブジェクト
	 *
	 * @return ユーザが使用可能なLoのメニューオブジェクトを取得します
	 *
	 */
	public MenuData[] getLoMenuList(BaseVo baseVo)throws Exception{
		return getLoMenuList(
								baseVo.getUserId(),
								baseVo.getLoginId(),
								baseVo.getGroupUserId(),
								baseVo.getLoId(),
								baseVo.getPassword()
							);
	}

	/**
	 * loType,realLoId,prereをプロパティにセットします<br>
	 *
	 * loIdを元にLoClientオブジェクトからloType,realLoId,prereを取得します
	 *
	 * 
	 * @param loId
	 * 
	 */
	public void setLoProperty(String loId)throws Exception{
		LoClient loClient = new LoClient();
		//LOIDを検索条件にセット
		loClient.setWhereLoID(loId);
		
		if(loClient.select() == false){
			//検索失敗
			throw new Exception("select Method of LoTopClient Class returned false.");
		}
			
		if(loClient.next()){
			this.loType = loClient.getLoType();
			this.realLoId = loClient.getRealLOID();
			this.prere = loClient.getPrere();			
		}
	}

	//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< getter & setter >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
	/**
	 * Returns the loType.
	 * @return String
	 */
	public String getLoType() {
		return loType;
	}

	/**
	 * Returns the prere.
	 * @return String
	 */
	public String getPrere() {
		return prere;
	}

	/**
	 * Returns the realLoId.
	 * @return String
	 */
	public String getRealLoId() {
		return realLoId;
	}

	/**
	 * Sets the loType.
	 * @param loType The loType to set
	 */
	public void setLoType(String loType) {
		this.loType = loType;
	}

	/**
	 * Sets the prere.
	 * @param prere The prere to set
	 */
	public void setPrere(String prere) {
		this.prere = prere;
	}

	/**
	 * Sets the realLoId.
	 * @param realLoId The realLoId to set
	 */
	public void setRealLoId(String realLoId) {
		this.realLoId = realLoId;
	}

}
