--- loncom/xml/lonxml.pm	2007/09/10 19:46:57	1.456
+++ loncom/xml/lonxml.pm	2007/11/13 22:16:10	1.469
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # XML Parser Module 
 #
-# $Id: lonxml.pm,v 1.456 2007/09/10 19:46:57 albertel Exp $
+# $Id: lonxml.pm,v 1.469 2007/11/13 22:16:10 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -92,8 +92,10 @@ use Apache::loncacc();
 use Apache::lonmaxima();
 use Apache::lonlocal;
 
-#==================================================   Main subroutine: xmlparse  
+#====================================   Main subroutine: xmlparse  
+
 #debugging control, to turn on debugging modify the correct handler
+
 $Apache::lonxml::debug=0;
 
 # keeps count of the number of warnings and errors generated in a parse
@@ -135,6 +137,16 @@ $Apache::lonxml::request='';
 $Apache::lonxml::counter=1;
 $Apache::lonxml::counter_changed=0;
 
+# Part counter hash.   In analysis mode, the
+# problems can use this to record which parts increment the counter
+# by how much.  The counter subs will maintain this hash via
+# their optional part parameters.  Note that the assumption is that
+# analysis is done in one request and therefore it is not necessary to
+# save this information request-to-request.
+
+
+%Apache::lonxml::counters_per_part = ();
+
 #internal check on whether to look at style defs
 $Apache::lonxml::usestyle=1;
 
@@ -365,7 +377,7 @@ sub xmlparse {
      $finaloutput .= join('',@script_var_displays);
      undef(@script_var_displays);
  }
-
+ &init_state();
  if ($env{'form.return_only_error_and_warning_counts'}) {
      return "$errorcount:$warningcount";
  }
@@ -619,6 +631,24 @@ sub callsub {
   return $currentstring;
 }
 
