/***********************************************************************************
Attin3
Copyright (C)2003-2007 SATT, Inc. All Rights Reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE..  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

************************************************************************************
日本訳: （英文優先）

Attain3
Copyright (C)2003-2007 SATT, Inc. All Rights Reserved.

このライブラリはフリーソフトウェアです。あなたはこれを、フリーソフトウェ
ア財団によって発行されたGNU 劣等一般公衆利用許諾契約書(バージョン2.1 
か、希望によってはそれ以降のバージョンのうちどれか)の定める条件の下で
再頒布または改変することができます。


このライブラリは有用であることを願って頒布されますが、*全くの無保証* 
です。商業可能性の保証や特定の目的への適合性は、言外に示されたものも含
め全く存在しません。詳しくはGNU 劣等一般公衆利用許諾契約書をご覧くださ

い。


あなたはこのライブラリと共に、GNU 劣等一般公衆利用許諾契約書の複製物を

一部受け取ったはずです。もし受け取っていなければ、フリーソフトウェア財
団まで請求してください(宛先は the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA)。

***********************************************************************************/

/**
Attain3対応の為に追加分js(必須)
*/
/**
navi_org.js
ステータスに影響なくナビゲーションの有効無効をチェックする

GUI_Previous_Sequencing_Request_Process
GUI_Continue_Sequencing_Request_Process
GUI_Flow_Subprocess
GUI_Flow_Tree_Traversal_Subprocess
GUI_Flow_Activity_Traversal_Subprocess
GUI_Sequencing_Rule_Check_Process
GUI_Sequencing_Rule_Check_Subprocess
**/


/*********************************
*/
function GUI_Previous_Sequencing_Request_Process(){ // previousシーケンシング要求プロセス
    // p92
    // 配信する次のアクティビティを特定する(現在のアクティビティからツリーを後方に辿る)
    // カレントアクティビティとフローサブプロセスを使う



    // 配信候補アクティビティを返すか、配信アクティビティがないという識別子を返す

    // 1. Current Activityが定義されていない



    if(current_activity==undefined || current_activity==null){
 	return; // 1.1. 配信するものがない



    }
    // 2. Current Activityに対してフローサブプロセスを後方に子検討フラグFalseで適用
    var fs=GUI_Flow_Subprocess(current_activity,"back",false);
    if(fs.is_deliver==false){ // 3. フローサブプロセスがFalseを返す
 	return; // 3.1. 配信するものがない



    }else{ // 4. Else
 	return fs.activity; // 4.1. 配信要求はフローサブプロセスが特定したアクティビティ
    }
}





/*********************************
*/
function GUI_Continue_Sequencing_Request_Process(){ // continueシーケンシング要求プロセス
    // p91
    // 配信する次のアクティビティを特定する(現在のアクティビティからツリーを前方に辿る)
    // カレントアクティビティとフローサブプロセスを使う



    // 配信候補アクティビティを返すか、配信アクティビティがないという識別子を返す

    // 1. Current Activityが定義されていない



    if(current_activity==undefined || current_activity==null){
 	return; // 1.1. 配信するものがない



    }
    // 2. Current Activityに対してフローサブプロセスを前方に子検討フラグFalseで適用
    var fs=GUI_Flow_Subprocess(current_activity,"forward",false);
    if(fs.is_deliver==false){ // 3. フローサブプロセスがFalseを返す
 	return; // 3.1. 配信するものがない



    }else{ // 4. Else
 	return fs.activity; // 4.1. 配信要求はフローサブプロセスが特定したアクティビティ
    }
}





