/////////////////////////////////////////////////////////////////
//Copyright (C) 2005 NTT CORPORATION.
//
//	LO進捗の階層構造を構築するクラス
//
//		変更履歴
//			2005.01.27  新規作成  Katsuhiko.Sakurai(UNITEC)
//
//	機能
//
//	このクラスはLO進捗の階層構造を構築するクラスです。
//
////////////////////////////////////////////////////////////////
package jp.co.ntt.lms.lo.progress;

import java.util.Iterator;
import java.util.List;

import jp.co.ntt.lms.lo.progress.util.XMOInformationGetter;
import jp.co.ntt.lms.xmo.Lo.LoClient;
import jp.co.ntt.lms.xmo.Lo.LoData;
import jp.co.ntt.lms.xmo.LoRelation.LoRelationClient;

/**
 * LO進捗の階層構造を構築するクラスです。
 * 
 * @author Katsuhiko Sakurai (UNITEC)
 * @version 1.0
 */
public class LOProgressTreeFactory extends AbstractXMOProgressTreeFactory {

	/**
	 * コンストラクタです。
	 * 
	 * @param parentID 階層構造の親LOのID
	 * @param targetID 対象となるユーザ・グループのID
	 * @param loginID ログインユーザのID
	 */
	public LOProgressTreeFactory(String parentID, String targetID, String loginID) {
		super(parentID, targetID, loginID);
	}

	/**
	 * Lo進捗階層構造を生成します。
	 * 
	 * @param parentID 	階層構造の親LoID
	 * @param targetUserID 対象となるユーザ・グループのID
	 * @param loginID ログインユーザID
	 * @param level 階層レベル
	 * @return XMOProgress LO進捗階層構造のルート
	 * @exception Exception
	 */
	protected XMOProgress createProgressTree(String parentID, String targetUserID, String loginID, int level ) throws Exception {
		
		XMOProgress rootProgress = null;
		
		// LOがルートの場合
		if( parentID.equals("LO0") ) {
			
			rootProgress = new ContainerProgress( parentID, targetUserID, level, super.getConfigManager() );

			// 指定ユーザがルートユーザの場合全LOが対象
			if (targetUserID.equals("PE000000")) {

				// LOの子供LOを取得
				LoRelationClient loRelation = new LoRelationClient();
				List childLoIDs = loRelation.getLoIds( parentID );
				Iterator ite = childLoIDs.iterator();
				
				// 検索結果
				while( ite.hasNext() ) {
					XMOProgress xmoProgress = this.createProgressTree( ite.next().toString(), targetUserID, loginID, level );
					rootProgress.add( xmoProgress );
				}
			
			// ルートユーザ以外はユーザにアサインされているLOのツリー作成
			} else {
			
				//指定ユーザに学習アサインされているルートLO情報を取得
				List rootLOs = XMOInformationGetter.getRootLoList(targetUserID, 1);
				
				// ログインユーザに管理アサインされているルートLO情報を取得
				List rootLOsOfLoginUser = XMOInformationGetter.getRootLoList(loginID, 2);
				
				XMOProgress progress = null;
				Iterator iteRootLos = rootLOs.iterator();

				while(iteRootLos.hasNext()) {
				
					LoData loData = (LoData)iteRootLos.next();
					
					// ログインユーザがルート以外で、自分自身のログ参照以外の場合、
					// ログインユーザに管理権限のあるLOかどうかチェック
					if (loginID.equals("PE000000") == false && loginID.equals(targetUserID) == false) {
						if ( this.containsLoData(loData,rootLOsOfLoginUser ) == false ) continue;
					}

					// コンテナの場合
					if ( loData.getLoType().equals("0") ){
						progress = new ContainerProgress( loData.getLoID(), 
															targetUserID, 
															level, 
															super.getConfigManager() );
							
						// LOの子供LOを取得
						LoRelationClient loRelation = new LoRelationClient();
						List childLoIDs = loRelation.getLoIds( loData.getLoID() );
						Iterator ite = childLoIDs.iterator();
						
						// 階層をカウントアップ
						int childLolevel = level + 1 ;
						
						// 検索結果
						while( ite.hasNext() ) {
							XMOProgress childProgress = 
								this.createProgressTree( ite.next().toString(),
															targetUserID, 
															loginID,
															childLolevel);
							progress.add( childProgress );
						}
							
					// LOの場合
					} else {
						progress = new LOProgress( loData.getLoID(), targetUserID, level, super.getConfigManager() );
					}
					
					rootProgress.add(progress);
				}
			}
			
		// LOが指定されたとき
		} else {
		
			LoClient parentLO = XMOInformationGetter.getLO( parentID );
			
			// 親LOがLOかコンテナかを判定し、ルートXMOProgressを作成
			// コンテナの場合
			if ( parentLO.getLoType().equals("0") ){
	
				rootProgress = new ContainerProgress( parentID, targetUserID, level, super.getConfigManager() );
				
				// 階層レベルをカウントアップ
				level++;
				
				// LOの子供LOを取得
				LoRelationClient loRelation = new LoRelationClient();
				List childLoIDs = loRelation.getLoIds( parentID );
				Iterator ite = childLoIDs.iterator();
				
				// 検索結果
				while( ite.hasNext() ) {
					XMOProgress xmoProgress = 
							this.createProgressTree( ite.next().toString(), 
														targetUserID, 
														loginID,
														level );
					rootProgress.add( xmoProgress );
				}
				
			// コンテナ以外の場合
			}else{
				
				rootProgress = new LOProgress( parentID, targetUserID, level, super.getConfigManager() );
			}
		}
		
		return rootProgress;
	}
	
	/**
	 * 指定されたLOデータが指定されたLo情報のリストに含まれるかを判別します。
	 * 
	 * @param loData Loのデータ
	 * @param targetList Lo情報のリスト
	 * @return boolean Loリストに含まれるか True:含まれる
	 */
	private boolean containsLoData(LoData loData, List targetList) {
		Iterator ite = targetList.iterator();
		while(ite.hasNext()){
			if ( ((LoData)ite.next()).getLoID().equals(loData.getLoID()) ) return true;
		}
		return false;
	}
}
