--- loncom/interface/londocs.pm	2008/05/28 14:21:30	1.307
+++ loncom/interface/londocs.pm	2008/12/15 06:09:37	1.322
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Documents
 #
-# $Id: londocs.pm,v 1.307 2008/05/28 14:21:30 www Exp $
+# $Id: londocs.pm,v 1.322 2008/12/15 06:09:37 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -26,6 +26,8 @@
 # http://www.lon-capa.org/
 #
 
+
+
 package Apache::londocs;
 
 use strict;
@@ -53,15 +55,10 @@ my %alreadyseen=();
 
 my $hadchanges;
 
-# Available help topics
 
 my %help=();
 
-# Mapread read maps into LONCAPA::map:: global arrays 
-# @order and @resources, determines status
-# sets @order - pointer to resources in right order
-# sets @resources - array with the resources with correct idx
-#
+
 
 sub mapread {
     my ($coursenum,$coursedom,$map)=@_;
@@ -81,20 +78,20 @@ sub storemap {
     return ($errtext,0);
 }
 
-# ----------------------------------------- Return hash with valid author names
+
 
 sub authorhosts {
     my %outhash=();
     my $home=0;
     my $other=0;
-    foreach (keys %env) {
-	if ($_=~/^user\.role\.(au|ca)\.(.+)$/) {
+    foreach my $key (keys(%env)) {
+	if ($key=~/^user\.role\.(au|ca)\.(.+)$/) {
 	    my $role=$1;
 	    my $realm=$2;
-	    my ($start,$end)=split(/\./,$env{$_});
+	    my ($start,$end)=split(/\./,$env{$key});
 	    if (($start) && ($start>time)) { next; }
 	    if (($end) && (time>$end)) { next; }
-	    my $ca; my $cd;
+	    my ($ca,$cd);
 	    if ($1 eq 'au') {
 		$ca=$env{'user.name'};
 		$cd=$env{'user.domain'};
@@ -116,7 +113,7 @@ sub authorhosts {
     }
     return ($home,$other,%outhash);
 }
-# ------------------------------------------------------ Generate "dump" button
+
 
 sub dumpbutton {
     my ($home,$other,%outhash)=&authorhosts();
@@ -141,7 +138,8 @@ sub clean {
     $title=~s/[^\w\/\!\$\%\^\*\-\_\=\+\;\:\,\\\|\`\~]+/\_/gs;
     return $title;	
 }
-# -------------------------------------------------------- Actually dump course
+
+
 
 sub dumpcourse {
     my ($r) = @_;
@@ -161,15 +159,15 @@ sub dumpcourse {
 	my $title=$env{'form.authorfolder'};
 	$title=&clean($title);
 	my %replacehash=();
-	foreach (keys %env) {
-	    if ($_=~/^form\.namefor\_(.+)/) {
-		$replacehash{$1}=$env{$_};
+	foreach my $key (keys(%env)) {
+	    if ($key=~/^form\.namefor\_(.+)/) {
+		$replacehash{$1}=$env{$key};
 	    }
 	}
 	my $crs='/uploaded/'.$env{'request.course.id'}.'/';
 	$crs=~s/\_/\//g;
-	foreach (keys %replacehash) {
-	    my $newfilename=$title.'/'.$replacehash{$_};
+	foreach my $item (keys(%replacehash)) {
+	    my $newfilename=$title.'/'.$replacehash{$item};
 	    $newfilename=~s/\.(\w+)$//;
 	    my $ext=$1;
 	    $newfilename=&clean($newfilename);
@@ -184,16 +182,16 @@ sub dumpcourse {
 		    unless(mkdir($makepath,0777)) { $fail=1; } 
 		}
 	    }
-	    $r->print('<br /><tt>'.$_.'</tt> => <tt>'.$newfilename.'</tt>: ');
+	    $r->print('<br /><tt>'.$item.'</tt> => <tt>'.$newfilename.'</tt>: ');
 	    if (my $fh=Apache::File->new('>'.$path.'/'.$newfilename)) {
-		if ($_=~/\.(sequence|page|html|htm|xml|xhtml)$/) {
+		if ($item=~/\.(sequence|page|html|htm|xml|xhtml)$/) {
 		    print $fh &Apache::lonclonecourse::rewritefile(
-         &Apache::lonclonecourse::readfile($env{'request.course.id'},$_),
+         &Apache::lonclonecourse::readfile($env{'request.course.id'},$item),
 				     (%replacehash,$crs => '')
 								    );
 		} else {
 		    print $fh
-         &Apache::lonclonecourse::readfile($env{'request.course.id'},$_);
+         &Apache::lonclonecourse::readfile($env{'request.course.id'},$item);
 		       }
 		$fh->close();
 	    } else {
@@ -211,8 +209,8 @@ sub dumpcourse {
 	    $r->print(
 		      '<h3>'.&mt('Select the Construction Space').'</h3><select name="authorspace">');
 	}
-	foreach (sort keys %outhash) {
-	    if ($_=~/^home_(.+)$/) {
+	foreach my $key (sort(keys(%outhash))) {
+	    if ($key=~/^home_(.+)$/) {
 		if ($home==1) {
 		    $r->print(
 		  '<input type="hidden" name="authorspace" value="'.$1.'" />');
@@ -228,33 +226,42 @@ sub dumpcourse {
 	my $title=$origcrsdata{'description'};
 	$title=~s/[\/\s]+/\_/gs;
 	$title=&clean($title);
-	$r->print('<h3>'.&mt('Folder in Construction Space').'</h3><input type="text" size="50" name="authorfolder" value="'.$title.'" /><br />');
+	$r->print('<h3>'.&mt('Folder in Construction Space').'</h3>'
+                 .'<input type="text" size="50" name="authorfolder" value="'.$title.'" /><br />');
 	&tiehash();
-	$r->print('<h3>'.&mt('Filenames in Construction Space').'</h3><table border="2"><tr><th>'.&mt('Internal Filename').'</th><th>'.&mt('Title').'</th><th>'.&mt('Save as ...').'</th></tr>');
-	foreach (&Apache::lonclonecourse::crsdirlist($origcrsid,'userfiles')) {
-	    $r->print('<tr><td>'.$_.'</td>');
-	    my ($ext)=($_=~/\.(\w+)$/);
+	$r->print('<h3>'.&mt('Filenames in Construction Space').'</h3>'
+                 .&Apache::loncommon::start_data_table()
+                 .&Apache::loncommon::start_data_table_header_row()
+                 .'<th>'.&mt('Internal Filename').'</th>'
+                 .'<th>'.&mt('Title').'</th>'
+                 .'<th>'.&mt('Save as ...').'</th>'
+                 .&Apache::loncommon::end_data_table_header_row());
+	foreach my $file (&Apache::lonclonecourse::crsdirlist($origcrsid,'userfiles')) {
+	    $r->print(&Apache::loncommon::start_data_table_row()
+                     .'<td>'.$file.'</td>');
+	    my ($ext)=($file=~/\.(\w+)$/);
 	    my $title=$hash{'title_'.$hash{
-		'ids_/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'.$_}};
+		'ids_/uploaded/'.$origcrsdata{'domain'}.'/'.$origcrsdata{'num'}.'/'.$file}};
 	    $r->print('<td>'.($title?$title:'&nbsp;').'</td>');
 	    if (!$title) {
-		$title=$_;
+		$title=$file;
 	    } else {
 		$title=~s|/|_|g;
 	    }
 	    $title=~s/\.(\w+)$//;
 	    $title=&clean($title);
 	    $title.='.'.$ext;
-	    $r->print("\n<td><input type='text' size='60' name='namefor_".$_."' value='".$title."' /></td></tr>\n");
+	    $r->print("\n<td><input type='text' size='60' name='namefor_".$file."' value='".$title."' /></td>"
+                     .&Apache::loncommon::end_data_table_row());
 	}
-	$r->print("</table>\n");
+	$r->print(&Apache::loncommon::end_data_table());
 	&untiehash();
 	$r->print(
-  '<p><input type="submit" name="dumpcourse" value="'.&mt('Dump [_1] DOCS',$type).'" /></p></form>');
+  '<p><input type="submit" name="dumpcourse" value="'.&mt("Dump $type DOCS").'" /></p></form>');
     }
 }
 
-# ------------------------------------------------------ Generate "export" button
+
 
 sub exportbutton {
     my $type = &Apache::loncommon::course_type();
@@ -264,12 +271,14 @@ sub exportbutton {
     &Apache::loncommon::help_open_topic('Docs_Export_Course_Docs').'</div>';
 }
 
+
+
 sub exportcourse {
     my $r=shift;
     my $type = &Apache::loncommon::course_type();
     my %discussiontime = &Apache::lonnet::dump('discussiontimes',
                                                $env{'course.'.$env{'request.course.id'}.'.domain'}, $env{'course.'.$env{'request.course.id'}.'.num'});
-    my $numdisc = keys %discussiontime;
+    my $numdisc = keys(%discussiontime);
     my $navmap = Apache::lonnavmaps::navmap->new();
     my $it=$navmap->getIterator(undef,undef,undef,1,undef,undef);
     my $curRes;
@@ -309,10 +318,10 @@ sub exportcourse {
                 chdir $cwd;
                 $outcome .= &mt('Download the zip file from <a href="[_1]">IMS '.lc($type).' archive</a><br />',$imszipfile,);
                 if ($copyresult) {
-                    $outcome .= 'The following errors occurred during export - '.$copyresult;
+                    $outcome .= &mt('The following errors occurred during export - [_1]',$copyresult);
                 }
             } else {
-                $outcome = '<br />Unfortunately you will not be able to retrieve an IMS archive of this posts at this time, because there was a problem creating a manifest file.<br />';
+                $outcome = '<br />'.&mt('Unfortunately you will not be able to retrieve an IMS archive of this posts at this time, because there was a problem creating a manifest file.').'<br />';
             }
         }
         $r->print(&Apache::loncommon::start_page('Export '.lc($type).' to IMS content package'));
@@ -439,8 +448,8 @@ function containerCheck(item) {
     }
         |;
 
-        foreach my $container (sort { $a <=> $b } keys %children) {
-            my @contents = split/:/,$children{$container};
+        foreach my $container (sort { $a <=> $b } (keys(%children))) {
+            my @contents = split(/:/,$children{$container});
             for (my $i=0; $i<@contents; $i ++) {
                 $scripttag .= '    parents['.$container.']['.$i.'] = '.$contents[$i]."\n";
             }
@@ -548,7 +557,7 @@ sub build_package {
             if ($curRes->is_sequence() || $curRes->is_page()) {
                 $lastcontainer = $count;
             }
-            if (grep/^$count$/,@$exportitems) {
+            if (grep(/^$count$/,@$exportitems)) {
                 &get_dependencies($exportitems,\%parent,$depth,\@dependencies);
             }
         }
@@ -572,7 +581,7 @@ sub build_package {
 
         if (ref($curRes)) {
             $count ++;
-            if ((grep/^$count$/,@$exportitems) || (grep/^$count$/,@dependencies)) {
+            if ((grep(/^$count$/,@$exportitems)) || (grep(/^$count$/,@dependencies))) {
                 my $symb = $curRes->symb();
                 my $isvisible = 'true';
                 my $resourceref;
@@ -606,11 +615,11 @@ sub build_package {
                      '   <resource identifier="RES-'.$env{'request.course.id'}.'-'.$count.
                      '" type="webcontent" href="'.$content_file.'">'."\n".
                      '       <file href="'.$content_file.'" />'."\n";
-                        foreach (@hrefs) {
+                        foreach my $item (@hrefs) {
                             $imsresources .=
-                     '        <file href="'.$_.'" />'."\n";
+                     '        <file href="'.$item.'" />'."\n";
                         }
-                        if (grep/^$count$/,@$discussions) {
+                        if (grep(/^$count$/,@$discussions)) {
                             my $ressymb = $symb;
                             my $mode;
                             if ($ressymb =~ m|adm/($match_domain)/($match_username)/(\d+)/bulletinboard$|) {
@@ -651,8 +660,8 @@ sub build_package {
 sub get_dependencies {
     my ($exportitems,$parent,$depth,$dependencies) = @_;
     if ($depth > 1) {
-        if ((!grep/^$$parent{$depth}$/,@$exportitems) && (!grep/^$$parent{$depth}$/,@$dependencies)) {
-            push @$dependencies, $$parent{$depth};
+        if ((!grep(/^$$parent{$depth}$/,@$exportitems)) && (!grep(/^$$parent{$depth}$/,@$dependencies))) {
+            push(@{$dependencies},$$parent{$depth});
             if ($depth > 2) {
                 &get_dependencies($exportitems,$parent,$depth-1,$dependencies);
             }
@@ -818,7 +827,7 @@ sub extract_media {
         $dirpath = $url;
         $container = '';
     }
-    &Apache::lonnet::extract_embedded_items(undef,undef,\%allfiles,\%codebase,$content);
+    &Apache::lonnet::extract_embedded_items(undef,\%allfiles,\%codebase,$content);
     foreach my $embed_file (keys(%allfiles)) {
         my $filename;
         if ($embed_file =~ m#([^/]+)$#) {
@@ -858,7 +867,7 @@ sub extract_media {
             my $copiedfile;
             if ($copiedfile = Apache::File->new('>'.$destination)) {
                 print $copiedfile $embed_content;
-                push @{$href}, 'resources/'.$count.'/res/'.$filename;
+                push(@{$href},'resources/'.$count.'/res/'.$filename);
                 my $attrib_regexp = '';
                 if (@{$allfiles{$embed_file}} > 1) {
                     $attrib_regexp = join('|',@{$allfiles{$embed_file}});
@@ -902,8 +911,7 @@ sub store_template {
     }
 }
 
-# Imports the given (name, url) resources into the course
-# coursenum, coursedom, and folder must precede the list
+
 sub group_import {
     my ($coursenum, $coursedom, $folder, $container, $caller, @files) = @_;
 
@@ -924,7 +932,7 @@ sub group_import {
             my $result=&Apache::lonnet::finishuserfileupload($coursenum,$coursedom,
                                                 'output',$1.$2);
             if ($result != m|^/uploaded/|) {
-                $errtext.='Map not saved: A network error occured when trying to save the new map. ';
+                $errtext.='Map not saved: A network error occurred when trying to save the new map. ';
                 $fatal = 2;
             }
             if ($fatal) {
@@ -949,7 +957,7 @@ sub group_import {
 }
 
 sub breadcrumbs {
-    my ($where)=@_;
+    my ($where,$allowed,$type)=@_;
     &Apache::lonhtmlcommon::clear_breadcrumbs();
     my (@folders);
     if ($env{'form.pagepath'}) {
@@ -966,7 +974,7 @@ sub breadcrumbs {
     my $is_random_order=0;
     while (@folders) {
 	my $folder=shift(@folders);
-	my $foldername=shift(@folders);
+    	my $foldername=shift(@folders);
 	if ($folderpath) {$folderpath.='&';}
 	$folderpath.=$folder.'&'.$foldername;
 	my $url='/adm/coursedocs?folderpath='.
@@ -982,6 +990,13 @@ sub breadcrumbs {
             if ($2) { $ishidden=1; }
             if ($3) { $isencrypted=1; }
 	    if ($4 ne '') { $is_random_order = 1; }
+            if ($folder eq 'supplemental') {
+                if ($allowed) {
+                    $name = &mt('Supplemental '.$type.' Documents');
+                } else {
+                    $name = &mt($type.' Documents');
+                }
+            }
 	    &Apache::lonhtmlcommon::add_breadcrumb(
 		      {'href'=>$url.$cpinfo,
 		       'title'=>$name,
@@ -1031,7 +1046,7 @@ sub log_docs {
                        'currentfolder' => $env{'form.folder'});
         if ($parmidx) {
            $storehash{'parameter_res'}=$oldresources[$parmidx];
-           foreach my $parm (keys %parmaction) {
+           foreach my $parm (keys(%parmaction)) {
               $storehash{'parameter_action_'.$parm}=$parmaction{$parm};
               $storehash{'parameter_value_'.$parm}=$parmvalue{$parm};
            }
@@ -1058,9 +1073,9 @@ sub log_docs {
 }
 
 
-#
-# Docs Change Log
-#
+
+
+
 sub docs_change_log {
     my ($r)=@_;
     my $folder=$env{'form.folder'};
@@ -1201,7 +1216,10 @@ sub update_paste_buffer {
 # Mark for copying
     my ($title,$url)=split(':',$LONCAPA::map::resources[$LONCAPA::map::order[$env{'form.markcopy'}]]);
     if (&is_supplemental_title($title)) {
+        &Apache::lonnet::appenv({'docs.markedcopy_supplemental' => $title});
 	($title) = &parse_supplemental_title($title);
+    } elsif ($env{'docs.markedcopy_supplemental'}) {
+        &Apache::lonnet::delenv('docs\\.markedcopy_supplemental');
     }
     $url=~s{http(&colon;|:)//https(&colon;|:)//}{https$2//};
 
@@ -1250,9 +1268,11 @@ ENDPASTE
 }
 
 sub do_paste_from_buffer {
-    my ($coursenum,$coursedom) = @_;
+    my ($coursenum,$coursedom,$folder) = @_;
 
-    return 0 if (!$env{'form.pastemarked'});
+    if (!$env{'form.pastemarked'}) {
+        return;
+    }
 
 # paste resource to end of list
     my $url=&LONCAPA::map::qtescape($env{'docs.markedcopy_url'});
@@ -1261,12 +1281,44 @@ sub do_paste_from_buffer {
     if (($url=~/\.(page|sequence)$/) && ($url=~/^\/uploaded\//)) {
 	$title=&mt('Copy of').' '.$title;
 	my $newid=$$.time;
-	$url=~/^(.+)\.(\w+)$/;
-	my $newurl=$1.$newid.'.'.$2;
+	my ($oldid,$ext) = ($url=~/^(.+)\.(\w+)$/);
+        if ($oldid =~ m{^(/uploaded/\Q$coursedom\E/\Q$coursenum\E/)(\D+)(\d+)$}) {
+            my $path = $1;
+            my $prefix = $2;
+            my $ancestor = $3;
+            if (length($ancestor) > 10) {
+                $ancestor = substr($ancestor,-10,10);
+            }
+            $oldid = $path.$prefix.$ancestor;
+        }
+        my $counter = 0;
+        my $newurl=$oldid.$newid.'.'.$ext;
+        my $is_unique = &uniqueness_check($newurl);
+        while (!$is_unique && $counter < 100) {
+            $counter ++;
+            $newid ++;
+            $newurl = $oldid.$newid;
+            $is_unique = &uniqueness_check($newurl);
+        }
+        if (!$is_unique) {
+            if ($url=~/\.page$/) {
+                return &mt('Paste failed: an error occurred creating a unique URL for the composite page');
+            } else {
+                return &mt('Paste failed: an error occurred creating a unique URL for the folder');
+            }
+        }
 	my $storefn=$newurl;
 	$storefn=~s{^/\w+/$match_domain/$match_username/}{};
-	&Apache::lonclonecourse::writefile($env{'request.course.id'},$storefn,
-					   &Apache::lonnet::getfile($url));
+	my $paste_map_result =
+            &Apache::lonclonecourse::writefile($env{'request.course.id'},$storefn,
+					       &Apache::lonnet::getfile($url));
+        if ($paste_map_result eq '/adm/notfound.html') {
+            if ($url=~/\.page$/) {
+                return &mt('Paste failed: an error occurred saving the composite page');
+            } else {
+                return &mt('Paste failed: an error occurred saving the folder');
+            }
+        }
 	$url = $newurl;
     }
 # published maps can only exists once, so remove it from paste buffer when done
@@ -1292,11 +1344,40 @@ sub do_paste_from_buffer {
     $url       = &LONCAPA::map::qtunescape($url);
 # Now insert the URL at the bottom
     my $newidx = &LONCAPA::map::getresidx($url);
+    if ($env{'docs.markedcopy_supplemental'}) {
+        if ($folder =~ /^supplemental/) {
+            $title = $env{'docs.markedcopy_supplemental'};
+        } else {
+            (undef,undef,$title) = 
+                &parse_supplemental_title($env{'docs.markedcopy_supplemental'});
+        }
+    } else {
+        if ($folder=~/^supplemental/) {
+           $title=time.'___&&&___'.$env{'user.name'}.'___&&&___'.
+                  $env{'user.domain'}.'___&&&___'.$title;
+        }
+    }
+
     $LONCAPA::map::resources[$newidx]= 	$title.':'.$url.':'.$ext.':normal:res';
     push(@LONCAPA::map::order, $newidx);
+    return 'ok';
 # Store the result
 }
 
+sub uniqueness_check {
+    my ($newurl) = @_;
+    my $unique = 1;
+    foreach my $res (@LONCAPA::map::order) {
+        my ($name,$url)=split(/\:/,$LONCAPA::map::resources[$res]);
+        $url=&LONCAPA::map::qtescape($url);
+        if ($newurl eq $url) {
+            $unique = 0;
+            last;    
+        }
+    }
+    return $unique;
+}
+
 my %parameter_type = ( 'randompick'     => 'int_pos',
 		       'hiddenresource' => 'string_yesno',
 		       'encrypturl'     => 'string_yesno',
@@ -1370,7 +1451,7 @@ sub handle_edit_cmd {
 }
 
 sub editor {
-    my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$which)=@_;
+    my ($r,$coursenum,$coursedom,$folder,$allowed,$upload_output,$type)=@_;
 
     my $container= ($env{'form.pagepath'}) ? 'page'
 		                           : 'sequence';
@@ -1387,7 +1468,7 @@ sub editor {
     }
     
     my ($breadcrumbtrail,$randompick,$ishidden,$isencrypted,$plain,$is_random_order)=
-	&breadcrumbs($folder);
+	&breadcrumbs($folder,$allowed,$type);
     $r->print($breadcrumbtrail);
     
 # ------------------------------------------------------------ Process commands
@@ -1412,9 +1493,14 @@ sub editor {
 	}
 	    
 	if ($env{'form.pastemarked'}) {
-	    &do_paste_from_buffer($coursenum,$coursedom);
-	    ($errtext,$fatal) = &storemap($coursenum,$coursedom,$folder.'.'.$container);
-	    return $errtext if ($fatal);
+            my $paste_res = 
+                &do_paste_from_buffer($coursenum,$coursedom,$folder);
+            if ($paste_res eq 'ok') {
+                ($errtext,$fatal) = &storemap($coursenum,$coursedom,$folder.'.'.$container);
+                return $errtext if ($fatal);
+            } elsif ($paste_res ne '') {
+                $r->print('<p><span class="LC_error">'.$paste_res.'</span></p>');
+            }
 	}
 
 	$r->print($upload_output);
@@ -1426,10 +1512,10 @@ sub editor {
 # Group import/search
 	if ($env{'form.importdetail'}) {
 	    my @imports;
-	    foreach (split(/\&/,$env{'form.importdetail'})) {
-		if (defined($_)) {
+	    foreach my $item (split(/\&/,$env{'form.importdetail'})) {
+		if (defined($item)) {
 		    my ($name,$url,$residx)=
-			map {&unescape($_)} split(/\=/,$_);
+			map {&unescape($_)} split(/\=/,$item);
 		    push(@imports, [$name, $url, $residx]);
 		}
 	    }
@@ -1489,8 +1575,9 @@ sub editor {
 	$r->print('<tr><td>'.&mt('Currently no documents.').'</td></tr>');
     }
     $r->print("\n</table>\n");
-    
-    &print_paste_buffer($r,$container);
+    if ($allowed) {
+        &print_paste_buffer($r,$container);
+    }
     return;
 }
 
@@ -1571,8 +1658,8 @@ sub process_file_upload {
 
                     $$upload_output .= 
 			'This file contains embedded multimedia objects, which need to be uploaded to LON-CAPA.<br />'.
-			&ask_for_embedded_content('/adm/coursedocs',
-						  $state,$allfiles,$codebase);
+			&Apache::loncommon::ask_for_embedded_content(
+                            '/adm/coursedocs',$state,$allfiles,$codebase);
                 } else {
                     $$upload_output .= 'No embedded items identified<br />';
                 }
@@ -1582,55 +1669,6 @@ sub process_file_upload {
     return $phase_status;
 }
 
-sub ask_for_embedded_content {
-    my ($actionurl,$state,$allfiles,$codebase,$args)=@_;
-    my $upload_output = '
-   <form name="upload_embedded" action="'.$actionurl.'"
-                  method="post" enctype="multipart/form-data">';
-    $upload_output .= $state;
-    $upload_output .= '<b>Upload embedded files</b>:<br />'.
-	&Apache::loncommon::start_data_table();
-
-    my $num = 0;
-    foreach my $embed_file (sort {lc($a) cmp lc($b)} keys(%{$allfiles})) {
-	$upload_output .= &Apache::loncommon::start_data_table_row().
-	    '<td>'.$embed_file.'</td><td>';
-	if ($args->{'ignore_remote_references'}
-	    && $embed_file =~ m{^\w+://}) {
-	    $upload_output.='<span class="LC_warning">'.&mt("URL points to other server.").'</span>';
-	} elsif ($args->{'error_on_invalid_names'}
-	    && $embed_file ne &Apache::lonnet::clean_filename($embed_file,{'keep_path' => 1,})) {
-	    
-	    $upload_output.='<span class="LC_warning">'.&mt("Invalid characters").'</span>';
-	    
-	} else {
-
-	    $upload_output .='
-           <input name="embedded_item_'.$num.'" type="file" value="bob" />
-           <input name="embedded_orig_'.$num.'" type="hidden" value="'.&escape($embed_file).'" />';
-	    my $attrib = join(':',@{$$allfiles{$embed_file}});
-	    $upload_output .=
-		"\n\t\t".
-		'<input name="embedded_attrib_'.$num.'" type="hidden" value="'.
-		$attrib.'" />';
-	    if (exists($$codebase{$embed_file})) {
-		$upload_output .= 
-		    "\n\t\t".
-		    '<input name="codebase_'.$num.'" type="hidden" value="'.
-		    &escape($$codebase{$embed_file}).'" />';
-	    }
-	}
-	$upload_output .= '</td>'.&Apache::loncommon::end_data_table_row();
-	$num++;
-    }
-    $upload_output .= &Apache::loncommon::end_data_table().'<br />
-   <input type ="hidden" name="number_embedded_items" value="'.$num.'" />
-   <input type ="submit" value="'.&mt('Upload Listed Files').'" />
-   '.&mt('(only files for which a location has been provided will be uploaded)').'
-   </form>';
-    return $upload_output;
-}
-
 sub process_secondary_uploads {
     my ($upload_output,$coursedom,$coursenum,$formname,$num,$newidx) = @_;
     my $folder=$env{'form.folder'};
@@ -1754,8 +1792,8 @@ sub entryline {
 		# no copy for published maps
 		$nocopy = 1;
 	    } else {
-		foreach (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$url),1)) {
-		    my ($title,$url,$ext,$type)=split(/\:/,$_);
+		foreach my $item (&Apache::lonsequence::attemptread(&Apache::lonnet::filelocation('',$url),1)) {
+		    my ($title,$url,$ext,$type)=split(/\:/,$item);
 		    if (($url=~/\.(page|sequence)/) && ($type ne 'zombie')) {
 			$nocopy=1;
 			last;
@@ -1919,7 +1957,7 @@ END
     	my $ro_set=
 	    ((&LONCAPA::map::getparameter($orderidx,'parameter_randomorder'))[0]=~/^yes$/i?' checked="checked"':'');
 	$rand_order_text ='
-<nobr><label><input type="checkbox" name="randomorder_'.$orderidx.'" onClick="this.form.changeparms.value=\'randomorder\';this.form.submit()" '.$ro_set.' /> '.&mt('Random Order').' </label></nobr>';   
+<span class="LC_nobreak"><label><input type="checkbox" name="randomorder_'.$orderidx.'" onClick="this.form.changeparms.value=\'randomorder\';this.form.submit()" '.$ro_set.' /> '.&mt('Random Order').' </label></span>';   
     }
     if ($ispage) {
         my $pagename=&escape($pagetitle);
@@ -1979,7 +2017,13 @@ ENDPARMS
     return $line;
 }
 
-# ---------------------------------------------------------------- tie the hash
+=pod
+
+=item tiehash()
+
+tie the hash
+
+=cut
 
 sub tiehash {
     my ($mode)=@_;
@@ -2005,7 +2049,8 @@ sub untiehash {
     return OK;
 }
 
-# --------------------------------------------------------------- check on this
+
+
 
 sub checkonthis {
     my ($r,$url,$level,$title)=@_;
@@ -2014,6 +2059,9 @@ sub checkonthis {
     $r->rflush();
     if (($url) && ($url!~/^\/uploaded\//) && ($url!~/\*$/)) {
        $r->print("\n<br />");
+       if ($level==0) {
+           $r->print("<br />");
+       }
        for (my $i=0;$i<=$level*5;$i++) {
            $r->print('&nbsp;');
        }
@@ -2023,7 +2071,7 @@ sub checkonthis {
 	  my $result=&Apache::lonnet::repcopy(
                               &Apache::lonnet::filelocation('',$url));
           if ($result eq 'ok') {
-             $r->print('<font color="green">'.&mt('ok').'</font>');
+             $r->print('<span class="LC_success">'.&mt('ok').'</span>');
              $r->rflush();
              &Apache::lonnet::countacc($url);
              $url=~/\.(\w+)$/;
@@ -2033,7 +2081,7 @@ sub checkonthis {
                  for (my $i=0;$i<=$level*5;$i++) {
                      $r->print('&nbsp;');
                  }
-                 $r->print('- '.&mt('Rendering').': ');
+                 $r->print('- '.&mt('Rendering:').' ');
 		 my ($errorcount,$warningcount)=split(/:/,
 	       &Apache::lonnet::ssi_body($url,
 			       ('grade_target'=>'web',
@@ -2042,13 +2090,11 @@ sub checkonthis {
                      ($warningcount)) {
 		     if ($errorcount) {
                         $r->print('<img src="/adm/lonMisc/bomb.gif" /><span class="LC_error">'.
-			  $errorcount.' '.
-				  &mt('error(s)').'</span> ');
+                          &mt('[quant,_1,error]',$errorcount).'</span>');
                      }
 		     if ($warningcount) {
                         $r->print('<span class="LC_warning">'.
-			  $warningcount.' '.
-				  &mt('warning(s)').'</span>');
+                          &mt('[quant,_1,warning]',$warningcount).'</span>');
                      }
                  } else {
                      $r->print('<span class="LC_success">'.&mt('ok').'</span>');
@@ -2057,30 +2103,36 @@ sub checkonthis {
              }
 	     my $dependencies=
                 &Apache::lonnet::metadata($url,'dependencies');
-             foreach (split(/\,/,$dependencies)) {
-		 if (($_=~/^\/res\//) && (!$alreadyseen{$_})) {
-                    &checkonthis($r,$_,$level+1);
+             foreach my $dep (split(/\,/,$dependencies)) {
+		 if (($dep=~/^\/res\//) && (!$alreadyseen{$dep})) {
+                    &checkonthis($r,$dep,$level+1);
                  }
              }
           } elsif ($result eq 'unavailable') {
              $r->print('<span class="LC_error">'.&mt('connection down').'</span>');
           } elsif ($result eq 'not_found') {
 	      unless ($url=~/\$/) {
-		  $r->print('<span class="LC_error">'.&mt('not found').'</b></font>');
+		  $r->print('<span class="LC_error">'.&mt('not found').'</b></span>');
 	      } else {
 		  $r->print('<span class="LC_unknown">'.&mt('unable to verify variable URL').'</span>');
 	      }
           } else {
              $r->print('<span class="LC_error">'.&mt('access denied').'</span>');
           }
-      }
-   }
+       }
+    }
 }
 
 
-#
-# ----------------------------------------------------------------- List Symbs
-# 
+
+=pod
+
+=item list_symbs()
+
+List Symbs
+
+=cut
+
 sub list_symbs {
     my ($r) = @_;
 
@@ -2096,9 +2148,7 @@ sub list_symbs {
 }
 
 
-#
-# -------------------------------------------------------------- Verify Content
-# 
+
 sub verifycontent {
     my ($r) = @_;
     my $type = &Apache::loncommon::course_type();
@@ -2110,17 +2160,17 @@ sub verifycontent {
    undef %alreadyseen;
    %alreadyseen=();
    &tiehash();
-   foreach (keys %hash) {
-       if ($hash{$_}=~/\.(page|sequence)$/) {
-	   if (($_=~/^src_/) && ($alreadyseen{&unescape($hash{$_})})) {
+   foreach my $key (keys(%hash)) {
+       if ($hash{$key}=~/\.(page|sequence)$/) {
+	   if (($key=~/^src_/) && ($alreadyseen{&unescape($hash{$key})})) {
 	       $r->print('<hr /><span class="LC_error">'.
 			 &mt('The following sequence or page is included more than once in your '.$type.': ').
-			 &unescape($hash{$_}).'</span><br />'.
+			 &unescape($hash{$key}).'</span><br />'.
 			 &mt('Note that grading records for problems included in this sequence or folder will overlap.<hr />'));
 	   }
        }
-       if (($_=~/^src\_(.+)$/) && (!$alreadyseen{&unescape($hash{$_})})) {
-           &checkonthis($r,$hash{$_},0,$hash{'title_'.$1});
+       if (($key=~/^src\_(.+)$/) && (!$alreadyseen{&unescape($hash{$key})})) {
+           &checkonthis($r,$hash{$key},0,$hash{'title_'.$1});
        }
    }
    &untiehash();
@@ -2129,8 +2179,6 @@ sub verifycontent {
 }
 
 
-# -------------------------------------------------------------- Check Versions
-
 sub devalidateversioncache {
     my $src=shift;
     &Apache::lonnet::devalidate_cache_new('courseresversion',$env{'request.course.id'}.'_'.
@@ -2160,16 +2208,16 @@ sub checkversions {
     my %newsetversions=();
     if ($env{'form.setmostrecent'}) {
 	$haschanged=1;
-	foreach (keys %hash) {
-	    if ($_=~/^ids\_(\/res\/.+)$/) {
+	foreach my $key (keys(%hash)) {
+	    if ($key=~/^ids\_(\/res\/.+)$/) {
 		$newsetversions{$1}='mostrecent';
                 &devalidateversioncache($1);
 	    }
 	}
     } elsif ($env{'form.setcurrent'}) {
 	$haschanged=1;
-	foreach (keys %hash) {
-	    if ($_=~/^ids\_(\/res\/.+)$/) {
+	foreach my $key (keys(%hash)) {
+	    if ($key=~/^ids\_(\/res\/.+)$/) {
 		my $getvers=&Apache::lonnet::getversion($1);
 		if ($getvers>0) {
 		    $newsetversions{$1}=$getvers;
@@ -2179,11 +2227,11 @@ sub checkversions {
 	}
     } elsif ($env{'form.setversions'}) {
 	$haschanged=1;
-	foreach (keys %env) {
-	    if ($_=~/^form\.set_version_(.+)$/) {
+	foreach my $key (keys(%env)) {
+	    if ($key=~/^form\.set_version_(.+)$/) {
 		my $src=$1;
-		if (($env{$_}) && ($env{$_} ne $setversions{$src})) {
-		    $newsetversions{$src}=$env{$_};
+		if (($env{$key}) && ($env{$key} ne $setversions{$src})) {
+		    $newsetversions{$src}=$env{$key};
 		    &devalidateversioncache($src);
 		}
 	    }
@@ -2204,8 +2252,8 @@ sub checkversions {
 # show all documents
 	$header=&mt('All Documents in '.$type);
 	$allsel=1;
-	foreach (keys %hash) {
-	    if ($_=~/^ids\_(\/res\/.+)$/) {
+	foreach my $key (keys(%hash)) {
+	    if ($key=~/^ids\_(\/res\/.+)$/) {
 		my $src=$1;
 		$changes{$src}=1;
 	    }
@@ -2215,7 +2263,7 @@ sub checkversions {
 	%changes=&Apache::lonnet::dump
 	 ('versionupdate',$env{'course.'.$env{'request.course.id'}.'.domain'},
                      $env{'course.'.$env{'request.course.id'}.'.num'});
-	my $firstkey=(keys %changes)[0];
+	my $firstkey=(keys(%changes))[0];
 	unless ($firstkey=~/^error\:/) {
 	    unless ($env{'form.timerange'}) {
 		$env{'form.timerange'}=604800;
@@ -2279,14 +2327,14 @@ sub checkversions {
 <input type="submit" name="setversions" value="$lt{'sv'}" />
 <table border="0">
 ENDHEADERS
-    foreach (sort keys %changes) {
-	if ($changes{$_}>$starttime) {
-	    my ($root,$extension)=($_=~/^(.*)\.(\w+)$/);
-	    my $currentversion=&Apache::lonnet::getversion($_);
+    foreach my $key (sort(keys(%changes))) {
+	if ($changes{$key}>$starttime) {
+	    my ($root,$extension)=($key=~/^(.*)\.(\w+)$/);
+	    my $currentversion=&Apache::lonnet::getversion($key);
 	    if ($currentversion<0) {
 		$currentversion=&mt('Could not be determined.');
 	    }
-	    my $linkurl=&Apache::lonnet::clutter($_);
+	    my $linkurl=&Apache::lonnet::clutter($key);
 	    $r->print(
 		      '<tr><td colspan="5"><br /><br /><font size="+1"><b>'.
 		      &Apache::lonnet::gettitle($linkurl).
@@ -2433,7 +2481,6 @@ sub changewarning {
 $help{'Caching'}.'</span></h3></form>'."\n\n");
 }
 
-# =========================================== Breadcrumbs for special functions
 
 sub init_breadcrumbs {
     my ($form,$text)=@_;
@@ -2449,7 +2496,9 @@ sub init_breadcrumbs {
 					    bug=>'Instructor Interface'});
 }
 
-# ================================================================ Main Handler
+
+
+
 sub handler {
     my $r = shift;
     &Apache::loncommon::content_type($r,'text/html');
@@ -2458,13 +2507,13 @@ sub handler {
     my $type = &Apache::loncommon::course_type();
 
 # --------------------------------------------- Initialize help topics for this
-    foreach ('Adding_Course_Doc','Main_Course_Documents',
-	     'Adding_External_Resource','Navigate_Content',
-	     'Adding_Folders','Docs_Overview', 'Load_Map',
-	     'Supplemental','Score_Upload_Form','Adding_Pages',
-	     'Importing_LON-CAPA_Resource','Uploading_From_Harddrive',
-	     'Check_Resource_Versions','Verify_Content') {
-	$help{$_}=&Apache::loncommon::help_open_topic('Docs_'.$_);
+    foreach my $topic ('Adding_Course_Doc','Main_Course_Documents',
+	               'Adding_External_Resource','Navigate_Content',
+	               'Adding_Folders','Docs_Overview', 'Load_Map',
+	               'Supplemental','Score_Upload_Form','Adding_Pages',
+	               'Importing_LON-CAPA_Resource','Uploading_From_Harddrive',
+	               'Check_Resource_Versions','Verify_Content') {
+	$help{$topic}=&Apache::loncommon::help_open_topic('Docs_'.$topic);
     }
     # Composite help files
     $help{'Syllabus'} = &Apache::loncommon::help_open_topic(
@@ -2525,6 +2574,11 @@ sub handler {
     if ($env{'form.pagepath'}) {
        $env{'form.folderpath'}='';
     }
+    if ($env{'form.folderpath'} =~ /^supplemental_\d+/) {
+        $env{'form.folderpath'} = 'supplemental&'.
+                                  &escape(&mt('Supplemental '.$type.' Documents')).'&'.
+                                  $env{'form.folderpath'};
+    }
     &Apache::loncommon::store_course_settings('docs_folderpath',
                                                 {'pagepath' => 'scalar',
                                                  'folderpath' => 'scalar'});
@@ -2578,8 +2632,9 @@ sub handler {
     }
 # -------------------------------------------------------------------- Body tag
     $script = '<script type="text/javascript">'."\n".$script."\n".'</script>';
+	my @brcrum = [{href=>"/adm/createuser",text=>"$type Documents"}];
     $r->print(&Apache::loncommon::start_page("$type Documents", $script,
-					     {'force_register' => $showdoc,}).
+					     {'force_register' => $showdoc, bread_crumbs => @brcrum}).
 	      &Apache::loncommon::help_open_menu('','',273,'RAT'));
   
   my %allfiles = ();
@@ -2618,12 +2673,12 @@ sub handler {
                   }
                   my @attributes = ();
                   if ($env{'form.embedded_attrib_'.$i} =~ /:/) {
-                      @attributes = split/:/,$env{'form.embedded_attrib_'.$i};
+                      @attributes = split(/:/,$env{'form.embedded_attrib_'.$i});
                   } else {
                       @attributes = ($env{'form.embedded_attrib_'.$i});
                   }
-                  foreach (@attributes) {
-                      push(@{$attribs{$i}},&unescape($_));
+                  foreach my $attr (@attributes) {
+                      push(@{$attribs{$i}},&unescape($attr));
                   }
                   if ($javacodebase) {
                       $codebase{$i} = $javacodebase;
@@ -2641,7 +2696,7 @@ sub handler {
               my $updateflag = 0;
               my $getstatus = &Apache::lonnet::getuploaded('GET',$primary_url,$coursedom,$coursenum,\$content,\$rtncode);
               if ($getstatus eq 'ok') {
-                  foreach my $item (keys %newname) {
+                  foreach my $item (keys(%newname)) {
                       if ($newname{$item} ne $origname{$item}) {
                           my $attrib_regexp = '';
                           if (@{$attribs{$item}} > 1) {
@@ -2789,12 +2844,12 @@ ENDCOURSEVERIFY
        }
        $hadchanges=0;
        my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,
-			   $upload_output);
+			   $upload_output,$type);
        if ($error) {
 	   $r->print('<p><span class="LC_error">'.$error.'</span></p>');
        }
        if ($hadchanges) {
-	   &mark_hash_old()
+	   &mark_hash_old();
        }
        &changewarning($r,$postexec);
        my $folderseq='/uploaded/'.$coursedom.'/'.$coursenum.'/default_'.time.
@@ -3035,11 +3090,11 @@ ENDBLOCK
 	   $folder='supplemental';
        }
        if ($folder =~ /^supplemental$/ &&
-	   $env{'form.folderpath'} =~ /^default\&/) {
-	   $env{'form.folderpath'}='supplemental&'.
-	       &escape(&mt('Supplemental '.$type.' Documents'));
+	   (($env{'form.folderpath'} =~ /^default\&/) || ($env{'form.folderpath'} eq ''))) {
+          $env{'form.folderpath'} = 'supplemental&'.
+                                    &escape(&mt('Supplemental '.$type.' Documents'));
        }
-       my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed);
+       my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$type);
        if ($error) {
 	   $r->print('<p><span class="LC_error">'.$error.'</span></p>');
        }
@@ -3349,3 +3404,126 @@ ENDNEWSCRIPT
 }
 1;
 __END__
+
+
+=head1 NAME
+
+Apache::londocs.pm
+
+=head1 SYNOPSIS
+
+This is part of the LearningOnline Network with CAPA project
+described at http://www.lon-capa.org.
+
+=head1 SUBROUTINES
+
+=over
+
+=item %help=()
+
+Available help topics
+
+=item mapread()
+
+Mapread read maps into LONCAPA::map:: global arrays 
+@order and @resources, determines status
+sets @order - pointer to resources in right order
+sets @resources - array with the resources with correct idx
+
+=item authorhosts()
+
+Return hash with valid author names
+
+=item dumpbutton()
+
+Generate "dump" button
+
+=item clean()
+
+=item dumpcourse()
+
+    Actually dump course
+
+
+=item exportbutton()
+
+    Generate "export" button
+
+=item exportcourse()
+
+=item create_ims_store()
+
+=item build_package()
+
+=item get_dependencies()
+
+=item process_content()
+
+=item replicate_content()
+
+=item extract_media()
+
+=item store_template()
+
+=item group_import()
+
+    Imports the given (name, url) resources into the course
+    coursenum, coursedom, and folder must precede the list
+
+=item breadcrumbs()
+
+=item log_docs()
+
+=item docs_change_log()
+
+=item update_paste_buffer()
+
+=item print_paste_buffer()
+
+=item do_paste_from_buffer()
+
+=item update_parameter()
+
+=item handle_edit_cmd()
+
+=item editor()
+
+=item process_file_upload()
+
+=item process_secondary_uploads()
+
+=item is_supplemental_title()
+
+=item parse_supplemental_title()
+
+=item entryline()
+
+=item tiehash()
+
+=item untiehash()
+
+=item checkonthis()
+
+check on this
+
+=item verifycontent()
+
+Verify Content
+
+=item devalidateversioncache() & checkversions()
+
+Check Versions
+
+=item mark_hash_old()
+
+=item is_hash_old()
+
+=item changewarning()
+
+=item init_breadcrumbs()
+
+Breadcrumbs for special functions
+
+=back
+
+=cut