/*********************************
*/
function GUI_Flow_Subprocess(item,direction,child_check){ // フローサブプロセス
    // p86-87
    // アクティビティ、トラバース方向、子検討フラグに対し、移動が成功したか否か、



    // および移動が停止したアクティビティを返す

    var candidate=item;     // 1. アクティビティを候補アクティビティとする
    //    alert("candidate "+candidate.getAttribute("identifier"));

    // 2. 候補アクティビティに対してフローツリートラバーサルプロセスをトラバース方向に、



    // 直前トラバース方向n/a、子検討フラグで適用
    var ft=GUI_Flow_Tree_Traversal_Subprocess(candidate,direction,child_check,"");
    if(ft==undefined){ // 3. フローツリートラバーサルサブプロセスがアクティビティを特定しない



 	// 3.1. 特定されたアクティビティは候補アクティビティ、配信可否はFalse
 	return new struct(candidate,false);
    }else{ // 4.
 	// 4.1. フローツリートラバーサルサブプロセスが特定したアクティビティを候補アクティビティとする
 	candidate=ft;
 	// 4.2. 候補アクティビティに対してフローアクティビティトラバーサルサブプロセスを



 	// トラバーサル方向に、直前トラバース方向n/aで適用
 	// 4.3. 特定されたアクティビティはフローアクティビティトラバーサルサブプロセスが特定した



 	// アクティビティ、配信可否はフローアクティビティトラバーサルサブプロセスが特定した通り
 	//alert("candidate "+candidate.getAttribute("identifier"));
 	//alert("exiting soon "+ Flow_Activity_Traversal_Subprocess(candidate,direction,"").activity.getAttribute("identifier"));
 	return GUI_Flow_Activity_Traversal_Subprocess(candidate,direction,"");
    }
}