+{
+    my %state;
+
+    sub init_state {
+	undef(%state);
+    }
+    
+    sub set_state {
+	my ($key,$value) = @_;
+	$state{$key} = $value;
+	return $value;
+    }
+    sub get_state {
+	my ($key) = @_;
+	return $state{$key};
+    }
+}
+
 sub setup_globals {
   my ($request,$target)=@_;
   $Apache::lonxml::request=$request;
@@ -627,6 +657,9 @@ sub setup_globals {
   $Apache::lonxml::default_homework_loaded=0;
   $Apache::lonxml::usestyle=1;
   &init_counter();
+  &clear_bubble_lines_for_part();
+  &init_state();
+  &set_state('target',$target);
   @Apache::lonxml::pwd=();
   @Apache::lonxml::extlinks=();
   @script_var_displays=();
@@ -800,6 +833,7 @@ sub init_safespace {
   $safehole->wrap(\&Math::Random::random_set_seed_from_phrase,$safeeval,'&random_set_seed_from_phrase');
   $safehole->wrap(\&Math::Random::random_get_seed,$safeeval,'&random_get_seed');
   $safehole->wrap(\&Math::Random::random_set_seed,$safeeval,'&random_set_seed');
+  $safehole->wrap(\&Apache::loncommon::languages,$safeeval,'&languages');
   $safehole->wrap(\&Apache::lonxml::error,$safeeval,'&LONCAPA_INTERNAL_ERROR');
   $safehole->wrap(\&Apache::lonxml::debug,$safeeval,'&LONCAPA_INTERNAL_DEBUG');
   $safehole->wrap(\&Apache::lonnet::logthis,$safeeval,'&LONCAPA_INTERNAL_LOGTHIS');
@@ -908,6 +942,9 @@ sub endredirection {
     }
     pop @Apache::lonxml::outputstack;
 }
+sub in_redirection {
+    return ($Apache::lonxml::redirection > 0)
+}
 
 sub end_tag {
   my ($tagstack,$parstack,$token)=@_;
@@ -1005,8 +1042,15 @@ sub get_all_text_unbalanced {
 	}
     }
     return $result
+
 }
 
+#########################################################################
+#                                                                       #
+#           bubble line counter management                              #
+#                                                                       #
+#########################################################################
+
 =pod
 
 For bubble grading mode and exam bubble printing mode, the tracking of
@@ -1022,16 +1066,31 @@ Increments the internal counter environm
 
 Optional Arguments:
   $increment - amount to increment by (defaults to 1)
+               Also 1 if the value is negative or zero.
+  $part_response - A concatenation of the part and response id
+                   identifying exactly what is being 'answered'.
+
 
 =cut
 
 sub increment_counter {
-    my ($increment) = @_;
-    if (defined($increment) && $increment gt 0) {
-	$Apache::lonxml::counter+=$increment;
-    } else {
-	$Apache::lonxml::counter++;
+    my ($increment, $part_response) = @_;
+    if (!defined($increment) || $increment le 0) {
+	$increment = 1;
+    }
+    $Apache::lonxml::counter += $increment;
+
+    # If the caller supplied the response_id parameter, 
+    # Maintain its counter.. creating if necessary.
+
+    if(defined($part_response)) {
+	if (!defined($Apache::lonxml::counters_per_part{$part_response})) {
+	    $Apache::lonxml::counters_per_part{$part_response} = 0;
+	}
+	$Apache::lonxml::counters_per_part{$part_response} += $increment;
+	my $new_value = $Apache::lonxml::counters_per_part{$part_response};
     }
+	
     $Apache::lonxml::counter_changed=1;
 }
 
@@ -1088,6 +1147,74 @@ sub store_counter {
     }
 }
 
+=pod
+
+=item  bubble_lines_for_part(part_response)
+
+Returns the number of lines required to get a response for
+$part_response (this is just $Apache::lonxml::counters_per_part{$part_response}
+
+=cut
+
+sub bubble_lines_for_part {
+    my ($part_response) = @_;
+
+    if (!defined($Apache::lonxml::counters_per_part{$part_response})) {
+	return 0;
+    } else {
+	return $Apache::lonxml::counters_per_part{$part_response};
+    }
+
+}
+
+=pod
+
+=item clear_bubble_lines_for_part
+
+Clears the hash of bubble lines per part.  If a caller
+needs to analyze several resources this should be called between
+resources to reset the hash for each problem being analyzed.
+
+=cut
+
+sub clear_bubble_lines_for_part {
+    undef(%Apache::lonxml::counters_per_part);
+}
+
+=pod
+
+=item set_bubble_lines(part_response, value)
+
+If there is a problem part, that for whatever reason
+requires bubble lines that are not
+the same as the counter increment, it can call this sub during
+analysis to set its hash value explicitly.
+
+=cut
+
+sub set_bubble_lines {
+    my ($part_response, $value) = @_;
+
+    $Apache::lonxml::counters_per_part{$part_response} = $value;
+}
+
+=pod
+
+=item get_bubble_line_hash
+
+Returns the current bubble line hash.  This is assumed to 
+be small so we return a copy
+
+
+=cut
+
+sub get_bubble_line_hash {
+    return %Apache::lonxml::counters_per_part;
+}
+
+
+#--------------------------------------------------
+
 sub get_all_text {
     my($tag,$pars,$style)= @_;
     my $gotfullstack=1;
@@ -1357,36 +1484,37 @@ sub inserteditinfo {
       my $initialize='';
       my $textarea_id = 'filecont';
       my ($add_to_onload, $add_to_onresize);
-      my $addbuttons=&Apache::lonhtmlcommon::htmlareaaddbuttons();
       $initialize=&Apache::lonhtmlcommon::spellheader();
       if ($filetype eq 'html' 
 	  && (!&Apache::lonhtmlcommon::htmlareablocked() &&
 	      &Apache::lonhtmlcommon::htmlareabrowser())) {
-	  $textarea_id .= '_htmlarea';
+	  $textarea_id .= '___Frame';
+	  my $lang = &Apache::lonhtmlcommon::htmlarea_lang();
 	  $initialize.=(<<FULLPAGE);
 <script type="text/javascript">
-$addbuttons
-
-    HTMLArea.loadPlugin("FullPage");
-
+lonca
     function initDocument() {
-	var editor=new HTMLArea("filecont",config);
-	editor.registerPlugin(FullPage);
-	editor.generate();
-	setTimeout(
-		   function () {
-		       HTMLArea._addEvents(editor._doc,
-					   ["keypress","mousedown"], unClean);
-		       editor._iframe.id = '$textarea_id';
-		       resize_textarea('$textarea_id','LC_aftertextarea');
-		   },300);
+        var oFCKeditor = new FCKeditor('filecont');
+	oFCKeditor.Config['CustomConfigurationsPath'] = '/fckeditor/loncapaconfig.js'  ;
+	oFCKeditor.Config['FullPage'] = true
+	oFCKeditor.Config['AutoDetectLanguage'] = false;
+        oFCKeditor.Config['DefaultLanguage'] = "$lang";
+	oFCKeditor.ReplaceTextarea();
+    }
+    function check_if_dirty(editor) {
+	if (editor.IsDirty()) {
+	    unClean();
+	}
+    }
+    function FCKeditor_OnComplete(editor) {
+	editor.Events.AttachEvent("OnSelectionChange",check_if_dirty);
+	resize_textarea('$textarea_id','LC_aftertextarea');
     }
 </script>
 FULLPAGE
       } else {
 	  $initialize.=(<<FULLPAGE);
 <script type="text/javascript">
-$addbuttons
     function initDocument() {
 	resize_textarea('$textarea_id','LC_aftertextarea');
     }
@@ -1543,10 +1671,13 @@ ENDNOTFOUND
 						    ['rawmode']);
 	    if ($env{'form.rawmode'}) { $result = $filecontents; }
 	    if ($filetype eq 'sty') {
+		my $controls =
+		    ($env{'request.state'} eq 'construct') ? &Apache::londefdef::edit_controls()
+		                                           : '';
 		my %options = ('bgcolor' => '#FFFFFF');
 		$result = 
 		    &Apache::loncommon::start_page(undef,undef,\%options).
-		    &Apache::londefdef::edit_controls().
+		    $controls.
 		    $result.
 		    &Apache::loncommon::end_page();
 	    }