--- loncom/interface/loncommon.pm	2007/03/02 23:17:58	1.511
+++ loncom/interface/loncommon.pm	2007/04/16 23:15:42	1.524
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.511 2007/03/02 23:17:58 albertel Exp $
+# $Id: loncommon.pm,v 1.524 2007/04/16 23:15:42 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -68,8 +68,12 @@ use Apache::lontexconvert();
 use Apache::lonclonecourse();
 use LONCAPA qw(:DEFAULT :match);
 
+# ---------------------------------------------- Designs
+use vars qw(%defaultdesign);
+
 my $readit;
 
+
 ##
 ## Global Variables
 ##
@@ -82,10 +86,6 @@ my %scprtag;
 my %fe; my %fd; my %fm;
 my %category_extensions;
 
-# ---------------------------------------------- Designs
-
-my %designhash;
-
 # ---------------------------------------------- Thesaurus variables
 #
 # %Keywords:
@@ -151,30 +151,18 @@ BEGIN {
         }
     }
 
-# -------------------------------------------------------------- domain designs
-
-    my $filename;
+# -------------------------------------------------------------- default domain designs
     my $designdir=$Apache::lonnet::perlvar{'lonTabDir'}.'/lonDomColors';
-    opendir(DIR,$designdir);
-    while ($filename=readdir(DIR)) {
-	if ($filename!~/\.tab$/) { next; }
-	my ($domain)=($filename=~/^($match_domain)\./);
-	{
-	    my $designfile = $designdir.'/'.$filename;
-	    if ( open (my $fh,"<$designfile") ) {
-		while (my $line = <$fh>) {
-		    next if ($line =~ /^\#/);
-		    chomp($line);
-		    my ($key,$val)=(split(/\=/,$line));
-		    if ($val) { $designhash{$domain.'.'.$key}=$val; }
-		}
-		close($fh);
-	    }
-	}
-
+    my $designfile = $designdir.'/default.tab';
+    if ( open (my $fh,"<$designfile") ) {
+        while (my $line = <$fh>) {
+            next if ($line =~ /^\#/);
+            chomp($line);
+            my ($key,$val)=(split(/\=/,$line));
+            if ($val) { $defaultdesign{$key}=$val; }
+        }
+        close($fh);
     }
-    closedir(DIR);
-
 
 # ------------------------------------------------------------- file categories
     {
@@ -1265,37 +1253,13 @@ sub create_text_file {
 ##        Home server <option> list generating code          ##
 ###############################################################
 
-=pod
-
-=head1 Home Server option list generating code
-
-=over 4
-
-=item * get_domains()
-
-Returns an array containing each of the domains listed in the hosts.tab
-file.
-
-=cut
-
-#-------------------------------------------
-sub get_domains {
-    # The code below was stolen from "The Perl Cookbook", p 102, 1st ed.
-    my @domains;
-    my %seen;
-    foreach my $dom (sort(values(%Apache::lonnet::hostdom))) {
-	push(@domains,$dom) unless $seen{$dom}++;
-    }
-    return @domains;
-}
-
 # ------------------------------------------
 
 sub domain_select {
     my ($name,$value,$multiple)=@_;
     my %domains=map { 
-	$_ => $_.' '.$Apache::lonnet::domaindescription{$_} 
-    } &get_domains;
+	$_ => $_.' '. &Apache::lonnet::domain($_,'description') 
+    } &Apache::lonnet::all_domains();
     if ($multiple) {
 	$domains{''}=&mt('Any domain');
 	return &multiple_select_form($name,$value,4,\%domains);
@@ -1308,6 +1272,12 @@ sub domain_select {
 
 =pod
 
+=head1 Routines for form select boxes
+
+=over 4
+
+=cut
+
 =item * multiple_select_form($name,$value,$size,$hash,$order)
 
 Returns a string containing a <select> element int multiple mode
@@ -1459,7 +1429,7 @@ selected");
 #-------------------------------------------
 sub select_dom_form {
     my ($defdom,$name,$includeempty) = @_;
-    my @domains = get_domains();
+    my @domains = sort(&Apache::lonnet::all_domains());
     if ($includeempty) { @domains=('',@domains); }
     my $selectdomain = "<select name=\"$name\" size=\"1\">\n";
     foreach my $dom (@domains) {
@@ -1475,30 +1445,6 @@ sub select_dom_form {
 
 =pod
 
-=item * get_library_servers($domain)
-
-Returns a hash which contains keys like '103l3' and values like 
-'kirk.lite.msu.edu'.  All of the keys will be for machines in the
-given $domain.
-
-=cut
-
-#-------------------------------------------
-sub get_library_servers {
-    my $domain = shift;
-    my %library_servers;
-    foreach my $hostid (keys(%Apache::lonnet::libserv)) {
-        if ($Apache::lonnet::hostdom{$hostid} eq $domain) {
-            $library_servers{$hostid} = &Apache::lonnet::hostname($hostid);
-        }
-    }
-    return %library_servers;
-}
-
-#-------------------------------------------
-
-=pod
-
 =item * home_server_option_list($domain)
 
 returns a string which contains an <option> list to be used in a 
@@ -1509,7 +1455,7 @@ returns a string which contains an <opti
 #-------------------------------------------
 sub home_server_option_list {
     my $domain = shift;
-    my %servers = &get_library_servers($domain);
+    my %servers = &Apache::lonnet::get_servers($domain,'library');
     my $result = '';
     foreach my $hostid (sort(keys(%servers))) {
         $result.=
@@ -1521,8 +1467,6 @@ sub home_server_option_list {
 
 =pod
 
-=back
-
 =cut
 
 ###############################################################
@@ -1911,7 +1855,9 @@ If target_domain is not found in domain.
 #-------------------------------------------
 sub get_auth_defaults {
     my $domain=shift;
-    return ($Apache::lonnet::domain_auth_def{$domain},$Apache::lonnet::domain_auth_arg_def{$domain});
+    return (&Apache::lonnet::domain($domain,'auth_def'),
+	    &Apache::lonnet::domain($domain,'auth_arg_def'));
+	    
 }
 ###############################################################
 ##   End Get Authentication Defaults for Domain              ##
@@ -2495,19 +2441,21 @@ sub preferred_languages {
     if ($browser) {
 	@languages=(@languages,split(/\s*(\,|\;|\:)\s*/,$browser));
     }
-    if ($Apache::lonnet::domain_lang_def{$env{'user.domain'}}) {
+    if (&Apache::lonnet::domain($env{'user.domain'},'lang_def')) {
 	@languages=(@languages,
-		$Apache::lonnet::domain_lang_def{$env{'user.domain'}});
+		    &Apache::lonnet::domain($env{'user.domain'},
+					    'lang_def'));
     }
-    if ($Apache::lonnet::domain_lang_def{$env{'request.role.domain'}}) {
+    if (&Apache::lonnet::domain($env{'request.role.domain'},'lang_def')) {
 	@languages=(@languages,
-		$Apache::lonnet::domain_lang_def{$env{'request.role.domain'}});
+		    &Apache::lonnet::domain($env{'request.role.domain'},
+					    'lang_def'));
     }
-    if ($Apache::lonnet::domain_lang_def{
-	                          $Apache::lonnet::perlvar{'lonDefDomain'}}) {
+    if (&Apache::lonnet::domain($Apache::lonnet::perlvar{'lonDefDomain'},
+				'lang_def')) {
 	@languages=(@languages,
-		$Apache::lonnet::domain_lang_def{
-                                  $Apache::lonnet::perlvar{'lonDefDomain'}});
+		    &Apache::lonnet::domain($Apache::lonnet::perlvar{'lonDefDomain'},
+					    'lang_def'));
     }
 # turn "en-ca" into "en-ca,en"
     my @genlanguages;
@@ -3228,6 +3176,60 @@ sub determinedomain {
     return $domain;
 }
 ###############################################
+
+sub devalidate_domconfig_cache {
+    my ($udom)=@_;
+    &Apache::lonnet::devalidate_cache_new('domainconfig',$udom);
+}
+
+# ---------------------- Get domain configuration for a domain
+sub get_domainconf {
+    my ($udom) = @_;
+    my $cachetime=1800;
+    my ($result,$cached)=&Apache::lonnet::is_cached_new('domainconfig',$udom);
+    if (defined($cached)) { return %{$result}; }
+
+    my %domconfig = &Apache::lonnet::get_dom('configuration',
+					     ['login','rolecolors'],$udom);
+    my %designhash;
+    if (keys(%domconfig) > 0) {
+        if (ref($domconfig{'login'}) eq 'HASH') {
+            foreach my $key (keys(%{$domconfig{'login'}})) {
+                $designhash{$udom.'.login.'.$key}=$domconfig{'login'}{$key};
+            }
+        }
+        if (ref($domconfig{'rolecolors'}) eq 'HASH') {
+            foreach my $role (keys(%{$domconfig{'rolecolors'}})) {
+                if (ref($domconfig{'rolecolors'}{$role}) eq 'HASH') {
+                    foreach my $item (keys(%{$domconfig{'rolecolors'}{$role}})) {
+                        $designhash{$udom.'.'.$role.'.'.$item}=$domconfig{'rolecolors'}{$role}{$item};
+                    }
+                }
+            }
+        }
+    } else {
+        my $designdir=$Apache::lonnet::perlvar{'lonTabDir'}.'/lonDomColors';
+        my $designfile =  $designdir.'/'.$udom.'.tab';
+        if (-e $designfile) {
+            if ( open (my $fh,"<$designfile") ) {
+                while (my $line = <$fh>) {
+                    next if ($line =~ /^\#/);
+                    chomp($line);
+                    my ($key,$val)=(split(/\=/,$line));
+                    if ($val) { $designhash{$udom.'.'.$key}=$val; }
+                }
+                close($fh);
+            }
+        }
+        if (-e '/home/httpd/html/adm/lonDomLogos/'.$udom.'.gif') {
+            $designhash{$udom.'.login.domlogo'} = "/adm/lonDomLogos/$udom.gif";
+        }
+    }
+    &Apache::lonnet::do_cache_new('domainconfig',$udom,\%designhash,
+				  $cachetime);
+    return %designhash;
+}
+
 =pod
 
 =item * &domainlogo()
@@ -3241,13 +3243,17 @@ If the domain logo does not exist, a des
 
 ###############################################
 sub domainlogo {
-    my $domain = &determinedomain(shift);    
-     # See if there is a logo
-    if (-e '/home/httpd/html/adm/lonDomLogos/'.$domain.'.gif') {
-	my $logo=&lonhttpdurl("/adm/lonDomLogos/$domain.gif");
-        return '<img src="'.$logo.'" alt="'.$domain.'" />';
-    } elsif(exists($Apache::lonnet::domaindescription{$domain})) {
-        return $Apache::lonnet::domaindescription{$domain};
+    my $domain = &determinedomain(shift);
+    my %designhash = &get_domainconf($domain);    
+    # See if there is a logo
+    if ($designhash{$domain.'.login.domlogo'} ne '') {
+        my $imgsrc = $designhash{$domain.'.login.domlogo'};
+        if ($imgsrc =~ /^\/(adm|res)/) {
+            $imgsrc = &lonhttpdurl($imgsrc);
+        } 
+        return '<img src="'.$imgsrc.'" alt="'.$domain.'" />';
+    } elsif (defined(&Apache::lonnet::domain($domain,'description'))) {
+        return &Apache::lonnet::domain($domain,'description');
     } else {
         return '';
     }
@@ -3283,11 +3289,20 @@ sub designparm {
 	return $env{'environment.color.'.$which};
     }
     $domain=&determinedomain($domain);
-    if (exists($designhash{$domain.'.'.$which})) {
-	return $designhash{$domain.'.'.$which};
+    my %domdesign = &get_domainconf($domain);
+    my $output;
+    if ($domdesign{$domain.'.'.$which} ne '') {
+	$output = $domdesign{$domain.'.'.$which};
     } else {
-        return $designhash{'default.'.$which};
+        $output = $defaultdesign{$which};
     }
+    if (($which =~ /^(student|coordinator|author|admin)\.img$/) ||
+        ($which =~ /login\.(img|logo|domlogo)/)) {
+        if ($output =~ /^\/(adm|res)\//) {
+            $output = &lonhttpdurl($output);
+        }
+    }
+    return $output;
 }
 
 ###############################################
@@ -3506,8 +3521,11 @@ ENDROLE
 # Top frame rendering, Remote is up
 #
 
-    my $upperleft='<img src="http://'.$ENV{'HTTP_HOST'}.':'.
-        $lonhttpdPort.$img.'" alt="'.$function.'" />';
+    my $imgsrc = $img;
+    if ($img =~ /^\/adm/) {
+        $imgsrc = 'http://'.$ENV{'HTTP_HOST'}.':'.$lonhttpdPort.$img;
+    }
+    my $upperleft='<img src="'.$imgsrc.'" alt="'.$function.'" />';
 
     # Explicit link to get inline menu
     my $menu= ($no_inline_link?''
@@ -3672,20 +3690,18 @@ sub standard_css {
     my $border = ($env{'browser.type'} eq 'explorer') ? '0px 2px 0px 2px'
 	                                              : '0px 3px 0px 4px';
 
+
     return <<END;
 h1, h2, h3, th { font-family: $sans }
 a:focus { color: red; background: yellow } 
 table.thinborder,
-table.LC_optres_prior {
-  border-collapse: collapse;
-}
+
 table.thinborder tr th {
   border-style: solid;
   border-width: 1px;
   background: $tabbg;
 }
-table.thinborder tr td, 
-table.LC_optres_prior tr td {
+table.thinborder tr td {
   border-style: solid;
   border-width: 1px
 }
@@ -3825,12 +3841,23 @@ td.LC_table_cell_checkbox {
   text-align: center;
 }
 
+table#LC_mainmenu td.LC_mainmenu_column {
+    vertical-align: top;
+}
+
 .LC_menubuttons_inline_text {
   color: $font;
   font-family: $sans;
   font-size: smaller;
 }
 
+.LC_menubuttons_category {
+  color: $font;
+  font-family: $sans;
+  font-size: larger;
+  font-weight: bold;
+}
+
 td.LC_menubuttons_text {
   color: $font;
   font-family: $sans;
@@ -3872,7 +3899,8 @@ table.LC_nested {
   border-spacing: 0px;
   width: 100%;
 }
-table.LC_data_table tr th, table.LC_calendar tr th, table.LC_mail_list tr th {
+table.LC_data_table tr th, table.LC_calendar tr th, table.LC_mail_list tr th,
+table.LC_prior_tries tr th {
   font-weight: bold;
   background-color: $data_table_head;
   font-size: smaller;
@@ -4249,6 +4277,61 @@ span.LC_feedback_link {
     font-size: larger;
 }
 
+table.LC_prior_tries {
+  border: 1px solid #000000;
+  border-collapse: separate;
+  border-spacing: 1px;
+}
+
+table.LC_prior_tries td {
+  padding: 2px;
+}
+
+.LC_answer_correct {
+  background: #AAFFAA;
+  color: black;
+}
+.LC_answer_charged_try {
+  background: #FFAAAA ! important;
+  color: black;
+}
+.LC_answer_not_charged_try, 
+.LC_answer_no_grade,
+.LC_answer_late {
+  background: #FFFFAA;
+  color: black;
+}
+.LC_answer_previous {
+  background: #AAAAFF;
+  color: black;
+}
+.LC_answer_no_message {
+  background: #FFFFFF;
+  color: black;
+}
+.LC_answer_unknown {
+  background: orange;
+  color: black;
+}
+
+
+span.LC_prior_numerical {
+  font-family: monospace;
+  white-space: pre;
+}
+
+table.LC_prior_option {
+  width: 100%;
+  border-collapse: collapse;
+}
+table.LC_prior_option tr td {
+  border: 1px solid #000000;
+}
+
+span.LC_nobreak {
+    white-space: nowrap;
+}
+
 END
 }
 
@@ -4291,7 +4374,7 @@ sub headtag {
     my $bgcolor  = $args->{'bgcolor'}  || &designparm($function.'.pgbg',$domain);
     my $url = join(':',$env{'user.name'},$env{'user.domain'},
 		   $Apache::lonnet::perlvar{'lonVersion'},
-		   #time(),
+		   time(),
 		   $env{'environment.color.timestamp'},
 		   $function,$domain,$bgcolor);