/*********************************
*/
function GUI_Flow_Tree_Traversal_Subprocess(item,direction,child_check,prev_direction){ 
    // フローツリートラバーサルサブプロセス
    // p81-83 指定されたアクティビティから前方または後方にツリーを辿り、次のアクティビティを



    // 特定する。最後もしくは最初を越えるトラバーサルは例外である
  
    // 1. アクティビティがアクティビティツリーのルートではないなら



    if(item.nodeName!="organization"){
 	var children=item.parentNode.childNodes;
 	var cm; // controlMode
 	for(var c=0;c<children.length;c++){
 	    if(children[c].nodeName=="imsss:sequencing"){
 		cm=My_getElementsByTagName(children[c],"imsss:controlMode");
 		break;
 	    }
 	}
 	// 1.1. 親のシーケンシングコントロールFlowがFalseなら



 	if((cm==undefined || cm==null) || cm.length==0 || cm[0].getAttribute("flow")=="false"){ 
 	    //alert("parent flow false");
 	    return undefined; // 1.1.1. Exit フローツリートラバーサルサブプロセス
 	} // End If
    } // End If

    // 2. 直前トラバース方向が定義され And
    // 直前トラバース方向が後方 And
    // アクティビティがアクティビティの親のAvailable Childrenのリストの最後のアクティビティ
    if((prev_direction!=undefined&&prev_direction!=null) && 
       prev_direction=="back" && 
       item==Available_Children(item.parentNode).pop()){

 	direction = "back"; // 2.1. トラバース方向は後方
 	// 2.2. アクティビティはアクティビティの親のAvailable Childrenのリストの最初のアクティビティ
 	item=Available_Children(item.parentNode)[0];
    } // End If

    if(direction=="forward"){ // 3. トラバース方向が前方なら



 	if(item==items[items.length-1]){ // 3.1. アクティビティがアクティビティツリーの前方順序付ツリートラバーサルの最後のアクティビティ
 	    return undefined; // 3.1.1. 
 	} // End If
 	if(item.getElementsByTagName("item").length==0||
 	   child_check==false){ // 3.2. アクティビティが葉 Or 子検討フラグがFalseなら



 	    // 3.2.1. アクティビティがアクティビティの親のAvailable Childrenリストの
 	    // 最後のアクティビティなら



 	    if(item==Available_Children(item.parentNode).pop()){ 
 		// 3.2.1.1. フローツリートラバーサルプロセスをアクティビティの親に対して
 		// トラバース方向前方、直前トラバース方向n/a、子検討フラグFalseで適用
 		var rec=GUI_Flow_Tree_Traversal_Subprocess(item.parentNode,"forward",false,"");
 		return rec; // 3.2.1.2. 再帰の結果を返す
 	    }else{ // 3.2.2.
 		// 3.2.2.1. アクティビティに対してStopForwardTraversalシーケンシングルールに関してシーケンシングルールチェックプロセスを適用する
 		if(GUI_Sequencing_Rule_Check_Process(item,new Array("StopForwardTraversal"))!=undefined){ // 3.2.2.2. // シーケンシングルールチェックプロセスがNilを返さない



 		    return undefined;// 3.2.2.2.1.
 		} // End If
 		// 3.2.2.3. ツリーを前方に、アクティビティの親のAvailable Childrenリスト中を



 		// 次アクティビティに一つ辿る



 		var parent_child_array=Available_Children(item.parentNode);
 		var p;
 		for(p=0;p<parent_child_array.length;p++){
 		    if(item==parent_child_array[p]){
 			break;
 		    }
 		}
 		var next=parent_child_array[p+1];
 		//alert("next "+(p+1)+" "+next.getAttribute("identifier"));
 		return next; // 3.2.2.4. 次アクティビティはトラバーサルで特定されたアクティビティ
 	    } // End If
 	}else{ // 3.3.
 	    // 3.3.1. 次アクティビティはアクティビティのAvailable Childrenリスト中の
 	    // 最初のアクティビティ
 	    return Available_Children(item)[0]; 
 	} // End If
    } // End If(トラバース方向が前方)

    if(direction=="back"){ // 4. トラバース方向が後方
 	// 4.1. アクティビティがアクティビティツリーのルートなら



 	if(item.nodeName=="organization"){ 
 	    return undefined; // 4.1.1.
 	}
 	if(item.getElementsByTagName("item").length==0||
 	   child_check==false){ // 4.2. アクティビティが葉 Or 子検討フラグがFalse
 	    // 4.2.1. アクティビティがアクティビティの親のAvailable Childrenリストの
 	    // 最初のアクティビティなら



 	    if(item==Available_Children(item.parentNode)[0]){ 
 		// 4.2.1.1. フローツリートラバーサルサブプロセスをアクティビティの親に対して
 		// トラバース方向後方、直前トラバース方向n/a、子検討フラグFalseで適用
 		var rec=GUI_Flow_Tree_Traversal_Subprocess(item.parentNode,"back",false,"");
 		return rec; // 4.2.1.2. 再帰の結果を返す
 	    }else{ // 4.2.2. 
 		var children=item.parentNode.childNodes; // 親の子供たち
 		var cm; // controlMode
 		for(var c=0;c<children.length;c++){
 		    if(children[c].nodeName=="imsss:sequencing"){
 			cm=My_getElementsByTagName(children[c],"imsss:controlMode");
 			break;
 		    }
 		}
 		// 4.2.2.1. アクティビティの親のシーケンシングコントロールForwardOnlyがTrue
 		if(cm!=undefined && cm!=null && cm[0].getAttribute("forwardOnly")=="true"){ 
 		    return undefined; // 4.2.2.1.1. 次アクティビティはNil
 		}		
 		// 4.2.2.2. ツリーを後方に、アクティビティの親のAvailable Childrenリスト中を



 		// 前アクティビティに一つ辿る



 		var parent_child_array=Available_Children(item.parentNode);
 		var p;
 		for(p=0;p<parent_child_array.length;p++){
 		    if(item==parent_child_array[p]){
 			break;
 		    }
 		}
 		var prev=parent_child_array[p-1];
 		//alert("prev "+prev.getAttribute("identifier"));
 		return prev; // 4.2.2.3. 次アクティビティはトラバーサルで特定されたアクティビティ
 	    }
 	}else{ // 4.3. 
 	    var children=item.parentNode.childNodes; // 親の子供たち
 	    var cm; // controlMode
 	    for(var c=0;c<children.length;c++){
 		if(children[c].nodeName=="imsss:sequencing"){
 		    cm=My_getElementsByTagName(children[c],"imsss:controlMode");
 		    break;
 		}
 	    }
 	    // 4.3.1. アクティビティの親のシーケンシングコントロールForwardOnlyがTrue または
 	    // アクティビティがアクティビティツリーのルートなら



 	    if(cm!=undefined && cm!=null && cm[0].getAttribute("forwardOnly")=="true" ||
 	       item.nodeName=="organization"){ 
 		// 4.3.1.1. 次アクティビティはアクティビティのAvailable Childrenリスト中の
 		// 最初のアクティビティ
 		return Available_Children(item)[0];
 	    }else{ // 4.3.2.
 		// 4.3.2.1. 次アクティビティはアクティビティのAvailable Childrenリスト中の
 		// 最後のアクティビティ
 		return Available_Children(item).pop();
 	    } // End If
 	} // End If
    } // End If
    return undefined; // 5. 次アクティビティはNil
}





