/////////////////////////////////////////////////////////////////
//Copyright (C) 2005 NTT CORPORATION.
//
//	ユーザ進捗の階層構造を構築するクラス
//
//		変更履歴
//			2005.01.27  新規作成  Katsuhiko.Sakurai(UNITEC)
//
//	機能
//
//	このクラスはユーザ進捗の階層構造を構築するクラスです。
//
////////////////////////////////////////////////////////////////
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.Assignments.AssignmentsClient;
import jp.co.ntt.lms.xmo.GroupAndPeople.GroupAndPeopleClient;
import jp.co.ntt.lms.xmo.Groups.GroupsData;
import jp.co.ntt.lms.xmo.LoRelation.LoRelationClient;

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

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

	/**
	 * Lo進捗階層構造を生成します。
	 * 
	 * @param parentID 	階層構造の親グループID
	 * @param targetLOID 対象となるLOのID
	 * @param loginUserID ログインユーザID
	 * @param level 階層レベル
	 * @return XMOProgress ユーザ進捗階層構造のルート
	 * @exception Exception
	 */
	protected XMOProgress createProgressTree( String parentID, String targetLOID, String loginUserID ,int level ) throws Exception {

		XMOProgress rootProgress = null;
		
		// ユーザがルートの場合
		if( /*loginUserID.equals("PE000000")==false && */  
				( parentID.equals("GR000000") || parentID.equals("grouptreeroot") ) ) {
			
			rootProgress = new GroupProgress( parentID, targetLOID, level, super.getConfigManager() );

			LoRelationClient relationClient = XMOInformationGetter.getLORelation(targetLOID);
			
			//指定LOにアサインされているユーザ情報を取得
			AssignmentsClient assignmentsClient = new AssignmentsClient();
			assignmentsClient.setWhereMaterialID( relationClient.getmaterialID() );
			if ( assignmentsClient.select() == false ) return rootProgress;
			
			// ログインユーザに管理アサインされているルートユーザ情報を取得
			List rootGroupList = XMOInformationGetter.getRootGroupIDList(loginUserID);
			
			// ログインユーザがルートユーザの場合、再度ルートユーザ情報を取得
			if (loginUserID.equals("PE000000")){
				rootGroupList = XMOInformationGetter.getChildGroupIDList((rootGroupList.get(0)).toString());
			}

			XMOProgress progress = null;
			while( assignmentsClient.next() ) {

				// 学習権限がないユーザなら処理なし
				if ( assignmentsClient.getLearnAuthority().equals("1") == false ) continue;
				
				String memberShipID = assignmentsClient.getMemberShipID();

				GroupAndPeopleClient groupAndPeople = this.getGroupAndPeopleFromMembershipID(memberShipID);
				String childID = groupAndPeople.getChildID();

				if (childID == null) continue;
				
				// ログインユーザに管理アサインされているルートユーザでなければ処理なし
				if (rootGroupList.contains(childID) == false ) continue;
				
				// グループの場合
				if (childID.startsWith("GR")) {
					
					progress = new GroupProgress( childID, targetLOID, level, super.getConfigManager() );
					
					// 子供のユーザを取得
					GroupAndPeopleClient childGroupAndPeopleClient = new GroupAndPeopleClient();
					childGroupAndPeopleClient.setWhereParentID(childID);
					if ( childGroupAndPeopleClient.select() == false ) continue;
					
					// 階層をカウントアップ
					int childUserlevel = level + 1 ;

					while(childGroupAndPeopleClient.next()) {
						XMOProgress childProgress = 
							this.createProgressTree( childGroupAndPeopleClient.getChildID(), 
														targetLOID, loginUserID, childUserlevel );
						progress.add( childProgress );
					}
					
				// ユーザの場合
				} else {
					progress = new PeopleProgress( childID, targetLOID, level, super.getConfigManager() );
				}
				
				rootProgress.add(progress);
			}

		} else {
			
			// 親IDがユーザかグループかを判定し、ルートXMOProgressを作成
			// グループの場合
			if ( parentID.startsWith( "GR" ) ){
	
				rootProgress = new GroupProgress( parentID, targetLOID, level, super.getConfigManager() );
	
				GroupAndPeopleClient groupAndPeople = new GroupAndPeopleClient();
				
				// 検索条件に親IDをセットする
				groupAndPeople.setWhereParentID( parentID );
				
				// 検索実施
				if ( groupAndPeople.select() == false ){
					throw new Exception();
				}
				
				// 階層レベルをカウントアップ
				level++;
				
				// 検索結果
				while( groupAndPeople.next() ) {
	
					XMOProgress xmoProgress = this.createProgressTree( groupAndPeople.getChildID(), targetLOID, loginUserID ,level );
					rootProgress.add( xmoProgress );
				}
				
			// ユーザの場合
			}else{
				
				rootProgress = new PeopleProgress( parentID, targetLOID, level, super.getConfigManager() );
			}
		}
		
		return rootProgress;
	}
	
	/**
	 * メンバーIDからグループ・ユーザ階層情報を取得します。
	 * 
	 * @param membershipID　メンバーID
	 * @return GroupAndPeopleClient グループ・ユーザ階層情報
	 * @throws Exception
	 */
	private GroupAndPeopleClient getGroupAndPeopleFromMembershipID(String membershipID) throws Exception {

		GroupAndPeopleClient groupAndPeopleClient = new GroupAndPeopleClient();
		groupAndPeopleClient.setMemberShipID( membershipID );
		
		if( groupAndPeopleClient.select() == false ) return null;
		if( groupAndPeopleClient.next() == false ) return null;
		
		return groupAndPeopleClient;
	}

	/**
	 * 指定されたグループIDが指定されたグループ情報のリストに含まれるかを判別します。
	 * 
	 * @param groupID グループID
	 * @param targetList グループ情報のリスト
	 * @return boolean グループリストに含まれるか True:含まれる
	 */
	private boolean containsGroupID(String groupID, List targetList) {
		Iterator ite = targetList.iterator();
		while(ite.hasNext()){
			GroupsData groupData = (GroupsData)ite.next();
			if ( groupData.getGroupID().equals(groupID) ) return true;
		}
		return false;
	}
}
