--- rat/lonratedt.pm	2002/05/09 21:59:33	1.6
+++ rat/lonratedt.pm	2002/05/13 19:38:32	1.14
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Edit Handler for RAT Maps
 #
-# $Id: lonratedt.pm,v 1.6 2002/05/09 21:59:33 www Exp $
+# $Id: lonratedt.pm,v 1.14 2002/05/13 19:38:32 www Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -35,6 +35,96 @@ package Apache::lonratedt;
 use strict;
 use Apache::Constants qw(:common);
 use Apache::lonnet;
+use Apache::lonratsrv;
+
+my @order=();
+my @resources=();
+
+
+# Mapread read maps into global arrays @links and @resources, determines status
+# sets @order - pointer to resources in right order
+# sets @resources - array with the resources with correct idx
+#
+sub mapread {
+    my $fn=shift;
+
+    my @links;
+    undef @links;
+    undef @resources;
+    undef @order;
+
+    my ($outtext,$errtext)=&Apache::lonratsrv::loadmap($fn,'');
+    if ($errtext) { return ($errtext,2); }
+
+# -------------------------------------------------------------------- Read map
+    foreach (split(/\<\&\>/,$outtext)) {
+	my ($command,$number,$content)=split(/\<\:\>/,$_);
+        if ($command eq 'objcont') {
+	    $resources[$number]=$content;
+        }
+        if ($command eq 'objlinks') {
+            $links[$number]=$content;
+        }
+    }
+# ------------------------------------------------------- Is this a linear map?
+    my @starters=();
+    my @endings=();
+    undef @starters;
+    undef @endings;
+
+    foreach (@links) {
+        if (defined($_)) {
+	    my ($start,$end,$cond)=split(/\:/,$_);
+            if ((defined($starters[$start])) || (defined($endings[$end]))) { 
+		return
+                 ('Map has branchings. Use advanced editor.',1);
+            }
+	    $starters[$start]=1;
+	    $endings[$end]=1;
+	    if ($cond) {
+		return
+                 ('Map has conditions. Use advanced editor.',1);
+            }
+	}
+
+    }
+    for (my $i=0; $i<=$#resources; $i++) {
+        if (defined($resources[$i])) {
+	    unless (($starters[$i]) || ($endings[$i])) {
+                return
+		 ('Map has unconnected resources. Use advanced editor.',1);
+            }
+        }
+    }
+
+# -------------------------------------------------- This is a linear map, sort
+
+    my $startidx=0;
+    my $endidx=0;
+    for (my $i=0; $i<=$#resources; $i++) {
+        if (defined($resources[$i])) {
+            my ($title,$url,$ext,$type)=split(/\:/,$resources[$i]);
+	    if ($type eq 'start') { $startidx=$i; }
+            if ($type eq 'finish') { $endidx=$i; }
+        }
+    }
+    my $k=0;
+    my $currentidx=$startidx;
+    $order[$k]=$currentidx;
+    for (my $i=0; $i<=$#resources; $i++) {
+        foreach (@links) {
+	    my ($start,$end)=split(/\:/,$_);
+            if ($start==$currentidx) {
+		$currentidx=$end;
+                $k++;
+                $order[$k]=$currentidx;
+                last;
+            }
+        }
+        if ($currentidx==$endidx) { last; }
+    }
+    return $errtext;
+}
 
 # --------------------------------------------------------- Build up RAT screen
 sub ratedt {
@@ -57,8 +147,129 @@ sub ratedt {
 ENDDOCUMENT
 }
 
+# ---------------------------------------------------------------- Make buttons
+
+sub buttons {
+    my $adv=shift;
+    my $output='<form method=post>';     
+    if ($adv==1) {
+	$output.='<input type=submit name=forceadv value="Edit">';
+    } else {
+        unless ($adv==2) {
+           $output.='<input type=submit name=forcesmp value="Simple Edit">';
+        }
+	$output.='<input type=submit name=forceadv value="Advanced Edit">';
+    }
+    return $output.'</form><hr>';
+}
+
 sub smpedt {
-   my ($r,$fn)=@_;
+   my ($r,$errtext)=@_;
+   my $buttons=&buttons(2);
+
+# ---------------------------------------------------------- Process form input
+
+   my @importselect=();
+   my @targetselect=();
+   undef @importselect;
+   undef @targetselect;
+   if (defined($ENV{'form.import'})) {
+       if (ref($ENV{'form.import'})) {
+	   @importselect=sort($ENV->{'form.import'});
+       } else {
+           @importselect=($ENV{'form.import'});
+       }
+   }
+   if (defined($ENV{'form.target'})) {
+       if (ref($ENV{'form.target'})) {
+	   @targetselect=sort($ENV->{'form.target'});
+       } else {
+           @targetselect=($ENV{'form.target'});
+       }
+   }
+# ============================================================ Process commands
+
+   my $targetdetail=$ENV{'form.targetdetail'};
+   my $importdetail=$ENV{'form.curimpdetail'};
+
+# ---------------------------------------------------- Importing from groupsort
+   if ($ENV{'form.importdetail'}) {
+
+       $importdetail='';
+       my @curimport=split(/\&/,$ENV{'form.curimpdetail'});
+
+       my $lastsel;
+
+       if (defined($importselect[-1])) {
+	   $lastsel=$importselect[-1];
+       } else {
+           $lastsel=$#curimport;
+       }
+
+       for (my $i=0;$i<=$lastsel;$i++) {
+           my ($name,$url)=split(/\=/,$curimport[$i]);
+           if ($url) {
+              $importdetail.='&'.&Apache::lonnet::escape($name).'='.
+		 	         &Apache::lonnet::escape($url);
+	   }
+       }
+
+      $importdetail.='&'.$ENV{'form.importdetail'};
+
+       for (my $i=$lastsel+1;$i<=$#curimport;$i++) {
+           my ($name,$url)=split(/\=/,$curimport[$i]);
+           if ($url) {
+              $importdetail.='&'.&Apache::lonnet::escape($name).'='.
+		 	         &Apache::lonnet::escape($url);
+	  }
+       }
+       $importdetail=~s/\&+/\&/g;
+       $importdetail=~s/^\&//;
+
+# ------------------------------------------------------------------- Clear all
+   } elsif ($ENV{'form.clear'}) {
+       $importdetail='';
+# ------------------------------------------------------------ Discard selected
+   } elsif ($ENV{'form.discard'}) {
+       $importdetail='';
+       my @curimport=split(/\&/,$ENV{'form.curimpdetail'});
+       foreach (@importselect) {
+	   $curimport[$_]='';
+       }
+       for (my $i=0;$i<=$#curimport;$i++) {
+           my ($name,$url)=split(/\=/,$curimport[$i]);
+           if ($url) {
+              $importdetail.='&'.&Apache::lonnet::escape($name).'='.
+		 	         &Apache::lonnet::escape($url);
+	   }
+       }
+# ---------------------------
+   }
+
+# ------------------------------------------------------------ Assemble windows
+
+   my $idx=-1;
+   my $importwindow=join("\n",map {
+       $idx++;
+       if ($_) { 
+          my ($name)=split(/\=/,$_);
+          unless ($name) { $name='UNKNOWN'; }
+          '<option value="'.$idx.'">'.&Apache::lonnet::unescape($name).
+                                    '</option>';
+      }
+   } split(/\&/,$importdetail));
+
+   $idx=0;
+   my $targetwindow=join("\n",map { 
+       my ($name,$url)=split(/\:/,$resources[$_]);
+       unless ($name) { $name='UNKNOWN'; }
+       $targetdetail.='&'.&Apache::lonnet::escape($name).'='.
+	                  &Apache::lonnet::escape($url);
+       $idx++;
+       '<option value="'.$idx.'_'.$_.'">'.$name.'</option>';
+   } @order);
+
+# ----------------------------------------------------- Start simple RAT screen
    $r->print(<<ENDSMPHEAD);
 <html>
 <head>
@@ -144,19 +355,49 @@ function idxcheck(mode) {
 </script>
 </head>                 
 <body bgcolor='#FFFFFF'>
-<form method=post>
-<input type=submit name=forceadv 
-value="Advanced Map Editing - Graphical Resource Assembly Tool"><hr>
-This is the future site of the great simple RAT
-<a href="javascript:groupsearch()">Group Search</a>
-<a href="javascript:groupimport()">Group Import</a>
-
+$buttons
+<font color=red>$errtext</font>
+<form name=simpleedit method=post>
+<input type=hidden name=forcesmp value=1>
+<table>
+    <tr><th width="40%">Import</th>
+<th>&nbsp;</th>
+<th width="40%">Target</th></tr>
+<tr><td bgcolor="#FFFFCC">
+<input type=button onClick="javascript:groupsearch()" value="Group Search">
+<input type=button onClick="javascript:groupimport();" value="Group Import">
+<br>after selected
+<hr>
+<input type=submit name="discard" value="Discard Selected">
+<input type=submit name="clear" value="Clear All">
+<input type=button onClick="javascript:viewimport()" value="View">
+    </td><td>&nbsp;</td><td bgcolor="#FFFFCC">
+<input type=button onClick="javascript:viewtarget()" value="View">
+</td></tr>
+<tr><td bgcolor="#FFFFCC"><select name="import" multiple>
+$importwindow
+</select>
+</td>
+<td bgcolor="#FFFFAA" align="center">
+Cut selected<br>
+<input type=submit name=cut value='<<<'><p>
+<hr>
+Paste after selected<br>
+<input type=submit name=paste value='>>>'>
+</td>
+<td bgcolor="#FFFFCC"><select name="target" multiple>
+$targetwindow
+</select>
+</table>
+<input type=hidden name=importdetail value="">
+<input type=hidden name=curimpdetail value="$importdetail">
+<input type=hidden name=targetdetail value="$targetdetail">
+</form>
+</body></html>
 ENDSMPHEAD
-
-    $r->print(
-      '<input type=submit name=forcesmp value="Store"></form></body></html>');
 }
 
+# ----------------------------------------------------------------- No such dir
 sub nodir {
    my ($r,$dir)=@_;
    $dir=~s/^\/home\/\w+\/public\_html//;
@@ -169,6 +410,31 @@ sub nodir {
 ENDNODIR
 }
 
+# ---------------------------------------------------------------- View Handler
+
+sub viewmap {
+    my ($r,$adv,$errtext)=@_;
+    $r->print('<html><body bgcolor="#FFFFFF">'.&buttons($adv));
+    if ($errtext) {
+	$r->print($errtext.'<hr>');
+    }
+    foreach (@resources) {
+	if (defined($_)) {
+	    my ($title,$url)=split(/\:/,$_);
+            $title=~s/\&colon\;/\:/g;
+            $url=~s/\&colon\;/\:/g;
+            unless ($title) { $title='<i>Unknown</i>'; }
+            if ($url) {
+		$r->print('<a href="'.&Apache::lonratsrv::qtescape($url).'">');
+            }
+            $r->print(&Apache::lonratsrv::qtescape($title));
+            if ($url) { $r->print('</a>'); }
+            $r->print('<br>');
+        }
+    }
+    $r->print('</body></html>');
+}
+
 # ================================================================ Main Handler
 
 sub handler {
@@ -186,6 +452,8 @@ sub handler {
       &nodir($r,$dir);
       return OK;
   }
+
+# ------------------------------------------- Determine which tools can be used
   my $adv=0;
 
   unless ($ENV{'form.forcesmp'}) {
@@ -197,10 +465,22 @@ sub handler {
      }
   }
 
-  if ($adv) {
+  my $errtext='';
+  my $fatal=0;
+
+# -------------------------------------------------------------------- Load map
+  ($errtext,$fatal)=&mapread($fn,$errtext);
+
+  if ($fatal==1) { $adv=1; }
+
+# ----------------------------------- adv==1 now means "graphical MUST be used"
+
+  if ($ENV{'form.forceadv'}) {
       &ratedt($r,$url);
+  } elsif ($ENV{'form.forcesmp'}) {
+      &smpedt($r,$errtext);
   } else {
-      &smpedt($r,$fn);
+      &viewmap($r,$adv,$errtext);
   }
   return OK;
 }