/**
*/
function GUI_Flow_Activity_Traversal_Subprocess(item,direction,prev_direction){ 
    // フローアクティビティトラバーサルサブプロセス
    // p84-85 アクティビティ、トラバース方向、直前トラバース方向に対し、アクティビティツリー中の
    // 指定のトラバース方向の次のアクティビティおよびアクティビティが配信可能な場合にTrueを返す
    // (構造体風の入れ物で)
    var children=item.parentNode.childNodes;  // 親の子供たち
    var cm; // controlMode
    var fat; // フローアクティビティトラバーサルサブプロセス再帰呼出しの値
    for(var c=0;c<children.length;c++){
 	if(children[c].nodeName=="imsss:sequencing"){
 	    cm=My_getElementsByTagName(children[c],"imsss:controlMode");
 	    break;
 	}
    }
    // 1. 親のシーケンシングコントロールFlowがFalseなら



    if(cm==undefined || cm==null || cm[0].getAttribute("flow")=="false"){ 
 	return new struct(item,false); // 1.1. 配信可能はFalse
	//return new struct(item,true); // 1.1. 配信可能はFalse
    } // End If

    // 2. skipシーケンシングルールに関してシーケンシングルールチェックプロセスを適用する
    // 3.シーケンシングルールチェックプロセスがNilを返さない    
    if(GUI_Sequencing_Rule_Check_Process(item,new Array("skip"))!=undefined){ 
 	// 3.1. アクティビティに対してフローツリートラバーサルサブプロセスをトラバース方向および
 	// 直前トラバース方向に子検討フラグFalseで適用
 	var ft=GUI_Flow_Tree_Traversal_Subprocess(item,direction,false,prev_direction);
 	// 3.2. フローツリートラバーサルサブプロセスがアクティビティを特定しないなら



 	if(ft==undefined){
 	    return new struct(item,false); // 3.2.1. 配信可能はFalse
 	}else{ // 3.3.
 	    // 3.3.1. フローツリートラバーサルサブプロセスが特定したアクティビティに対して
 	    // フローアクティビティトラバーサルサブプロセスをトラバース方向に
 	    // 直前トラバース方向n/aで適用
 	    // 3.3.2. 再帰フローアクティビティトラバーサルサブプロセスの結果を返す
 	    return GUI_Flow_Activity_Traversal_Subprocess(ft,direction,"");
 	}
    }
    // 4. アクティビティにチェックアクティビティプロセスを適用する
    // 5. チェックアクティビティプロセスがTrueを返すなら



    if(Check_Activity_Process(item)){
 	return new struct(item,false); // 5.1. 配信可能はFalse
    }
    // 6. アクティビティがアクティビティツリーの葉でない



    if(item.getElementsByTagName("item").length>0){
 	//alert("not leaf "+item.getAttribute("identifier"));
 	// 6.1. アクティビティに対してフローツリートラバーサルサブプロセスをトラバース方向に
 	// 直前トラバース方向n/a、子検討フラグTrueで適用
 	var ft=GUI_Flow_Tree_Traversal_Subprocess(item,direction,true,"");
 	if(ft==undefined){ // 6.2. フローツリートラバーサルサブプロセスがアクティビティを特定しない



 	    return new struct(item,false); // 6.2.1. 配信可能はFalse
 	}else{ // 6.3.
 	    var ft_parent_children=ft.parentNode.childNodes; // 特定されたアクティビティの親の子供たち
 	    var cm_parent_children; // controlMode
 	    for(var c=0;c<ft_parent_children.length;c++){
 		if(ft_parent_children[c].nodeName=="imsss:sequencing"){
 		    cm_parent_children
 			=My_getElementsByTagName(ft_parent_children[c],"imsss:controlMode");
 		    break;
 		}
 	    }
 	    // 6.3.1. フローツリートラバーサルプロセスで特定されたアクティビティの親アクティビティの
 	    // シーケンシングコントロールForwardOnlyがTrue And トラバース方向が後方
 	    if(cm_parent_children!=undefined && cm_parent_children!=null && 
 	       cm_parent_children[0].getAttribute("forwardOnly")=="true" &&
 	       direction=="back"){
 		// 6.3.1.1. フローツリートラバーサルプロセスで特定されたアクティビティに対し



 		// フローアクティビティトラバーサルサブプロセスをトラバース方向前方、



 		// 直前トラバース方向後方で適用
 		fat = GUI_Flow_Activity_Traversal_Subprocess(ft,"forward","back");
 		item=fat.activity;
 	    }else{ // 6.3.2.
 		// 6.3.2.1. フローツリートラバーサルプロセスで特定されたアクティビティに対し



 		// フローアクティビティトラバーサルサブプロセスをトラバース方向に、



 		// 直前トラバーサル方向n/aで適用
 		fat=GUI_Flow_Activity_Traversal_Subprocess(ft,direction,"");
 		item=fat.activity;
 	    }
 	}
    }
    return new struct(item,true); // 配信可能はTrue
}





/**
*/
function GUI_Sequencing_Rule_Check_Process(item, ruleActions){ // シーケンシングルールチェックプロセス
    // p114 アクティビティ(item)とルールアクションの集合(ruleActions)を受け取り、



    // Trueと評価された最初のシーケンシングルールのルール動作を帰すか、Nilを返す
    // 1.1. アクティビティに対していずれかのルールアクションを有するシーケンシングルールの
    // 集合を、元のルールの順序を保ちながら選択し、ルールリストを初期化



    var ruleList_Array = new Array();
    var sequencingRules = My_getElementsByTagName(item,"imsss:ruleAction");
    for(var a=0;a<ruleActions.length;a++){ // ルールアクションの集合を舐める
 	for(var r=0;r<sequencingRules.length;r++){
 	    if(sequencingRules[r].getAttribute("action")==ruleActions[a] &&
 	       sequencingRules[r].parentNode.parentNode.parentNode.parentNode==item){
 		ruleList_Array.push(sequencingRules[r].parentNode);
 	    }
 	}
    }
    if(ruleList_Array.length!=0){
 	// 1. アクティビティが指定されたいずれかのルールアクションを持つシーケンシングルールを含むなら



 	for(var r=0;r<ruleList_Array.length;r++){ // 1.2. ルールリストの各ルール
 	    //alert("ruleAction "+ruleList_Array[r].nodeName);
 	    // 1.2.1. アクティビティとルールに対しシーケンシングルールチェックサブプロセスを適用
 	    if(GUI_Sequencing_Rule_Check_Subprocess(item, ruleList_Array[r])==true){
 		// 1.2.2. シーケンシングルールチェックサブプロセスがTrueを返すなら



 		// Trueと評価される最初のルール(ルール動作)を返す
 		return My_getElementsByTagName(ruleList_Array[r],"imsss:ruleAction")[0].getAttribute("action");
 	    } // End If
 	} // End For
    } // End If
    //alert("no rule");
    return undefined; // 2. Trueとして評価するルールがない



}





/**
*/
function GUI_Sequencing_Rule_Check_Subprocess(item, rule){
	
	//alert("GUI_Sequencing_Rule_Check_Subprocess:" + id(item) + ":" + rule);
	
    //alert("SeqRule Subprocess Checking " + item.getAttribute("identifier") + " " +rule.nodeName);
    // p115 シーケンシングルールチェックサブプロセス
    // アクティビティ(item)にシーケンシングルール(rule)を適用し、TrueかFalseを返す
    // ルールはpreCondition, postCondition, exitConditionのどれでもよい



    // ルールのオブジェクトさえあればitemは特定できるので、引数itemは実は使っていない




    // (番外編)ここでmapInfoを見ておく!
    // targetObjectiveIDで得られる学習目標の値をobjectiveIDの値としてコピー
    var seq=rule.parentNode.parentNode; // "imsss:sequencing"    
    var item_all_objectives = new Array(); // その(ルールがある)アイテムの全ての学習目標



    // 主学習目標は連想配列から取り出す



    item_all_objectives.push(item_primary_objectives[id(item)]);
    // 主でない学習目標はmanifestから読む
    //var obj = My_getElementsByTagName(seq,"imsss:objective");
    // 主でない学習目標も連想配列から読む
    var objs = item_objectives[id(item)];
    if(objs != undefined && objs != null){
 	//if(obj[0] != undefined && obj[0] != null){
 	for(var o=0;o<objs.length;o++){
 	    item_all_objectives.push(objs[o]);
 	}
    }
    
    /*
    for(var ob=0;ob<item_all_objectives.length;ob++){ // mapInfoを見に行く
	 	var maps = My_getElementsByTagName(item_all_objectives[ob],"imsss:mapInfo");
	 	if(maps!=undefined){  // mapInfoがない場合、My_getElementsByTagNameはundefinedを返してくる
	 	    if(maps.length>0){
		 		for(var mp=0;mp<maps.length;mp++){
		 		    if(maps[mp].getAttribute("readSatisfiedStatus")=="true"){ // 文字列としての"true"なので注意			
						objective_progress_status[id(item)][obj_id(item_all_objectives[ob])]=
			 			    objective_progress_status_global[obj_id(maps[mp])];
			 			objective_satisfied_status[id(item)][obj_id(item_all_objectives[ob])]=
			 			    objective_satisfied_status_global[obj_id(maps[mp])]; 			
		 		    }
		 		    if(maps[mp].getAttribute("readNormalizedMeasure")=="true"){ // 文字列としての"true"なので注意


			 			objective_measure_status[id(item)][obj_id(item_all_objectives[ob])]=
			 			    objective_measure_status_global[obj_id(maps[mp])];
			 			objective_normalized_measure[id(item)][obj_id(item_all_objectives[ob])]=
			 			    objective_normalized_measure_global[obj_id(maps[mp])];
		 		    }
		 		}
	 	    }
	 	}
    }
    */
    
    var rulesArray = new Array(); // 1. ルール条件集合を空に初期化



    //    var ruleCondition_array = rule.getElementsByTagName('ruleCondition');
    var ruleCondition_array = My_getElementsByTagName(rule,'imsss:ruleCondition');
    for(var i=0;i<ruleCondition_array.length;i++){ // 2. 各Rule Condition
 	var eval_result=false; // 評価結果
 	// 2.1. ここでトラッキング情報を見て条件を評価する!
 	var referencedObjective=ruleCondition_array[i].getAttribute("referencedObjective");
 	var condition = ruleCondition_array[i].getAttribute("condition");

 	// referencedObjectiveがなかったら主学習目標を使う



 	if(referencedObjective==undefined || referencedObjective==null){
 	    referencedObjective=obj_id(item_primary_objectives[id(item)]);
 	}
 	if(condition == "satisfied"){
 	    if(objective_progress_status[id(item)][referencedObjective]==true &&
 	       objective_satisfied_status[id(item)][referencedObjective]==true){
 		eval_result=true;
 	    }
 	}else if(condition == "objectiveStatusKnown"){
 	    if(objective_progress_status[id(item)][referencedObjective]==true){
 		eval_result=true;
 	    }
 	}else if(condition == "objectiveMeasureKnown"){
 	    if(objective_progress_status[id(item)][referencedObjective]==true &&
 	       objective_measure_status[id(item)][referencedObjective]==true){
 		eval_result=true;
 	    }
 	}else if(condition == "objectiveMeasureGreaterThan"){
 	}else if(condition == "objectiveMeasureLessThan"){
 	}else if(condition == "completed"){
 	    if(attempt_progress_status[id(item)]==true &&
 	       attempt_completion_status[id(item)]==true){
 		eval_result=true;
 	    }
 	}else if(condition == "activityProgressKnown"){
 	    if(activity_progress_status[id(item)]==true &&
 	       attempt_progress_status[id(item)]==true){
 		eval_result=true;
 	    }	    
 	}else if(condition == "attempted"){
 	    if(activity_progress_status[id(item)]==true &&
 	       activity_attempt_count[id(item)]>0){
 		eval_result=true;
 	    }	    
 	}else if(condition == "attemptLimitExceeded"){
 	}else if(condition == "timeLimitExceeded"){
 	}else if(condition == "outsideAvailableTimeRange"){
 	}else if(condition == "always"){
 	    eval_result=true;
 	}
 	if(ruleCondition_array[i].getAttribute("operator")=="not"){ // 2.2. OperatorがNotなら



 	    //	    alert(ruleCondition_array[i].getAttribute("operator"));
 	    eval_result=!(eval_result);   // 2.2.1. Negate ルール条件
 	}
 	//	alert(eval_result);
 	rulesArray.push(eval_result); // 2.3. ルール条件の値をルール条件集合に追加
    } // End For
    if(rulesArray.length==0){ // 3. ルール条件集合が空
 	return false;         // 3.1. Falseを返して終了



    }
    var ruleConditions = My_getElementsByTagName(rule,'imsss:ruleConditions')[0];
    if(ruleConditions != undefined && ruleConditions != null){
 	var conditionCombination = ruleConditions.getAttribute("conditionCombination");
 	// 4. Combinationをルール条件集合に適用して、単一のルール評価を得る
 	var rules_true=0; // 条件を満たしたルールの数
 	for(var r=0;r<rulesArray.length;r++){rules_true += rulesArray[r];}
 	if(conditionCombination == "all"){ // And演算



 	    if(rules_true == rulesArray.length){
 		//alert(item.getAttribute("identifier") + " true");
 		return true;
 	    }else{
 		return false;
 	    }
 	}else{ // Anyか空の時、Or演算



 	    if(rules_true > 0){
 		//alert(item.getAttribute("identifier") + " true");
 		return true; // 一つでも満たしていたらtrue
 	    }else{
 		return false;// 全部ダメならfalse
 	    }
 	}
    }
    return false; // 万一ruleConditionsがなかったら…(仕様上は、ない場合もありうる)
}

/*************
追加
objectiveをDBに格納する前に反映するため
*/
function AddEnd_Attempt_Process(item){ // 試行終了プロセス
    //p117-118 コンテンツオブジェクトが値を設定しないときに使う値を規定する



    // 値は返さない



    //alert("End_Attempt " +id(item));
    if(item.getElementsByTagName("item").length==0){ // 1. アクティビティが葉なら



 	if(tracked[id(item)]==true){ // 1.1. アクティビティのTrackedがTrueなら



 	    // 1.1.1. アクティビティのActivity is SuspendedがFalseなら



 	    if(activity_is_suspended[id(item)]==false){ 
 		// 1.1.1.1. アクティビティのCompletion Set by ContentがFalseなら



 		if(completion_set_by_content[id(item)]==false){ 
 		    // 1.1.1.1.1. アクティビティのAttempt Progress StatusがFalseなら



 		    if(attempt_progress_status[id(item)]==false){ 
 			// 1.1.1.1.1.1. アクティビティのAttempt Progress StatusをTrueに設定



 			attempt_progress_status[id(item)]=true;
 			// 1.1.1.1.1.2. アクティビティのAttempt Completion StatusをTrueに設定



 			attempt_completion_status[id(item)]=true;
 		    }
 		}
 		// 1.1.1.2. アクティビティのObjective Set by ContentがFalseなら



 		//alert(id(item) +" " + objective_set_by_content[id(item)]);
 		if(objective_set_by_content[id(item)]==false){ 
 		    var item_all_objectives = new Array();
 		    var seq; // "imsss:sequencing"
 		    var children=item.childNodes;
 		    for(var c=0;c<children.length;c++){
 			if(children[c].nodeName=="imsss:sequencing"){
 			    seq=children[c];
 			    break;
 			}
 		    }
 		    //var pobj = My_getElementsByTagName(seq,"imsss:primaryObjective");
 		    //if(pobj!=undefined && pobj!=null){
 		    //if(pobj[0] != undefined && pobj[0] != null){
 		    //item_all_objectives.push(pobj[0]);
 		    //}
 		    //}
 		    // 主学習目標は連想配列から
 		    item_all_objectives.push(item_primary_objectives[id(item)]);

 		    // 主でない学習目標はmanifestから
 		    //var objs = My_getElementsByTagName(seq,"imsss:objective");
 		    // 主でない学習目標も連想配列から読む
 		    var objs = item_objectives[id(item)];
 		    if(objs!=undefined && objs!=null){
 			//if(obj[0] != undefined && obj[0] != null){
 			for(var o=0;o<objs.length;o++){
 			    item_all_objectives.push(objs[o]);
 			}
 		    }
 		    // 1.1.1.2.1. アクティビティに関する全学習目標について
 		    //alert("ac_oblen "+item_all_objectives.length);
 		    for(var ob=0;ob<item_all_objectives.length;ob++){ 
 			// 1.1.1.2.1.1. 学習目標のObjective Contributes to RollupがTrueなら



 			if(objective_contributes_to_rollup[id(item)][obj_id(item_all_objectives[ob])]==true){ 
 			    // 1.1.1.2.1.1.1. 学習目標のObjective Progress StatusがFalseなら



 			    //alert("prog_sta "+objective_progress_status[id(item)][obj_id(item_all_objectives[ob])]);

 			    if(objective_progress_status[id(item)][obj_id(item_all_objectives[ob])]==false){ 
 				// 1.1.1.2.1.1.1.1. 学習目標のObjective Progress StatusをTrueに設定



 				objective_progress_status[id(item)][obj_id(item_all_objectives[ob])]=true;
				//alert("hoge");
 				// 1.1.1.2.1.1.1.2. 学習目標のObjective Satisfied StatusをTrueに設定



 				objective_satisfied_status[id(item)][obj_id(item_all_objectives[ob])]=true;
 				//alert("geho");
				//alert(obj_id(item_all_objectives[ob])+":"+objective_satisfied_status[id(item)][obj_id(item_all_objectives[ob])]);
 			    }
 			}
 		    }
 		}
 	    }
 	}
    }else{
    	/*
    	// 2. Else(アクティビティが葉でない)
	 	var item_children = Available_Children(item); // 子アクティビティのリスト


	 	var has_suspended_child = 0; // 「Activity is Suspended属性がTrueの子アクティビティ」の数
	 	for (var ic=0;ic<item_children.length;ic++){
	 	    //alert("item_child "+id(item_children[ic]));
	 	    if(activity_is_suspended[id(item_children[ic])]==true){
	 		has_suspended_child++;
	 	    }
	 	}
	 	// 2.1. アクティビティが「Activity is Suspended属性がTrueの子アクティビティ」を持つなら


	 	if(has_suspended_child>0){ 
	 	    // 2.1.1. アクティビティのActivity is SuspendedをTrueに設定


	 	    activity_is_suspended[id(item)]=true;
	 	}else{ // 2.2. 
	 	    // 2.2.1. アクティビティのActivity is SuspendedをFalseに設定


	 	    activity_is_suspended[id(item)]=false;
	 	}
	 	*/
    }
    // 3. アクティビティのActivity is ActiveをFalseに設定


    //activity_is_active[id(item)]=false;
    // 4. 試行終了プロセスの終了



}
