       1 #!/usr/bin/perl -w
       2 #
       3 # File: SDFilesToHTML.pl
       4 # Author: Manish Sud <msud@san.rr.com>
       5 #
       6 # Copyright (C) 2018 Manish Sud. All rights reserved.
       7 #
       8 # This file is part of MayaChemTools.
       9 #
      10 # MayaChemTools is free software; you can redistribute it and/or modify it under
      11 # the terms of the GNU Lesser General Public License as published by the Free
      12 # Software Foundation; either version 3 of the License, or (at your option) any
      13 # later version.
      14 #
      15 # MayaChemTools is distributed in the hope that it will be useful, but without
      16 # any warranty; without even the implied warranty of merchantability of fitness
      17 # for a particular purpose.  See the GNU Lesser General Public License for more
      18 # details.
      19 #
      20 # You should have received a copy of the GNU Lesser General Public License
      21 # along with MayaChemTools; if not, see <http://www.gnu.org/licenses/> or
      22 # write to the Free Software Foundation Inc., 59 Temple Place, Suite 330,
      23 # Boston, MA, 02111-1307, USA.
      24 #
      25
      26 use strict;
      27 use FindBin; use lib "$FindBin::Bin/../lib";
      28 use Getopt::Long;
      29 use File::Basename;
      30 use File::Spec;
      31 use Text::ParseWords;
      32 use Benchmark;
      33 use Cwd;
      34 use FileUtil;
      35 use SDFileUtil;
      36 use TextUtil;
      37 use HTMLUtil;
      38
      39 my($ScriptName, %Options, $StartTime, $EndTime, $TotalTime);
      40
      41 # Autoflush STDOUT
      42 $| = 1;
      43
      44 # Starting message...
      45 $ScriptName = basename($0);
      46 print "\n$ScriptName: Starting...\n\n";
      47 $StartTime = new Benchmark;
      48
      49 # Get the options and setup script...
      50 SetupScriptUsage();
      51 if ($Options{help} || @ARGV < 1) {
      52   die GetUsageFromPod("$FindBin::Bin/$ScriptName");
      53 }
      54
      55 my(@SDFilesList);
      56 @SDFilesList = ExpandFileNames(\@ARGV, "sdf sd");
      57
      58 #Make sure appropriate mode specific option values are specified...
      59 print "Processing options...\n";
      60 my(%OptionsInfo);
      61 ProcessOptions();
      62
      63 # Collect information about SD files...
      64 print "Checking input SD file(s)...\n";
      65 my(%SDFilesInfo);
      66 RetrieveSDFilesInfo();
      67 SetupMultipleTablesAndMiscInfo();
      68
      69 # Generate output files...
      70 my($FileIndex);
      71 if (@SDFilesList > 1) {
      72   print "\nProcessing SD files...\n";
      73 }
      74 for $FileIndex (0 .. $#SDFilesList) {
      75   if ($SDFilesInfo{FileOkay}[$FileIndex]) {
      76     print "\nProcessing file $SDFilesList[$FileIndex]...\n";
      77     GenerateHTMLTable($FileIndex);
      78   }
      79 }
      80 print "\n$ScriptName:Done...\n\n";
      81
      82 $EndTime = new Benchmark;
      83 $TotalTime = timediff ($EndTime, $StartTime);
      84 print "Total time: ", timestr($TotalTime), "\n";
      85
      86 ###############################################################################
      87
      88 # Generate HTML table(s)...
      89 sub GenerateHTMLTable {
      90   my($Index) = @_;
      91
      92   if ($SDFilesInfo{MultipleHTMLTables}[$Index]) {
      93     GenerateMultipleHTMLTables($Index);
      94   }
      95   else {
      96     GenerateOneHTMLTable($Index);
      97   }
      98 }
      99
     100 # Generate one HTML table...
     101 sub GenerateOneHTMLTable {
     102   my($Index) = @_;
     103   my($SDFile, $TopHTMLDir, $HTMLFile, $StartCmpdNum, $EndCmpdNum, $CSSFile, $CSSRef, $CSSFilePath, $TableNum);
     104
     105   $HTMLFile = $SDFilesInfo{HTMLRoot}[$Index] . ".html";
     106   $SDFile = $SDFilesList[$Index];
     107
     108   # Setup data directories...
     109   ($TopHTMLDir) = SetupDataDirs($Index);
     110
     111   # Setup stylesheet file...
     112   $CSSRef = "";
     113   if ($Options{stylesheet} =~ /^new$/i) {
     114     $CSSFile = $SDFilesInfo{HTMLRoot}[$Index] . ".css"; $CSSRef = ".\/" . "$CSSFile";
     115     $CSSFilePath = "$TopHTMLDir" . "\/" . $CSSFile;
     116     GenerateStyleSheetFile($CSSFilePath);
     117   }
     118   elsif ($Options{stylesheet} =~ /^old$/i) {
     119     $CSSRef = $Options{stylesheetname};
     120   }
     121
     122   # Set HTML file location...
     123   $HTMLFile = "$TopHTMLDir" . "\/" . $HTMLFile;
     124
     125   print "Generating HTML file $HTMLFile...\n";
     126   open HTMLFILE, ">$HTMLFile" or die "Error: Can't open $HTMLFile: $! \n";
     127   open SDFILE, "$SDFile" or die "Error: Can't open $SDFile: $! \n";
     128
     129   # Write out HTML page header...
     130   print HTMLFILE SetupHTMLPageHeader($SDFilesInfo{HTMLTitle}[$Index], $CSSRef, $OptionsInfo{TopHTMLDirStrViewerJSFileRef});
     131
     132   if ($OptionsInfo{StrViewerJSFileRef}) {
     133     print HTMLFILE SetupStrViewerJSInitCmd($OptionsInfo{StrViewerType}, $OptionsInfo{TopHTMLDirStrViewerCodeBase});
     134   }
     135
     136   # Setup page title...
     137   if ($OptionsInfo{TitleDisplay}) {
     138     print HTMLFILE SetupHTMLPageTitle($SDFilesInfo{HTMLTitle}[$Index]);
     139   }
     140   else {
     141     print HTMLFILE SetupHTMLEmptyLines(1);
     142   }
     143
     144   # Start the table...
     145   print HTMLFILE SetupHTMLAlignmentBegin("center");
     146   print HTMLFILE SetupHTMLTableHeader($OptionsInfo{TableBorder}, $OptionsInfo{TableCellPadding}, $OptionsInfo{TableCellSpacing});
     147
     148   # Generate table rows...
     149   $StartCmpdNum = 1;
     150   $EndCmpdNum = $SDFilesInfo{CmpdCount}[$Index];
     151   $TableNum = 1;
     152   GenerateTableRows($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, \*SDFILE, \*HTMLFILE);
     153
     154   # Finish up the table...
     155   print HTMLFILE SetupHTMLTableEnd();
     156   print HTMLFILE SetupHTMLAlignmentEnd("center");
     157
     158   # Write out HTML page end...
     159   print HTMLFILE SetupHTMLPageEnd($OptionsInfo{FooterMsg});
     160
     161   close HTMLFILE;
     162   close SDFILE;
     163 }
     164
     165 # Generate multiple tables...
     166 sub GenerateMultipleHTMLTables {
     167   my($Index) = @_;
     168   my($TopHTMLDir, $SubHTMLDir, $SDFile, $HTMLFile, $TableNum, $TableCount, $TableIndex, $TableStartCmpdNum, $TableEndCmpdNum, $PrintMsg, $CSSFile, $CSSRef, $CSSFilePath, $NewStyleSheet, $StrViewerCodeBase, $StrViewerJSFileRef);
     169
     170   # Open SD file...
     171   $SDFile = $SDFilesList[$Index];
     172   open SDFILE, "$SDFile" or die "Error: Can't open $SDFile: $! \n";
     173
     174   # Set up data directories to hold various html files...
     175   ($TopHTMLDir, $SubHTMLDir) = SetupDataDirs($Index);
     176
     177   # Create stylesheet file...
     178   $CSSRef = "";
     179   $NewStyleSheet = 0;
     180   if ($Options{stylesheet} =~ /^new$/i) {
     181     $NewStyleSheet = 1;
     182     $CSSFile = $SDFilesInfo{HTMLRoot}[$Index] . ".css";
     183     $CSSFilePath = "$TopHTMLDir" . "\/" . $CSSFile;
     184     GenerateStyleSheetFile($CSSFilePath);
     185   }
     186   elsif ($Options{stylesheet} =~ /^old$/i) {
     187     $CSSRef = $Options{stylesheetname};
     188   }
     189
     190   $PrintMsg = 1;
     191   # Generate HTML files for all the tables...
     192   $TableCount = $SDFilesInfo{TableCount}[$Index];
     193   for $TableNum (1 .. $TableCount) {
     194     $TableIndex = $TableNum - 1;
     195     $HTMLFile = ${$SDFilesInfo{TableHTMLFiles}[$Index]}[$TableIndex];
     196     $TableStartCmpdNum = ${$SDFilesInfo{TableStartCmpdNum}[$Index]}[$TableIndex];
     197     $TableEndCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$TableIndex];
     198
     199     # Setup file name...
     200     if ($TableNum == 1) {
     201       $HTMLFile = "$TopHTMLDir" . "\/" . $HTMLFile;
     202       print "Generating HTML file $HTMLFile...\n";
     203     }
     204     else {
     205       $HTMLFile = "$SubHTMLDir" . "\/" . $HTMLFile;
     206       if ($PrintMsg) {
     207         $PrintMsg = 0;
     208         if ($TableCount == 2) {
     209           print "Generating HTML file $HTMLFile...\n";
     210         }
     211         else {
     212           print "Generating ", ($TableCount - 1), " other HTML files: $SubHTMLDir\/$SDFilesInfo{HTMLRoot}[$Index]\*.html...\n";
     213         }
     214       }
     215     }
     216     # Setup stylesheet reference...
     217     if ($NewStyleSheet) {
     218       $CSSRef = ($TableNum == 1) ? ".\/" : "..\/";
     219       $CSSRef .= $CSSFile;
     220     }
     221
     222     open HTMLFILE, ">$HTMLFile" or die "Error: Can't open $HTMLFile: $! \n";
     223     # Write out HTML page header...
     224     $StrViewerJSFileRef = ($TableNum == 1) ? $OptionsInfo{TopHTMLDirStrViewerJSFileRef} : $OptionsInfo{SubHTMLDirStrViewerJSFileRef};
     225     print HTMLFILE SetupHTMLPageHeader($SDFilesInfo{HTMLTitle}[$Index], $CSSRef, $StrViewerJSFileRef);
     226
     227     if ($OptionsInfo{StrViewerJSFileRef}) {
     228       $StrViewerCodeBase = ($TableNum == 1) ? $OptionsInfo{TopHTMLDirStrViewerCodeBase} : $OptionsInfo{SubHTMLDirStrViewerCodeBase};
     229       print HTMLFILE SetupStrViewerJSInitCmd($OptionsInfo{StrViewerType}, $StrViewerCodeBase);
     230     }
     231
     232     # Set up the navigation links for this table...
     233     if ($OptionsInfo{NavLinksAtTop}) {
     234       WriteNavigationLinks($Index, $TableNum, \*HTMLFILE);
     235     }
     236     # Setup page title...
     237     if ($OptionsInfo{TitleDisplay}) {
     238       print HTMLFILE SetupHTMLPageTitle($SDFilesInfo{HTMLTitle}[$Index]);
     239     }
     240     else {
     241       print HTMLFILE SetupHTMLEmptyLines(1);
     242     }
     243
     244     # Start the table...
     245     print HTMLFILE SetupHTMLAlignmentBegin("center");
     246     print HTMLFILE SetupHTMLTableHeader($OptionsInfo{TableBorder}, $OptionsInfo{TableCellPadding}, $OptionsInfo{TableCellSpacing});
     247
     248     # Generate table content...
     249     GenerateTableRows($Index, $TableNum, $TableStartCmpdNum, $TableEndCmpdNum, \*SDFILE, \*HTMLFILE);
     250
     251     # Finish up the table...
     252     print HTMLFILE SetupHTMLTableEnd();
     253     print HTMLFILE SetupHTMLAlignmentEnd("center");
     254
     255     # Set up the navigation links for this table...
     256     if ($OptionsInfo{NavLinksAtBottom}) {
     257       print HTMLFILE SetupHTMLEmptyLines(1);
     258       WriteNavigationLinks($Index, $TableNum, \*HTMLFILE);
     259     }
     260
     261     # Write out HTML page end...
     262     print HTMLFILE SetupHTMLPageEnd($OptionsInfo{FooterMsg});
     263     close HTMLFILE;
     264   }
     265   close SDFILE;
     266
     267 }
     268
     269 # Generate table content...
     270 sub GenerateTableRows {
     271   my($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, $SDFileRef, $HTMLFileRef) = @_;
     272
     273   if ($OptionsInfo{StructuresOnlyMode}) {
     274     WriteRowStructures($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, $SDFileRef, $HTMLFileRef);
     275   }
     276   else {
     277     WriteColLabels($Index, $SDFileRef, $HTMLFileRef);
     278     WriteRowValues($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, $SDFileRef, $HTMLFileRef);
     279   }
     280 }
     281
     282 # Create stylesheet file...
     283 sub GenerateStyleSheetFile {
     284   my($CSSFile) = @_;
     285     print "Generating stylesheet file $CSSFile...\n";
     286     open CSSFILE, ">$CSSFile" or die "Error: Can't open $CSSFile: $! \n";
     287     print CSSFILE SetupHTMLStyleSheetTags();
     288     close CSSFILE;
     289 }
     290
     291 # Write out table header using column labels...
     292 sub WriteColLabels {
     293   my($Index, $SDFileRef, $HTMLFileRef) = @_;
     294
     295   my(@ColLabels, $Label);
     296   print $HTMLFileRef $SDFilesInfo{TableRowHeaderTags};
     297
     298   # Write out structure label...
     299   $Label = "Structure";
     300   print $HTMLFileRef SetupHTMLTableRowHeaderValue($Label);
     301
     302   # Write out field values..
     303   @ColLabels = @{$SDFilesInfo{SpecifiedDataFieldLabels}[$Index]};
     304   for $Label (@ColLabels) {
     305     print $HTMLFileRef SetupHTMLTableRowHeaderValue($Label);
     306   }
     307   print $HTMLFileRef $SDFilesInfo{RowEndTags};
     308 }
     309
     310 # Write out the rows value...
     311 sub WriteRowValues {
     312   my($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, $SDFileRef, $HTMLFileRef) = @_;
     313   my($BackgroundColor, $FontColor, $RowNum, $CmpdNum, $CmpdString, @CmpdLines, $Label, %DataFieldValues, $Value);
     314
     315   $RowNum = 0;
     316   for $CmpdNum ($StartCmpdNum .. $EndCmpdNum) {
     317     $RowNum++;
     318     $CmpdString = ReadCmpdString($SDFileRef);
     319     if ($OptionsInfo{ShadeRowsStatus}) {
     320       print $HTMLFileRef ($RowNum % 2) ? $SDFilesInfo{BgFilledOddRowHeaderTags} : $SDFilesInfo{BgFilledEvenRowHeaderTags};
     321     }
     322     else {
     323       print $HTMLFileRef $SDFilesInfo{RowHeaderTags};
     324     }
     325     @CmpdLines = split "\n", $CmpdString;
     326     %DataFieldValues = GetCmpdDataHeaderLabelsAndValues(\@CmpdLines);
     327
     328     # Setup structure column...
     329     SetupStructureColumn($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
     330     # Write out field values..
     331     for $Label (@{$SDFilesInfo{SpecifiedDataFieldLabels}[$Index]}) {
     332       $Value = (IsNotEmpty($DataFieldValues{$Label})) ? $DataFieldValues{$Label} : "";
     333       $BackgroundColor = ""; $FontColor = "";
     334       if ($OptionsInfo{HighlightStatus}) {
     335         if (exists($OptionsInfo{SpecifiedHighlightDataFieldLabelsMap}{$Label})) {
     336           ($BackgroundColor, $FontColor) = GetValueHighlightColors($Label, $Value);
     337         }
     338       }
     339       print $HTMLFileRef SetupHTMLTableRowDataValue($Value, $BackgroundColor, $FontColor);
     340     }
     341     print $HTMLFileRef $SDFilesInfo{RowEndTags};
     342   }
     343 }
     344
     345 # Write only structures...
     346 sub WriteRowStructures {
     347   my($Index, $TableNum, $StartCmpdNum, $EndCmpdNum, $SDFileRef, $HTMLFileRef) = @_;
     348   my($CmpdNum, $CmpdString, $StartRowFlag, $ColNum, $RowNum, $RowBgColor, $RowStartTags, $ColumnHeaderTags, $ColumnEndTags, $CmpdDataFieldValue, $CmpdHTMLFileRef, $Value);
     349
     350   $StartRowFlag = 1; $ColNum = 0; $RowNum = 0;
     351   $ColumnHeaderTags = SetupHTMLTableColumnHeader();
     352   $ColumnEndTags = SetupHTMLTableColumnEnd();
     353
     354   if ($OptionsInfo{StructuresOnlyMode} && !$OptionsInfo{TableBorder} && ($OptionsInfo{OddRowsShadeColor} =~ /^(#ffffff|white)$/i)) {
     355     print $HTMLFileRef SetupHTMLTableRowHeader($OptionsInfo{RowHAlignment}, $OptionsInfo{TableHeaderRowColor}, $OptionsInfo{RowVAlignment});
     356     $Value = SetupHTMLTableRowDataValue("");
     357     print $HTMLFileRef InsertHTMLTags($Value, "colspan", "$OptionsInfo{StrTableCols}");
     358     print $HTMLFileRef $SDFilesInfo{RowEndTags};
     359   }
     360
     361   for $CmpdNum ($StartCmpdNum .. $EndCmpdNum) {
     362     $CmpdString = ReadCmpdString($SDFileRef);
     363     if ($StartRowFlag) {
     364       $StartRowFlag = 0;
     365       $RowNum++;
     366       if ($OptionsInfo{ShadeRowsStatus}) {
     367         print $HTMLFileRef ($RowNum % 2) ? $SDFilesInfo{BgFilledOddRowHeaderTags} : $SDFilesInfo{BgFilledEvenRowHeaderTags};
     368       }
     369       else {
     370         print $HTMLFileRef $SDFilesInfo{RowHeaderTags};
     371       }
     372     }
     373     $ColNum++;
     374
     375     $CmpdDataFieldValue = "";
     376     if ($OptionsInfo{CmpdDataField}) {
     377       my($CmpdDataField, @CmpdLines, %DataFieldValues);
     378       $CmpdDataField = $OptionsInfo{CmpdDataField};
     379       @CmpdLines = split "\n", $CmpdString;
     380       %DataFieldValues = GetCmpdDataHeaderLabelsAndValues(\@CmpdLines);
     381       if (exists($DataFieldValues{$CmpdDataField}) && length($DataFieldValues{$CmpdDataField})) {
     382         $CmpdDataFieldValue = $DataFieldValues{$CmpdDataField};
     383         if ($OptionsInfo{CmpdDataFieldLabel} =~ /^yes$/i) {
     384           $CmpdDataFieldValue = "${CmpdDataField}: ${CmpdDataFieldValue}";
     385         }
     386         # Make sure it's not to looong...
     387         if (length($CmpdDataFieldValue) > 30) {
     388           $CmpdDataFieldValue = substr($CmpdDataFieldValue, 0, 30) . "...";
     389         }
     390       }
     391     }
     392     if ($CmpdDataFieldValue) {
     393       $RowBgColor = "";
     394       if ($OptionsInfo{ShadeRowsStatus}) {
     395         $RowBgColor = ($RowNum % 2) ? $OptionsInfo{OddRowsShadeColor} : $OptionsInfo{EvenRowsShadeColor};
     396       }
     397       $RowStartTags = SetupHTMLTableRowHeader($OptionsInfo{CmpdDataFieldAlignment}, $RowBgColor, "middle");
     398       # Start  a new table in current column...
     399       print $HTMLFileRef $ColumnHeaderTags;
     400       print $HTMLFileRef SetupHTMLAlignmentBegin("center");
     401       print $HTMLFileRef SetupHTMLTableHeader(0, 0, 0);
     402
     403       if ($OptionsInfo{CmpdDataFieldPosition} =~ /^top$/i ) {
     404         # Add an empty row...
     405         print $HTMLFileRef $RowStartTags;
     406         print $HTMLFileRef SetupHTMLTableRowDataValue("");
     407         print $HTMLFileRef $SDFilesInfo{RowEndTags};
     408
     409         # Display the label value...
     410         print $HTMLFileRef $RowStartTags;
     411         $CmpdHTMLFileRef = SetupCompoundSummaryFileAndLink($Index, $TableNum, $CmpdString, $CmpdNum);
     412         $Value = SetupHTMLHRef("$CmpdDataFieldValue", $CmpdHTMLFileRef, "Compound Summary");
     413         print $HTMLFileRef SetupHTMLTableRowDataValue($Value);
     414         print $HTMLFileRef $SDFilesInfo{RowEndTags};
     415       }
     416       # Display the structure...
     417       print $HTMLFileRef SetupHTMLTableRowHeader("center", $RowBgColor, "middle");
     418       SetupStructureDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
     419       print $HTMLFileRef $SDFilesInfo{RowEndTags};
     420
     421       if ($OptionsInfo{CmpdDataFieldPosition} =~ /^bottom$/i ) {
     422         # Display the label value...
     423         print $HTMLFileRef $RowStartTags;
     424         $CmpdHTMLFileRef = SetupCompoundSummaryFileAndLink($Index, $TableNum, $CmpdString, $CmpdNum);
     425         $Value = SetupHTMLHRef("$CmpdDataFieldValue", $CmpdHTMLFileRef, "Compound Summary");
     426         print $HTMLFileRef SetupHTMLTableRowDataValue($Value);
     427         print $HTMLFileRef $SDFilesInfo{RowEndTags};
     428
     429         # Add an empty row...
     430         print $HTMLFileRef $RowStartTags;
     431         print $HTMLFileRef SetupHTMLTableRowDataValue("");
     432         print $HTMLFileRef $SDFilesInfo{RowEndTags};
     433       }
     434
     435       print $HTMLFileRef SetupHTMLTableEnd();
     436       print $HTMLFileRef SetupHTMLAlignmentEnd("center");
     437       print $HTMLFileRef $ColumnEndTags;
     438     }
     439     else {
     440       SetupStructureDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
     441     }
     442
     443     if ($ColNum == $OptionsInfo{StrTableCols}) {
     444       # Finish up the current row and get ready for starting a new row...
     445       print $HTMLFileRef $SDFilesInfo{RowEndTags};
     446       $ColNum = 0;
     447       $StartRowFlag = 1;
     448     }
     449   }
     450   if (!$StartRowFlag) {
     451     # Finish up an existing row...
     452     my($ColIndex, $Value);
     453     $Value = "";
     454     for $ColIndex ($ColNum .. ($OptionsInfo{StrTableCols} - 1) ) {
     455       print $HTMLFileRef SetupHTMLTableRowDataValue($Value);
     456     }
     457     print $HTMLFileRef $SDFilesInfo{RowEndTags};
     458   }
     459 }
     460
     461 # Setup structure column...
     462 sub SetupStructureColumn {
     463   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
     464
     465   if ($OptionsInfo{DisplayStructure}) {
     466     SetupStructureDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
     467   }
     468   else {
     469     SetupStructureLink($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
     470   }
     471 }
     472
     473 # Setup structure display for compound summary page...
     474 sub SetupStructureDisplayForCmpdSummaryPage {
     475   my($Index, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
     476   my($TableNum, $RowNum);
     477
     478   # Use table num 0 to force usage of "../mol" prefix for all MOL file references. Row num
     479   # doesn't matter...
     480   $TableNum = 0;
     481   $RowNum = 1;
     482
     483   $OptionsInfo{SettingUpCmpdSummaryPage} = 1;
     484
     485   # Setup size and bgcolor parameters for linking structures...
     486   $OptionsInfo{StrViewerParams}{width} = $OptionsInfo{StrLinkWidth};
     487   $OptionsInfo{StrViewerParams}{height} = $OptionsInfo{StrLinkHeight};
     488   $OptionsInfo{StrViewerParams}{bgcolor} = $OptionsInfo{StrLinkBgColorSpecified};
     489
     490   SetupStructureDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef);
     491
     492   # Reset size and bgcolor parameters back to displaying structures in tables...
     493   $OptionsInfo{StrViewerParams}{width} = $OptionsInfo{StrWidth};
     494   $OptionsInfo{StrViewerParams}{height} = $OptionsInfo{StrHeight};
     495   $OptionsInfo{StrViewerParams}{bgcolor} = $OptionsInfo{StrBgColorSpecified} ? $OptionsInfo{StrBgColorSpecified} : "";
     496
     497   $OptionsInfo{SettingUpCmpdSummaryPage} = 0;
     498 }
     499
     500
     501 # Setup structure column display...
     502 sub SetupStructureDisplay {
     503   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
     504   my($Nothing);
     505
     506  STRVIEWERTYPE: {
     507     if ($OptionsInfo{StrViewerType} =~ /^JME$/i) { SetupJMEDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
     508     if ($OptionsInfo{StrViewerType} =~ /^Jmol$/i) { SetupJmolDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
     509     if ($OptionsInfo{StrViewerType} =~ /^Chime$/i) { SetupChimeDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
     510     if ($OptionsInfo{StrViewerType} =~ /^(Chem3DActiveX|ChemDrawActiveX|ChemDrawPlugIn)$/i) { SetupCambridgeSoftDisplay($OptionsInfo{StrViewerType}, $Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
     511     if ($OptionsInfo{StrViewerType} =~ /^MarvinView$/i) { SetupMarvinDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
     512     if ($OptionsInfo{StrViewerType} =~ /^ViewerActiveX$/i) { SetupViewerAccelrysActiveXDisplay($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef); last STRVIEWERTYPE; }
     513     $Nothing = 1;
     514   }
     515 }
     516
     517 # Setup JME display...
     518 sub SetupJMEDisplay {
     519   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
     520   my($MolString, $AppletBGColor, $Value, $ValueTag, $AppletName, $StrViewerCodeBase);
     521
     522   $Value = "";
     523   ($MolString) = split "$SDFilesInfo{MolEndTag}", $CmpdString;
     524   if (IsNotEmpty($MolString)) {
     525     $AppletBGColor = SetupStructureBGColor($RowNum);
     526     $MolString .= "$SDFilesInfo{MolEndTag}";
     527
     528     # JME viewer doesn't appear to support "bgcolor" param. So, always use white background for
     529     # structure cell...
     530     $AppletName = "JME" . $CmpdNum;
     531     $OptionsInfo{StrViewerParams}{name} = $AppletName;
     532     if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
     533       if (!$OptionsInfo{StrBgColorSpecified}) {
     534         $OptionsInfo{StrViewerParams}{bgcolor} = $AppletBGColor;
     535       }
     536     }
     537     $StrViewerCodeBase = ($TableNum == 1) ? $OptionsInfo{TopHTMLDirStrViewerCodeBase} : $OptionsInfo{SubHTMLDirStrViewerCodeBase};
     538     $Value = SetupStrViewerJMEApplet($MolString, $StrViewerCodeBase, \%{$OptionsInfo{StrViewerParams}});
     539     $ValueTag = SetupHTMLTableRowDataValue($Value, $SDFilesInfo{White});
     540   }
     541   else {
     542     $ValueTag = SetupHTMLTableRowDataValue($Value);
     543   }
     544   if ($OptionsInfo{SettingUpCmpdSummaryPage}) {
     545     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
     546   }
     547   print $HTMLFileRef $ValueTag;
     548 }
     549
     550 # Setup Marvin display...
     551 sub SetupMarvinDisplay {
     552   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
     553   my($MolString, $AppletBGColor, $Value, $ValueTag, $AppletName, $StrViewerCodeBase);
     554
     555   $Value = "";
     556   ($MolString) = split "$SDFilesInfo{MolEndTag}", $CmpdString;
     557   if (IsNotEmpty($MolString)) {
     558     $AppletBGColor = SetupStructureBGColor($RowNum);
     559     $MolString .= "$SDFilesInfo{MolEndTag}";
     560
     561     $AppletName = "MView" . $CmpdNum;
     562     $OptionsInfo{StrViewerParams}{name} = $AppletName;
     563     if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
     564       if (!$OptionsInfo{StrBgColorSpecified}) {
     565         $OptionsInfo{StrViewerParams}{bgcolor} = $AppletBGColor;
     566       }
     567     }
     568     $StrViewerCodeBase = ($TableNum == 1) ? $OptionsInfo{TopHTMLDirStrViewerCodeBase} : $OptionsInfo{SubHTMLDirStrViewerCodeBase};
     569     $Value = SetupStrViewerMarvinViewApplet($MolString, $StrViewerCodeBase, \%{$OptionsInfo{StrViewerParams}});
     570     $ValueTag = SetupHTMLTableRowDataValue($Value);
     571   }
     572   else {
     573     $ValueTag = SetupHTMLTableRowDataValue($Value);
     574   }
     575   if ($OptionsInfo{SettingUpCmpdSummaryPage}) {
     576     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
     577   }
     578   print $HTMLFileRef $ValueTag;
     579 }
     580
     581 # Setup Jmol display...
     582 sub SetupJmolDisplay {
     583   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
     584   my($MolString, $AppletBGColor, $Value, $ValueTag, $AppletName, $StrViewerCodeBase);
     585
     586   $Value = ""; $ValueTag = "";
     587   ($MolString) = split "$SDFilesInfo{MolEndTag}", $CmpdString;
     588   if (IsNotEmpty($MolString)) {
     589     $AppletBGColor = SetupStructureBGColor($RowNum);
     590     $MolString .= "$SDFilesInfo{MolEndTag}";
     591
     592     # Make sure MolName line is not empty; otherwise, JMol doesn't display structure...
     593     my(@MolLines) = split "\n", $MolString;
     594     if (IsEmpty($MolLines[0])) {
     595       $MolLines[0] = "Cmpd${CmpdNum}";
     596       $MolString = join "\n", @MolLines;
     597     }
     598
     599     # Setup the applet...
     600     $AppletName = "Jmol" . $CmpdNum;
     601     $OptionsInfo{StrViewerParams}{name} = $AppletName;
     602     if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
     603       if (!$OptionsInfo{StrBgColorSpecified}) {
     604         $OptionsInfo{StrViewerParams}{bgcolor} = $AppletBGColor;
     605       }
     606     }
     607     $StrViewerCodeBase = ($TableNum == 1) ? $OptionsInfo{TopHTMLDirStrViewerCodeBase} : $OptionsInfo{SubHTMLDirStrViewerCodeBase};
     608     $Value = SetupStrViewerJmolApplet($MolString, $StrViewerCodeBase, \%{$OptionsInfo{StrViewerParams}});
     609     $ValueTag = SetupHTMLTableRowDataValue($Value);
     610   }
     611   else {
     612     $ValueTag = SetupHTMLTableRowDataValue($Value);
     613   }
     614   if ($OptionsInfo{SettingUpCmpdSummaryPage}) {
     615     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
     616   }
     617   print $HTMLFileRef $ValueTag;
     618 }
     619
     620 # Setup Chime display...
     621 sub SetupChimeDisplay {
     622   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
     623   my($MolString, $BGColor, $Value, $ValueTag, $MolFileRef);
     624
     625   $Value = "";
     626   ($MolString) = split "$SDFilesInfo{MolEndTag}", $CmpdString;
     627   if (IsNotEmpty($MolString)) {
     628     $BGColor = SetupStructureBGColor($RowNum);
     629     $MolString .= "$SDFilesInfo{MolEndTag}";
     630     # Write out MOL file...
     631     $MolFileRef = SetupMOLFile($Index, $TableNum, $MolString, $CmpdNum);
     632     # Setup the applet...
     633     if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
     634       if (!$OptionsInfo{StrBgColorSpecified}) {
     635         $OptionsInfo{StrViewerParams}{bgcolor} = $BGColor;
     636       }
     637     }
     638     $Value = SetupStrViewerChimePlugIn($MolFileRef, \%{$OptionsInfo{StrViewerParams}});
     639     $ValueTag = SetupHTMLTableRowDataValue($Value);
     640   }
     641   else {
     642     $ValueTag = SetupHTMLTableRowDataValue($Value);
     643   }
     644   if ($OptionsInfo{SettingUpCmpdSummaryPage}) {
     645     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
     646   }
     647   print $HTMLFileRef $ValueTag;
     648 }
     649
     650 # Setup displays for various viewers available from CambridgeSoft...
     651 sub SetupCambridgeSoftDisplay {
     652   my($ViewerType, $Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
     653   my($MolString, $BGColor, $Value, $ValueTag, $MolFileRef, $Name);
     654
     655   $Value = "";
     656   ($MolString) = split "$SDFilesInfo{MolEndTag}", $CmpdString;
     657   if (IsNotEmpty($MolString)) {
     658     $BGColor = SetupStructureBGColor($RowNum);
     659     $MolString .= "$SDFilesInfo{MolEndTag}";
     660     # Write out MOL file...
     661     $MolFileRef = SetupMOLFile($Index, $TableNum, $MolString, $CmpdNum);
     662     # Setup the viewer...
     663     $Name = "CS" . $CmpdNum;
     664     if ($ViewerType =~ /^Chem3DActiveX$/) {
     665       # Use white background for Chem3D and cell; otherwise, it doesn't look good:
     666       # cell size is larger than Chem3D window size and different colors don't work
     667       $BGColor = $SDFilesInfo{White};
     668       $OptionsInfo{StrViewerParams}{name} = $Name;
     669       if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
     670         if (!$OptionsInfo{StrBgColorSpecified}) {
     671           $OptionsInfo{StrViewerParams}{bgcolor} = $BGColor;
     672         }
     673       }
     674       $Value = SetupStrViewerChem3DActiveX($MolFileRef, \%{$OptionsInfo{StrViewerParams}});
     675       $ValueTag = SetupHTMLTableRowDataValue($Value, $BGColor);
     676     }
     677     elsif ($ViewerType =~ /^ChemDrawActiveX$/i) {
     678       # BGColor is not supported. So, make it all white...
     679       $BGColor = $SDFilesInfo{White};
     680       $OptionsInfo{StrViewerParams}{name} = $Name;
     681       if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
     682         if (!$OptionsInfo{StrBgColorSpecified}) {
     683           $OptionsInfo{StrViewerParams}{bgcolor} = $BGColor;
     684         }
     685       }
     686       $Value = SetupStrViewerChemDrawActiveX($MolFileRef, \%{$OptionsInfo{StrViewerParams}});
     687       $ValueTag = SetupHTMLTableRowDataValue($Value, $BGColor);
     688     }
     689     elsif ($ViewerType =~ /^ChemDrawPlugIn$/i) {
     690       # BGColor is not supported. So, make it all white...
     691       $BGColor = $SDFilesInfo{White};
     692       if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
     693         if (!$OptionsInfo{StrBgColorSpecified}) {
     694           $OptionsInfo{StrViewerParams}{bgcolor} = $BGColor;
     695         }
     696       }
     697       $Value = SetupStrViewerChemDrawPlugIn($MolFileRef, \%{$OptionsInfo{StrViewerParams}});
     698       $ValueTag = SetupHTMLTableRowDataValue($Value, $BGColor);
     699     }
     700   }
     701   else {
     702     $ValueTag = SetupHTMLTableRowDataValue($Value);
     703   }
     704   if ($OptionsInfo{SettingUpCmpdSummaryPage}) {
     705     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
     706   }
     707   print $HTMLFileRef $ValueTag;
     708 }
     709
     710 # Setup Accelrys Viewer ActiveX display...
     711 sub SetupViewerAccelrysActiveXDisplay {
     712   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
     713   my($MolString, $BGColor, $Value, $ValueTag, $Name, $MolFileRef);
     714
     715   $Value = "";
     716   ($MolString) = split "$SDFilesInfo{MolEndTag}", $CmpdString;
     717   if (IsNotEmpty($MolString)) {
     718     $BGColor = SetupStructureBGColor($RowNum);
     719     $MolString .= "$SDFilesInfo{MolEndTag}";
     720     # Write out MOL file. Accelrys ActiveX viewer doesn't load mol files with relative path names.
     721     # So, set up a complete path name for now; however, it may lead to issues during web
     722     # deployment.
     723     my($CompletePath) = 1;
     724     $MolFileRef = SetupMOLFile($Index, $TableNum, $MolString, $CmpdNum, $CompletePath);
     725     # Setup the viewer...
     726     $Name = "ViewerActiveX" . $CmpdNum;
     727     if (!$OptionsInfo{SettingUpCmpdSummaryPage}) {
     728       if (!$OptionsInfo{StrBgColorSpecified}) {
     729         $OptionsInfo{StrViewerParams}{bgcolor} = $BGColor;
     730       }
     731     }
     732     $OptionsInfo{StrViewerParams}{name} = $Name;
     733     $Value = SetupStrViewerAccelrysActiveX($MolFileRef, \%{$OptionsInfo{StrViewerParams}});
     734     $ValueTag = SetupHTMLTableRowDataValue($Value);
     735   }
     736   else {
     737     $ValueTag = SetupHTMLTableRowDataValue($Value);
     738   }
     739   if ($OptionsInfo{SettingUpCmpdSummaryPage}) {
     740     $ValueTag = InsertHTMLTags($ValueTag, ("class", "box"));
     741   }
     742   print $HTMLFileRef $ValueTag;
     743 }
     744
     745
     746 # Setup structure background color...
     747 sub SetupStructureBGColor {
     748   my($RowNum) = @_;
     749   my($BGColor);
     750
     751   $BGColor = "";
     752   if ($OptionsInfo{ShadeRowsStatus}) {
     753     $BGColor =  ($RowNum % 2) ? $OptionsInfo{OddRowsShadeColor} : $OptionsInfo{EvenRowsShadeColor};
     754   }
     755   else {
     756     $BGColor = $SDFilesInfo{White};
     757   }
     758   return $BGColor;
     759 }
     760
     761 # Setup  MDL MOL file...
     762 sub SetupMOLFile {
     763   my($Index, $TableNum, $MolString, $CmpdNum, $CompletePath);
     764   my($SubMolDir, $MolFileName, $MolFile, $MolFileRef);
     765
     766   $CompletePath = "";
     767   if (@_ == 5) {
     768     ($Index, $TableNum, $MolString, $CmpdNum, $CompletePath) = @_;
     769   }
     770   else {
     771     ($Index, $TableNum, $MolString, $CmpdNum) = @_;
     772   }
     773
     774   $SubMolDir = $SDFilesInfo{SubMolDir}[$Index];
     775   $MolFileName = $SDFilesInfo{HTMLRoot}[$Index] . "Cmpd" . $CmpdNum . ".mol";
     776   $MolFile = $SubMolDir . "\/" . $MolFileName;
     777
     778   open MOLFILE, ">$MolFile" or die "Error: Can't open $MolFile: $! \n";
     779   print MOLFILE "$MolString\n";
     780   close MOLFILE;
     781
     782   if ($CompletePath) {
     783     my($CWD, $NewCWD);
     784     $CWD = cwd();
     785     $NewCWD = ConvertCygwinPath($CWD);
     786     $MolFileRef = $NewCWD . "\/" . $SDFilesInfo{TopHTMLDir}[$Index] .  "\/mol\/$MolFileName" ;
     787   }
     788   else {
     789     $MolFileRef = ($TableNum == 1) ? ".\/mol\/$MolFileName" : "..\/mol\/$MolFileName";
     790   }
     791
     792   return $MolFileRef;
     793 }
     794
     795 # Setup a link to structure and other available information...
     796 sub SetupStructureLink {
     797   my($Index, $TableNum, $RowNum, $CmpdString, $CmpdNum, $HTMLFileRef) = @_;
     798   my($CmpdHTMLFileRef, $Value);
     799
     800   $CmpdHTMLFileRef = SetupCompoundSummaryFileAndLink($Index, $TableNum, $CmpdString, $CmpdNum);
     801
     802   if ($Options{strlinktype} =~ /^button$/i) {
     803     $Value = SetupHTMLButtonRef("View", $CmpdHTMLFileRef);
     804   }
     805   else {
     806     $Value = SetupHTMLHRef("View", $CmpdHTMLFileRef);
     807   }
     808   print $HTMLFileRef SetupHTMLTableRowDataValue($Value);
     809 }
     810
     811 # Setup HTML compound summary file and link...
     812 sub SetupCompoundSummaryFileAndLink {
     813   my($Index, $TableNum, $CmpdString, $CmpdNum) = @_;
     814   my($CmpdHTMLFile, $CmpdHTMLFileName, $CmpdHTMLFileRef, $CSSRef, @CmpdLines, $Label, @DataFieldLabels, %DataFieldValues, $Value, $Tag);
     815
     816   # Setup compound file names...
     817   $CmpdHTMLFileName = $SDFilesInfo{HTMLRoot}[$Index] . "Cmpd" . $CmpdNum . ".html";
     818   $CmpdHTMLFile = $SDFilesInfo{SubHTMLDir}[$Index] . "\/" . $CmpdHTMLFileName;
     819
     820   # Setup stylesheet reference....
     821   $CSSRef = "";
     822   if ($Options{stylesheet} =~ /^old$/i) {
     823     $CSSRef = $Options{stylesheetname};
     824   }
     825   else {
     826     $CSSRef = "..\/" . $SDFilesInfo{HTMLRoot}[$Index] . ".css";
     827   }
     828
     829   # Write out compound data in a new HTML file. For summary page, usage of even and odd row shade color
     830   # is reversed: it causes structure background to be white by default...
     831   open CMPDHTMLFILE, ">$CmpdHTMLFile" or die "Error: Can't open $CmpdHTMLFile: $! \n";
     832   print CMPDHTMLFILE SetupHTMLPageHeader($OptionsInfo{StrLinkTitle}, $CSSRef, $OptionsInfo{SubHTMLDirStrViewerJSFileRef});
     833
     834   if ($OptionsInfo{StrViewerJSFileRef}) {
     835     print CMPDHTMLFILE SetupStrViewerJSInitCmd($OptionsInfo{StrViewerType}, $OptionsInfo{SubHTMLDirStrViewerCodeBase});
     836   }
     837
     838   if ($OptionsInfo{StrLinkTitleDisplay}) {
     839     print CMPDHTMLFILE SetupHTMLPageTitle($OptionsInfo{StrLinkTitle}, "center");
     840   }
     841   else {
     842     print CMPDHTMLFILE SetupHTMLEmptyLines(1);
     843   }
     844   print CMPDHTMLFILE SetupHTMLAlignmentBegin("center");
     845
     846   # Setup structure display ...
     847   print CMPDHTMLFILE SetupHTMLTableHeader(0, 5, 2);
     848
     849   print CMPDHTMLFILE SetupHTMLTableRowHeader("center", "#ffffff", "middle");
     850
     851   SetupStructureDisplayForCmpdSummaryPage($Index, $CmpdString, $CmpdNum, \*CMPDHTMLFILE);
     852   print CMPDHTMLFILE $SDFilesInfo{RowEndTags};
     853
     854   if ($Options{strlinkmode} =~ /^plain$/i) {
     855     print CMPDHTMLFILE SetupHTMLTableRowHeader("center", $OptionsInfo{StrLinkShadeColor});
     856     $Tag = SetupHTMLTableRowDataValue("");
     857     print CMPDHTMLFILE $Tag;
     858     print CMPDHTMLFILE $SDFilesInfo{RowEndTags};
     859   }
     860
     861   print CMPDHTMLFILE SetupHTMLTableRowHeader("left", "", "middle");
     862   # Start a new table with two columns, one each for data field labels and values, in
     863   # current column...
     864   print CMPDHTMLFILE SetupHTMLTableColumnHeader();
     865   print CMPDHTMLFILE SetupHTMLAlignmentBegin("left");
     866   print CMPDHTMLFILE SetupHTMLTableHeader(0, 5, 2);
     867
     868   # Setup table for other available data...
     869   my($CmpdRowHeaderTags);
     870   $CmpdRowHeaderTags = SetupHTMLTableRowHeader("left", "", "middle");
     871
     872   @CmpdLines = split "\n", $CmpdString;
     873
     874   @DataFieldLabels = GetCmpdDataHeaderLabels(\@CmpdLines);
     875   %DataFieldValues = GetCmpdDataHeaderLabelsAndValues(\@CmpdLines);
     876
     877   my($LabelWrapLength, $ValueWrapLength, $LabelColWidth);
     878   $LabelWrapLength = 30; $ValueWrapLength = 60; $LabelColWidth = 40;
     879
     880   for $Label (@DataFieldLabels) {
     881     $Value =  $DataFieldValues{$Label};
     882     $Label .= ":";
     883     if ($Label && (length($Label) > $LabelWrapLength)) {
     884       $Label = WrapText($Label,  $LabelWrapLength, "<br>");
     885     }
     886     print CMPDHTMLFILE $CmpdRowHeaderTags;
     887     if ($Options{strlinkmode} =~ /^plain$/i) {
     888       $Tag = SetupHTMLTableRowDataValue($Label, "", "", 1);
     889     }
     890     else {
     891       $Tag = SetupHTMLTableRowDataValue($Label, $OptionsInfo{StrLinkShadeColor});
     892     }
     893     $Tag = InsertHTMLTags($Tag, "width", "$LabelColWidth");
     894     print CMPDHTMLFILE $Tag;
     895
     896     if ($Value && (length($Value) >=$ValueWrapLength) && $Value !~ /a href/i) {
     897       $Value =~ s/(\r\n)|(\r)|\n//g;
     898       $Value = WrapText($Value,  $ValueWrapLength, "<br>");
     899     }
     900     $Tag = SetupHTMLTableRowDataValue($Value);
     901     print CMPDHTMLFILE $Tag;
     902     print CMPDHTMLFILE $SDFilesInfo{RowEndTags};
     903   }
     904
     905   # Finish up table holding numerical data...
     906   print CMPDHTMLFILE SetupHTMLTableEnd();
     907   print CMPDHTMLFILE SetupHTMLAlignmentEnd("left");
     908   print CMPDHTMLFILE SetupHTMLTableColumnEnd();
     909   print CMPDHTMLFILE $SDFilesInfo{RowEndTags};
     910
     911   # Finish up main table...
     912   print CMPDHTMLFILE SetupHTMLTableEnd();
     913   print CMPDHTMLFILE SetupHTMLAlignmentEnd("center");
     914
     915   if ($OptionsInfo{StrLinkNavigation} && ($SDFilesInfo{CmpdCount}[$Index] > 1) ) {
     916     print CMPDHTMLFILE SetupHTMLEmptyLines(1);
     917     WriteCompoundSummaryNavigationLinks($Index, $TableNum, $CmpdNum, \*CMPDHTMLFILE);
     918   }
     919
     920   print CMPDHTMLFILE SetupHTMLPageEnd($OptionsInfo{FooterMsg});
     921   close CMPDHTMLFILE;
     922
     923   # Add a link to compound's HTML file in table cell...
     924   $CmpdHTMLFileRef = ($TableNum == 1) ? ".\/html\/" : ".\/";
     925   $CmpdHTMLFileRef .= $CmpdHTMLFileName;
     926
     927   return $CmpdHTMLFileRef;
     928 }
     929
     930 # Write navigation link information for compound summary page...
     931 sub WriteCompoundSummaryNavigationLinks {
     932   my($Index, $CurTableNum, $CurCmpdNum, $CmpdHTMLFileRef) = @_;
     933   my($FirstTableNum, $CurTableIndex, $FirstCmpdNum, $LastCmpdNum, $PreviousCmpdNum, $NextCmpdNum, $HTMLFile, $HTMLRefFile, $HTMLRefValue);
     934
     935   $FirstTableNum = 1;
     936   $FirstCmpdNum = 1;
     937
     938   $CurTableIndex = $CurTableNum - 1;
     939
     940   if ($SDFilesInfo{MultipleHTMLTables}[$Index]) {
     941     my($FirstTableIndex, $LastTableNum, $LastTableIndex);
     942     $FirstTableIndex = $FirstTableNum - 1;
     943     $LastTableNum = $SDFilesInfo{TableCount}[$Index]; $LastTableIndex = $LastTableNum - 1;
     944     $LastCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$LastTableIndex];
     945   }
     946   else {
     947     $LastCmpdNum = $SDFilesInfo{CmpdCount}[$Index];
     948   }
     949
     950   $PreviousCmpdNum = ($CurCmpdNum == $FirstCmpdNum) ? 0 : ($CurCmpdNum - 1);
     951   $NextCmpdNum = ($CurCmpdNum == $LastCmpdNum) ? 0 : ($CurCmpdNum + 1);
     952
     953   my($InactiveLinkNumColor, $InactiveLinkFontBold) = ("#8e2323", "1");
     954   my($LinkTextColor, $LinkBGColor, $LinkFontBold) = ("", "", "0");
     955   my($BorderWidth, $CellPadding, $CellSpacing) = (0, 2, 2);
     956
     957   # Start link table...
     958   print $CmpdHTMLFileRef SetupHTMLAlignmentBegin("center");
     959   print $CmpdHTMLFileRef SetupHTMLDivBegin("tablenav");
     960   print $CmpdHTMLFileRef  SetupHTMLTableHeader($BorderWidth, $CellPadding, $CellSpacing);
     961   print $CmpdHTMLFileRef $SDFilesInfo{RowHeaderTags};
     962
     963   print $CmpdHTMLFileRef SetupHTMLTableRowDataValue("Compounds: ");
     964
     965   # Setup a link to first compound...
     966   if ($CurCmpdNum != $FirstCmpdNum) {
     967     $HTMLFile = $SDFilesInfo{HTMLRoot}[$Index] . "Cmpd" . $FirstCmpdNum . ".html";
     968     $HTMLRefFile = "./${HTMLFile}";
     969     $HTMLRefValue = SetupHTMLHRef("First", $HTMLRefFile, "First Compound");
     970     print $CmpdHTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
     971   }
     972
     973   # Setup a link to previous compund
     974   if ($PreviousCmpdNum) {
     975     $HTMLFile = $SDFilesInfo{HTMLRoot}[$Index] . "Cmpd" . $PreviousCmpdNum . ".html";
     976     $HTMLRefFile = "./${HTMLFile}";
     977     $HTMLRefValue = SetupHTMLHRef("Previous", $HTMLRefFile, "Previous Compound");
     978     print $CmpdHTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
     979   }
     980
     981   # Setup a link to compound table...
     982   if ($SDFilesInfo{MultipleHTMLTables}[$Index]) {
     983     $HTMLFile = ${$SDFilesInfo{TableHTMLFiles}[$Index]}[$CurTableIndex];
     984   }
     985   else {
     986     $HTMLFile = $SDFilesInfo{HTMLRoot}[$Index] . ".html";
     987   }
     988   $HTMLRefFile = (($CurTableNum == $FirstTableNum) ? "../" : "./") . $HTMLFile;
     989   $HTMLRefValue = SetupHTMLHRef("Table", $HTMLRefFile, "Table With This Compound");
     990   print $CmpdHTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
     991
     992   # Setup a link to next compound...
     993   if ($NextCmpdNum) {
     994     $HTMLFile = $SDFilesInfo{HTMLRoot}[$Index] . "Cmpd" . $NextCmpdNum . ".html";
     995     $HTMLRefFile = "./${HTMLFile}";
     996     $HTMLRefValue = SetupHTMLHRef("Next", $HTMLRefFile, "Next Compound");
     997     print $CmpdHTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
     998   }
     999
    1000   # Setup a link to last compund
    1001   if ($CurCmpdNum != $LastCmpdNum) {
    1002     $HTMLFile = $SDFilesInfo{HTMLRoot}[$Index] . "Cmpd" . $LastCmpdNum . ".html";
    1003     $HTMLRefFile = "./${HTMLFile}";
    1004     $HTMLRefValue = SetupHTMLHRef("Last", $HTMLRefFile, "Last Compound");
    1005     print $CmpdHTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
    1006   }
    1007
    1008   # Setup current table info text....
    1009   print $CmpdHTMLFileRef SetupHTMLTableRowDataValue("&nbsp");
    1010   print $CmpdHTMLFileRef SetupHTMLTableRowDataValue("&nbsp");
    1011   print $CmpdHTMLFileRef SetupHTMLTableRowDataValue("Showing $CurCmpdNum of $LastCmpdNum");
    1012
    1013   print $CmpdHTMLFileRef $SDFilesInfo{RowEndTags};
    1014
    1015   # End link table...
    1016   print $CmpdHTMLFileRef SetupHTMLTableEnd();
    1017   print $CmpdHTMLFileRef SetupHTMLDivEnd();
    1018   print $CmpdHTMLFileRef SetupHTMLAlignmentEnd("center");
    1019 }
    1020
    1021 # Setup navigation link information for each table.
    1022 #
    1023 # All table sets besides first and last have these links: FirstTable, Previous, Current-1,Current,Current+1,  Next, and LastTable
    1024 # First set: Current, Next, and LastTable
    1025 # Last set: FirstTable, Previous and Current.
    1026 #
    1027 sub WriteNavigationLinks {
    1028   my($Index, $CurTableNum, $HTMLFileRef) = @_;
    1029   my($TableNum, $StartTableNum, $EndTableNum, $TableIndex, $BorderWidth, $CellPadding, $CellSpacing,$HTMLFile, $HTMLRefFile, $RelativeFileDir, $HTMLRefValue, $FirstTableNum, $FirstTableIndex, $LastTableNum, $LastTableIndex, $TableStartCmpdNum, $TableEndCmpdNum, $LastCmpdNum, $BGColor, $LinksOffSet);
    1030
    1031   $LinksOffSet = 10;
    1032
    1033   $FirstTableNum = 1; $FirstTableIndex = $FirstTableNum - 1;
    1034   $LastTableNum = $SDFilesInfo{TableCount}[$Index]; $LastTableIndex = $LastTableNum - 1;
    1035   $LastCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$LastTableIndex];
    1036
    1037   # Figure out which links to display for a particular table...
    1038   $StartTableNum = $CurTableNum - $LinksOffSet + 1;
    1039   $StartTableNum = ($StartTableNum < $FirstTableNum) ? $FirstTableNum : $StartTableNum;
    1040   if ($CurTableNum < $LinksOffSet) {
    1041     $EndTableNum = $LinksOffSet;
    1042   }
    1043   else {
    1044     $EndTableNum = $CurTableNum + $LinksOffSet - 1;
    1045   }
    1046   $EndTableNum = ($EndTableNum > $LastTableNum) ? $LastTableNum : $EndTableNum;
    1047
    1048   my($InactiveLinkNumColor, $InactiveLinkFontBold) = ("#8e2323", "1");
    1049   my($LinkTextColor, $LinkBGColor, $LinkFontBold) = ("", "", "1");
    1050
    1051   # Start link table...
    1052   $BorderWidth = 0; $CellPadding = 2; $CellSpacing = 2;
    1053   print $HTMLFileRef SetupHTMLAlignmentBegin("center");
    1054   print $HTMLFileRef SetupHTMLDivBegin("tablenav");
    1055   print $HTMLFileRef  SetupHTMLTableHeader($BorderWidth, $CellPadding, $CellSpacing);
    1056   print $HTMLFileRef $SDFilesInfo{RowHeaderTags};
    1057
    1058   if ($OptionsInfo{NavLinksTableInfo} && $OptionsInfo{NavLinksCmpdInfo}) {
    1059     print $HTMLFileRef SetupHTMLTableRowDataValue("Showing table $CurTableNum of $LastTableNum");
    1060     print $HTMLFileRef SetupHTMLTableRowDataValue("&nbsp");
    1061     print $HTMLFileRef SetupHTMLTableRowDataValue("&nbsp");
    1062   }
    1063
    1064   print $HTMLFileRef SetupHTMLTableRowDataValue("Tables: ");
    1065   # Setup a link to first table...
    1066   if ($StartTableNum != $FirstTableNum) {
    1067     $HTMLFile = ${$SDFilesInfo{TableHTMLFiles}[$Index]}[$FirstTableIndex];
    1068     $HTMLRefFile = GetRelativeFileDir($CurTableNum, $FirstTableNum, $FirstTableNum) . $HTMLFile;
    1069     $TableStartCmpdNum = ${$SDFilesInfo{TableStartCmpdNum}[$Index]}[$FirstTableIndex];
    1070     $TableEndCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$FirstTableIndex];
    1071     $HTMLRefValue = SetupHTMLHRef("First", $HTMLRefFile, "First Table Containing Compounds $TableStartCmpdNum To $TableEndCmpdNum");
    1072     print $HTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
    1073   }
    1074
    1075   # Setup link to previous table...
    1076   if ($CurTableNum != $FirstTableNum) {
    1077     my($PreviousTableNum, $PreviousTableIndex);
    1078     $PreviousTableNum = $CurTableNum - 1; $PreviousTableIndex = $PreviousTableNum - 1;
    1079     $HTMLFile = ${$SDFilesInfo{TableHTMLFiles}[$Index]}[$PreviousTableIndex];
    1080     $HTMLRefFile = GetRelativeFileDir($CurTableNum, $PreviousTableNum, $FirstTableNum) . $HTMLFile;
    1081     $TableStartCmpdNum = ${$SDFilesInfo{TableStartCmpdNum}[$Index]}[$PreviousTableIndex];
    1082     $TableEndCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$PreviousTableIndex];
    1083     $HTMLRefValue = SetupHTMLHRef("Previous", $HTMLRefFile, "Previous Table Containing Compounds $TableStartCmpdNum To $TableEndCmpdNum");
    1084     print $HTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
    1085   }
    1086
    1087   for $TableNum ($StartTableNum .. $EndTableNum) {
    1088     $TableIndex = $TableNum - 1;
    1089     $HTMLFile = ${$SDFilesInfo{TableHTMLFiles}[$Index]}[$TableIndex];
    1090     if ($TableNum == $CurTableNum) {
    1091       print $HTMLFileRef SetupHTMLTableRowDataValue($TableNum, $LinkBGColor, $InactiveLinkNumColor, $InactiveLinkFontBold);
    1092     }
    1093     else {
    1094       # Setup the link...
    1095       my($RefTitle);
    1096       $TableStartCmpdNum = ${$SDFilesInfo{TableStartCmpdNum}[$Index]}[$TableIndex];
    1097       $TableEndCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$TableIndex];
    1098       $RefTitle = AddNumberSuffix($TableNum) . " Table Containing Compounds $TableStartCmpdNum To $TableEndCmpdNum";
    1099       $HTMLRefFile = GetRelativeFileDir($CurTableNum, $TableNum, $FirstTableNum) . $HTMLFile;
    1100       $HTMLRefValue = SetupHTMLHRef($TableNum, $HTMLRefFile, $RefTitle);
    1101       print $HTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue);
    1102     }
    1103   }
    1104
    1105   # Setup link to next table...
    1106   if ($CurTableNum != $LastTableNum) {
    1107     my($NextTableNum, $NextTableIndex);
    1108     $NextTableNum = $CurTableNum + 1; $NextTableIndex = $NextTableNum - 1;
    1109     $HTMLFile = ${$SDFilesInfo{TableHTMLFiles}[$Index]}[$NextTableIndex];
    1110     $HTMLRefFile = GetRelativeFileDir($CurTableNum, $NextTableNum, $FirstTableNum) . $HTMLFile;
    1111     $TableStartCmpdNum = ${$SDFilesInfo{TableStartCmpdNum}[$Index]}[$NextTableIndex];
    1112     $TableEndCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$NextTableIndex];
    1113     $HTMLRefValue = SetupHTMLHRef("Next", $HTMLRefFile, "Next Table Containing Compounds $TableStartCmpdNum To $TableEndCmpdNum");
    1114     print $HTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
    1115   }
    1116
    1117   # Setup link to last table...
    1118   if ($EndTableNum != $LastTableNum) {
    1119     $HTMLFile = ${$SDFilesInfo{TableHTMLFiles}[$Index]}[$LastTableIndex];
    1120     $HTMLRefFile = GetRelativeFileDir($CurTableNum, $LastTableNum, $FirstTableNum) . $HTMLFile;
    1121     $TableStartCmpdNum = ${$SDFilesInfo{TableStartCmpdNum}[$Index]}[$LastTableIndex];
    1122     $TableEndCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$LastTableIndex];
    1123     $HTMLRefValue = SetupHTMLHRef("Last", $HTMLRefFile, "Last Table Containing Compounds $TableStartCmpdNum To $TableEndCmpdNum");
    1124     print $HTMLFileRef SetupHTMLTableRowDataValue($HTMLRefValue, $LinkBGColor, $LinkTextColor, $LinkFontBold);
    1125   }
    1126   # Setup current table info text....
    1127   print $HTMLFileRef SetupHTMLTableRowDataValue("&nbsp");
    1128   print $HTMLFileRef SetupHTMLTableRowDataValue("&nbsp");
    1129   $TableStartCmpdNum = ${$SDFilesInfo{TableStartCmpdNum}[$Index]}[$CurTableNum - 1];
    1130   $TableEndCmpdNum = ${$SDFilesInfo{TableEndCmpdNum}[$Index]}[$CurTableNum - 1];
    1131   if ($OptionsInfo{NavLinksCmpdInfo}) {
    1132     print $HTMLFileRef SetupHTMLTableRowDataValue("Showing compounds $TableStartCmpdNum to $TableEndCmpdNum of $LastCmpdNum");
    1133   }
    1134   else {
    1135     print $HTMLFileRef SetupHTMLTableRowDataValue("Showing table $CurTableNum of $LastTableNum");
    1136   }
    1137
    1138   print $HTMLFileRef $SDFilesInfo{RowEndTags};
    1139   # End link table...
    1140   print $HTMLFileRef SetupHTMLTableEnd();
    1141   print $HTMLFileRef SetupHTMLDivEnd();
    1142   print $HTMLFileRef SetupHTMLAlignmentEnd("center");
    1143 }
    1144
    1145 # Generate relative directory path...
    1146 sub GetRelativeFileDir {
    1147   my($FromTableNum, $ToTableNum, $FirstTableNum) = @_;
    1148   my($RelativeFileDir) = "";
    1149
    1150   if ($FromTableNum == $FirstTableNum) {
    1151     $RelativeFileDir = ($ToTableNum == $FirstTableNum) ? ".\/" : ".\/html\/";
    1152   }
    1153   else {
    1154     $RelativeFileDir = ($ToTableNum == $FirstTableNum) ? "..\/" : ".\/";
    1155   }
    1156   return $RelativeFileDir;
    1157 }
    1158
    1159 # Based on hightlight stype, return appropriate colors for background or text...
    1160 sub GetValueHighlightColors {
    1161   my($Label, $Value) = @_;
    1162   my($DataType, $Criterion, $CriterionValue, $BgColor, $FontColor, $ValueOk, $Nothing);
    1163
    1164   $BgColor = ""; $FontColor = "";
    1165   $DataType = $OptionsInfo{SpecifiedHighlightDataFieldTypesMap}{$Label};
    1166   $Criterion = $OptionsInfo{SpecifiedHighlightDataFieldCriteriaMap}{$Label};
    1167   $CriterionValue = $OptionsInfo{SpecifiedHighlightDataFieldValueMap}{$Label};
    1168
    1169   $ValueOk = 0;
    1170   if ($DataType =~ /^numeric$/i) {
    1171   NUMSWITCH: {
    1172       if ($Criterion =~ /^ge$/i) { $ValueOk = ($Value >= $CriterionValue) ? 1 : 0; last NUMSWITCH; }
    1173       if ($Criterion =~ /^le$/i) { $ValueOk = ($Value <= $CriterionValue) ? 1 : 0; last NUMSWITCH; }
    1174       if ($Criterion =~ /^eq$/i) { $ValueOk = ($Value == $CriterionValue) ? 1 : 0; last NUMSWITCH; }
    1175       $Nothing = 1;
    1176     }
    1177   }
    1178   else {
    1179   TEXTSWITCH: {
    1180       if ($Criterion =~ /^ge$/i) { $ValueOk = ($Value ge $CriterionValue) ? 1 : 0; last TEXTSWITCH; }
    1181       if ($Criterion =~ /^le$/i) { $ValueOk = ($Value le $CriterionValue) ? 1 : 0; last TEXTSWITCH; }
    1182       if ($Criterion =~ /^eq$/i) { $ValueOk = ($Value eq $CriterionValue) ? 1 : 0; last TEXTSWITCH; }
    1183       $Nothing = 1;
    1184     }
    1185   }
    1186   $BgColor = $ValueOk ? $OptionsInfo{ValueOkColor} : $OptionsInfo{ValueNotOkColor};
    1187   if ($Options{highlightstyle} =~ /^text$/i) {
    1188     $BgColor = "";
    1189     $FontColor = $ValueOk ? $OptionsInfo{ValueOkColor} : $OptionsInfo{ValueNotOkColor};
    1190   }
    1191   return ($BgColor, $FontColor);
    1192 }
    1193
    1194 #Make sure appropriate mode specific option values are specified...
    1195 sub ProcessOptions {
    1196
    1197   %OptionsInfo = ();
    1198
    1199   $OptionsInfo{TitleDisplay} = ($Options{titledisplay} =~ /^yes$/i) ? 1 : 0;
    1200
    1201   $OptionsInfo{RowHAlignment} = "left"; $OptionsInfo{RowVAlignment} = "middle";
    1202   if (exists($Options{align})) {
    1203     my (@AlignValues) = split ",", $Options{align};
    1204     if (@AlignValues == 2) {
    1205       $OptionsInfo{RowHAlignment} = $AlignValues[0];
    1206       $OptionsInfo{RowVAlignment} = $AlignValues[1];
    1207     }
    1208     elsif (@AlignValues == 1) {
    1209       $OptionsInfo{RowHAlignment} = $AlignValues[0];
    1210     }
    1211     else {
    1212       die "Error: Invalid number of values, ", scalar(@AlignValues) , ", specified by \"-a --align\" option.\nIt must contain only one or two values.\n";
    1213     }
    1214     if ($OptionsInfo{RowHAlignment} !~ /^(left|center|right)$/i) {
    1215       die "Error: The horizontal alignment value specified, $Options{align}, for option \"-a --align\" is not valid. Allowed values: left, center, or right\n";
    1216     }
    1217     if ($OptionsInfo{RowVAlignment} !~ /^(top|middle|bottom)$/i) {
    1218       die "Error: The horizontal alignment value specified, $Options{align}, for option \"-a --align\" is not valid. Allowed values: top, middle, or bottom\n";
    1219     }
    1220   }
    1221
    1222   $OptionsInfo{TableHeaderRowHAlignment} = "center"; $OptionsInfo{TableHeaderRowVAlignment} = "middle";
    1223   if (exists($Options{headeralign})) {
    1224     my (@AlignValues) = split ",", $Options{headeralign};
    1225     if (@AlignValues == 2) {
    1226       $OptionsInfo{TableHeaderRowHAlignment} = $AlignValues[0];
    1227       $OptionsInfo{TableHeaderRowVAlignment} = $AlignValues[1];
    1228     }
    1229     elsif (@AlignValues == 1) {
    1230       $OptionsInfo{TableHeaderRowHAlignment} = $AlignValues[0];
    1231     }
    1232     else {
    1233       die "Error: Invalid number of values, ", scalar(@AlignValues) , ", specified by \"--headeralign\" option.\nIt must contain only one or two value.\n";
    1234     }
    1235     if ($OptionsInfo{TableHeaderRowHAlignment} !~ /^(left|center|right)$/i) {
    1236       die "Error: The horizontal alignment value specified, $Options{headeralign}, for option \"--headeralign\" is not valid. Allowed values: left, center, or right\n";
    1237     }
    1238     if ($OptionsInfo{TableHeaderRowVAlignment} !~ /^(top|middle|bottom)$/i) {
    1239       die "Error: The horizontal alignment value specified, $Options{headeralign}, for option \"-a --headeralign\" is not valid. Allowed values: top, middle, or bottom\n";
    1240     }
    1241   }
    1242
    1243   if (exists($Options{border})) {
    1244     $OptionsInfo{TableBorder} = $Options{border};
    1245   }
    1246   else {
    1247     $OptionsInfo{TableBorder} = ($Options{mode} =~ /^(plain|highlight)$/i) || $Options{mode} =~ /^structuresonly$/i ? 1 : 0;
    1248   }
    1249   $OptionsInfo{TableCellPadding} = $Options{cellpadding};
    1250   $OptionsInfo{TableCellSpacing} = $Options{cellspacing};
    1251   $OptionsInfo{FooterMsg} = $Options{footer} ? $Options{footer} : "";
    1252
    1253   if ($Options{headercolor}) {
    1254     $OptionsInfo{TableHeaderRowColor} = $Options{headercolor};
    1255   }
    1256   else {
    1257     $OptionsInfo{TableHeaderRowColor} = ($Options{mode} =~ /^plain$/i) ? "" : "#e0e9eb";
    1258   }
    1259
    1260   $OptionsInfo{NavLinksAtBottom} = 1; $OptionsInfo{NavLinksAtTop} = 0;
    1261   if ($Options{displaylinks} =~ /^(both|top)$/i) {
    1262     $OptionsInfo{NavLinksAtTop} = 1;
    1263   }
    1264   $OptionsInfo{NavLinksTableInfo} = 1; $OptionsInfo{NavLinksCmpdInfo} = 0;
    1265   if ($Options{displaylinksinfo} =~ /^both$/i) {
    1266     $OptionsInfo{NavLinksCmpdInfo} = 1;
    1267     $OptionsInfo{NavLinksTableInfo} = 1;
    1268   }
    1269   elsif ($Options{displaylinksinfo} =~ /^compound$/i) {
    1270     $OptionsInfo{NavLinksCmpdInfo} = 1;
    1271     $OptionsInfo{NavLinksTableInfo} = 0;
    1272   }
    1273
    1274   if ($Options{stylesheet} =~ /^old$/i ) {
    1275     if (!$Options{stylesheetname}) {
    1276       die "Error: No stylesheet name specified using \"--stylesheetname\" option: It is required for \"old\" value of \"-s --stylesheet\" option. \n";
    1277     }
    1278   }
    1279
    1280   my(@ColorValues);
    1281   $OptionsInfo{ShadeRowsStatus} = 0;
    1282   $OptionsInfo{OddRowsShadeColor} = "#ffffff";
    1283   $OptionsInfo{EvenRowsShadeColor} = "#e0e9eb";
    1284   if ($Options{shadecolor}) {
    1285     # Make sure only one value is specified...
    1286     @ColorValues = split ",", $Options{shadecolor};
    1287     if (@ColorValues == 2) {
    1288       $OptionsInfo{OddRowsShadeColor} = $ColorValues[0];
    1289       $OptionsInfo{EvenRowsShadeColor} = $ColorValues[1];
    1290     }
    1291     else {
    1292       die "Error: Invalid number of values, ", scalar(@ColorValues) , ", specified by \"--shadecolor\" option.\nIt must contain only two value.\n";
    1293     }
    1294   }
    1295   if ($Options{mode} =~ /^(shade|shadedhighlight|shadedstructuresonly)$/i) {
    1296     $OptionsInfo{ShadeRowsStatus} = 1;
    1297   }
    1298
    1299   $OptionsInfo{SettingUpCmpdSummaryPage} = 0;
    1300   $OptionsInfo{StrLinkShadeColor} = (exists $Options{strlinkshadecolor}) ? $Options{strlinkshadecolor} : "#e0e9eb";
    1301   $OptionsInfo{DisplayStructure} = ($Options{structure} =~ /^display$/i) ? 1 : 0;
    1302   $OptionsInfo{StrViewerType} = $Options{strviewertype};
    1303   $OptionsInfo{StrLinkNavigation} = ($Options{strlinknavigation} =~ /^yes$/i) ? 1 : 0;
    1304   $OptionsInfo{StrLinkTitleDisplay} = ($Options{strlinktitledisplay} =~ /^yes$/i) ? 1 : 0;
    1305   $OptionsInfo{StrLinkTitle} = (exists($Options{strlinktitle}) && length($Options{strlinktitle})) ? "$Options{strlinktitle}" : "Compound Summary";
    1306
    1307   my($StrViewerEmbedUsingJS) = (($Options{strviewerembed} =~ /^javascript$/i) && ($OptionsInfo{StrViewerType} =~ /^(Jmol|MarvinView|ChemDrawPlugIn|ChemDrawActiveX|Chem3DActiveX)$/i )) ? 1 : 0;
    1308
    1309   $OptionsInfo{StrTableRows} = 6; $OptionsInfo{StrTableCols} = 4;
    1310   if ($Options{strtablesize}) {
    1311     my(@StrTableSizeValues) = split ",", $Options{strtablesize};
    1312     if (@StrTableSizeValues == 2) {
    1313       $OptionsInfo{StrTableRows} = $StrTableSizeValues[0];
    1314       $OptionsInfo{StrTableCols} = $StrTableSizeValues[1];
    1315       if (!IsPositiveInteger($OptionsInfo{StrTableRows})) {
    1316         die "Error: The first value specified, $OptionsInfo{StrTableRows},  for option \"--strtablesize\" is not valid: Allowed integer values: > 0.\n";
    1317       }
    1318       if (!IsPositiveInteger($OptionsInfo{StrTableCols})) {
    1319         die "Error: The first value specified, $OptionsInfo{StrTableCols},  for option \"--strtablesize\" is not valid: Allowed integer values: > 0.\n";
    1320       }
    1321     }
    1322     else {
    1323       die "Error: Invalid number of values, ", scalar(@StrTableSizeValues), ", specified by \"--strtablesize\" option.\nIt must contain only two value for structuresonly \"-m --mode\" option.\n";
    1324     }
    1325   }
    1326
    1327   # Setup applet information...
    1328   $OptionsInfo{StrViewerCodeBase} = GetMayaChemToolsLibDirName() . "/Jmol";
    1329   $OptionsInfo{TopHTMLDirStrViewerCodeBase} = $OptionsInfo{StrViewerCodeBase};
    1330   $OptionsInfo{SubHTMLDirStrViewerCodeBase} = $OptionsInfo{StrViewerCodeBase};
    1331
    1332   my($StrViewerAppletArchive, $StrViewerAppletCode) = SetupDefaultAppletArchiveAndCode($OptionsInfo{StrViewerType});
    1333   if ($Options{strviewerconfig}) {
    1334     my(@StrViewerConfigParts) = split ",", $Options{strviewerconfig};
    1335     if (@StrViewerConfigParts >=1 && @StrViewerConfigParts <= 3) {
    1336       if (@StrViewerConfigParts == 3) {
    1337         $OptionsInfo{StrViewerCodeBase} = $StrViewerConfigParts[0];
    1338         $StrViewerAppletArchive = $StrViewerConfigParts[1];
    1339         $StrViewerAppletCode = $StrViewerConfigParts[2];
    1340       }
    1341       elsif (@StrViewerConfigParts == 2) {
    1342         $OptionsInfo{StrViewerCodeBase} = $StrViewerConfigParts[0];
    1343         $StrViewerAppletArchive = $StrViewerConfigParts[1];
    1344         my($AppletArchive, $AppletCode) = SetupDefaultAppletArchiveAndCode($OptionsInfo{StrViewerType});
    1345         $StrViewerAppletCode = $AppletCode;
    1346       }
    1347       else {
    1348         $OptionsInfo{StrViewerCodeBase} = $StrViewerConfigParts[0];
    1349         ($StrViewerAppletArchive, $StrViewerAppletCode) = SetupDefaultAppletArchiveAndCode($OptionsInfo{StrViewerType});
    1350       }
    1351     }
    1352     else {
    1353       die "Error: Invalid number of values, ", scalar(@StrViewerConfigParts), ", specified by \"--strviewerconfig\" option.\nNumver of allowed values:1 to 3 \n";
    1354     }
    1355   }
    1356   else {
    1357     if ($OptionsInfo{StrViewerType} =~ /^(JME|MarvinView)$/i ) {
    1358       die "Error: No codebase specified using \"--strviewerconfig\" option for $OptionsInfo{StrViewerType} structure viewer\n";
    1359     }
    1360     if ($StrViewerEmbedUsingJS && $OptionsInfo{StrViewerType} !~ /^Jmol$/i) {
    1361       die "Error: No codebase specified using \"--strviewerconfig\" option for javascript value of \"--strviewerembed\" option for $OptionsInfo{StrViewerType} structure viewer \n";
    1362     }
    1363   }
    1364
    1365   if (-d $OptionsInfo{StrViewerCodeBase}) {
    1366     # Change local code base direcrory name to a relative directory name based on the
    1367     # current directory containing SD file; otherwise, Java applets and JavaScripts don't
    1368     # get loaded into Firefox and Chrome browsers.
    1369     #
    1370     # For top and sub HTML directories, add prefix "../" and "../../" to relative path...
    1371     $OptionsInfo{StrViewerCodeBase} = File::Spec->abs2rel($OptionsInfo{StrViewerCodeBase}, Cwd::cwd());
    1372
    1373     $OptionsInfo{TopHTMLDirStrViewerCodeBase} = "../" . $OptionsInfo{StrViewerCodeBase};
    1374     $OptionsInfo{SubHTMLDirStrViewerCodeBase} = "../../" . $OptionsInfo{StrViewerCodeBase};
    1375   }
    1376
    1377   # Setup structure viewer parameter information...
    1378   %{$OptionsInfo{StrViewerParams}} = ();
    1379   if ($Options{strviewerparams}) {
    1380     my(@ParamsSplit, @ParamPairSplit, $ParamPair);
    1381     #@ParamsSplit = split " ", $Options{strviewerparams};
    1382     @ParamsSplit = quotewords(" ", 0, $Options{strviewerparams});
    1383     for $ParamPair (@ParamsSplit) {
    1384       @ParamPairSplit = split "=", $ParamPair;
    1385       if (@ParamPairSplit == 2) {
    1386         $OptionsInfo{StrViewerParams}{$ParamPairSplit[0]} = $ParamPairSplit[1];
    1387       }
    1388       else {
    1389         die "Error: Invalid value, $ParamPair, specified by \"--strviewerparams\" option.\nValid values: name=value\n";
    1390       }
    1391     }
    1392   }
    1393
    1394   if ($OptionsInfo{StrViewerType} =~ /^(JME|Jmol|MarvinView)$/i ) {
    1395     $OptionsInfo{StrViewerParams}{name} = $StrViewerAppletCode;
    1396     $OptionsInfo{StrViewerParams}{archive} = $StrViewerAppletArchive;
    1397     $OptionsInfo{StrViewerParams}{code} = $StrViewerAppletCode;
    1398   }
    1399   $OptionsInfo{StrWidth} = exists($OptionsInfo{StrViewerParams}{width}) ? $OptionsInfo{StrViewerParams}{width} : 250;
    1400   $OptionsInfo{StrViewerParams}{width} = $OptionsInfo{StrWidth};
    1401   $OptionsInfo{StrHeight} = exists($OptionsInfo{StrViewerParams}{height}) ? $OptionsInfo{StrViewerParams}{height} : 170;
    1402   $OptionsInfo{StrViewerParams}{height} = $OptionsInfo{StrHeight};
    1403
    1404   $OptionsInfo{StrLinkWidth} = 500;
    1405   if (exists($OptionsInfo{StrViewerParams}{strlinkwidth})) {
    1406     $OptionsInfo{StrLinkWidth} = $OptionsInfo{StrViewerParams}{strlinkwidth};
    1407     $OptionsInfo{StrViewerParams}{strlinkwidth} = "";
    1408   }
    1409   $OptionsInfo{StrLinkHeight} = 295;
    1410   if (exists($OptionsInfo{StrViewerParams}{strlinkheight})) {
    1411     $OptionsInfo{StrLinkHeight} = $OptionsInfo{StrViewerParams}{strlinkheight};
    1412     $OptionsInfo{StrViewerParams}{strlinkheight} = "";
    1413   }
    1414
    1415   $OptionsInfo{StrBgColorSpecified} = "";
    1416   if (exists($OptionsInfo{StrViewerParams}{bgcolor})) {
    1417     $OptionsInfo{StrBgColorSpecified} = $OptionsInfo{StrViewerParams}{bgcolor};
    1418   }
    1419
    1420   $OptionsInfo{StrLinkBgColorSpecified} = "#ffffff";
    1421   if (exists($OptionsInfo{StrViewerParams}{strlinkbgcolor})) {
    1422     $OptionsInfo{StrLinkBgColorSpecified} = $OptionsInfo{StrViewerParams}{strlinkbgcolor};
    1423     $OptionsInfo{StrViewerParams}{strlinkbgcolor} = "";
    1424   }
    1425
    1426   # Setup Java Script usage...
    1427   $OptionsInfo{StrViewerJSFileRef} = "";
    1428   $OptionsInfo{TopHTMLDirStrViewerJSFileRef} = "";
    1429   $OptionsInfo{SubHTMLDirStrViewerJSFileRef} = "";
    1430
    1431   if ($StrViewerEmbedUsingJS) {
    1432     my ($StrViewerJSFileName) = "";
    1433     if ($Options{strviewerjsfile}) {
    1434       $StrViewerJSFileName = $Options{strviewerjsfile};
    1435     }
    1436     else {
    1437       if ($OptionsInfo{StrViewerType} =~ /^Jmol$/i) {
    1438         $StrViewerJSFileName = "Jmol.js";
    1439       }
    1440       elsif ($OptionsInfo{StrViewerType} =~ /^MarvinView$/i) {
    1441         $StrViewerJSFileName = "marvin.js";
    1442       }
    1443       elsif ($OptionsInfo{StrViewerType} =~ /^(ChemDrawPlugIn|ChemDrawActiveX)$/i) {
    1444         $StrViewerJSFileName = "chemdraw.js";
    1445       }
    1446       elsif ($OptionsInfo{StrViewerType} =~ /^Chem3DActiveX$/i) {
    1447         $StrViewerJSFileName = "chem3d.js";
    1448       }
    1449     }
    1450     if ($StrViewerJSFileName) {
    1451       $OptionsInfo{StrViewerParams}{usejavascript} = $StrViewerJSFileName;
    1452       $OptionsInfo{StrViewerJSFileRef} = "$OptionsInfo{StrViewerCodeBase}" . "\/" . "$StrViewerJSFileName";
    1453       $OptionsInfo{TopHTMLDirStrViewerJSFileRef} = "$OptionsInfo{TopHTMLDirStrViewerCodeBase}" . "\/" . "$StrViewerJSFileName";
    1454       $OptionsInfo{SubHTMLDirStrViewerJSFileRef} = "$OptionsInfo{SubHTMLDirStrViewerCodeBase}" . "\/" . "$StrViewerJSFileName";
    1455     }
    1456   }
    1457
    1458   # Check any other user specified parametrs applicable to all structure viewers...
    1459
    1460   $OptionsInfo{StructuresOnlyMode} = 0;
    1461   $OptionsInfo{MaxCmpdsPerTable} = ($Options{structure} =~ /^display$/i) ? 15 : 50;
    1462   if (exists $Options{numcmpds}) {
    1463     $OptionsInfo{MaxCmpdsPerTable} = $Options{numcmpds};
    1464   }
    1465   if ($Options{mode} =~ /^(structuresonly|shadedstructuresonly)$/i) {
    1466     $OptionsInfo{MaxCmpdsPerTable} = ($OptionsInfo{MaxCmpdsPerTable} > 0) ? ($OptionsInfo{StrTableRows} * $OptionsInfo{StrTableCols}) : 0;
    1467     $OptionsInfo{StructuresOnlyMode} = 1;
    1468   }
    1469   $OptionsInfo{CmpdDataField} = "";
    1470   $OptionsInfo{CmpdDataFieldLabel} = "no";
    1471   $OptionsInfo{CmpdDataFieldPosition} = "bottom";
    1472   $OptionsInfo{CmpdDataFieldAlignment} = "center";
    1473   if (exists($Options{cmpddatafield}) && length($Options{cmpddatafield})) {
    1474     my (@CmpdDataFieldValues) = split ",", $Options{cmpddatafield};
    1475     if (@CmpdDataFieldValues == 1) {
    1476       $OptionsInfo{CmpdDataField} = $CmpdDataFieldValues[0];
    1477     }
    1478     elsif (@CmpdDataFieldValues == 2) {
    1479       $OptionsInfo{CmpdDataField} = $CmpdDataFieldValues[0];
    1480       $OptionsInfo{CmpdDataFieldLabel} = $CmpdDataFieldValues[1];
    1481     }
    1482     elsif (@CmpdDataFieldValues == 3) {
    1483       $OptionsInfo{CmpdDataField} = $CmpdDataFieldValues[0];
    1484       $OptionsInfo{CmpdDataFieldLabel} = $CmpdDataFieldValues[1];
    1485       $OptionsInfo{CmpdDataFieldPosition} = $CmpdDataFieldValues[2];
    1486     }
    1487     elsif (@CmpdDataFieldValues == 4) {
    1488       $OptionsInfo{CmpdDataField}  = $CmpdDataFieldValues[0];
    1489       $OptionsInfo{CmpdDataFieldLabel} = $CmpdDataFieldValues[1];
    1490       $OptionsInfo{CmpdDataFieldPosition} = $CmpdDataFieldValues[2];
    1491       $OptionsInfo{CmpdDataFieldAlignment} = $CmpdDataFieldValues[3];
    1492     }
    1493     else {
    1494       die "Error: Invalid number of values, ", scalar(@CmpdDataFieldValues) , ", specified by \"--cmpddatafield\" option.\nIt must contain only one, two, three, or four values.\n";
    1495     }
    1496     if ($OptionsInfo{CmpdDataFieldLabel} !~ /^(yes|no)$/ ) {
    1497       die "Error: The label value specified, $Options{cmpddatafield}, for option \"--cmpddatafield\" is not valid. Allowed values: yes or no\n";
    1498     }
    1499     if ($OptionsInfo{CmpdDataFieldPosition} !~ /^(top|bottom)$/ ) {
    1500       die "Error: The position value specified, $Options{cmpddatafield}, for option \"--cmpddatafield\" is not valid. Allowed values: top or bottom\n";
    1501     }
    1502     if ($OptionsInfo{CmpdDataFieldAlignment} !~ /^(left|center|right)$/ ) {
    1503       die "Error: The alignment value specified, $Options{cmpddatafield}, for option \"--cmpddatafield\" is not valid. Allowed values: left, center, or right\n";
    1504     }
    1505   }
    1506
    1507   # Process data fields to be displayed in tables...
    1508   $OptionsInfo{SpecifiedDataFields} = exists($Options{datafields}) ? $Options{datafields} : "All";
    1509
    1510   $OptionsInfo{ValueOkColor} = ""; $OptionsInfo{ValueNotOkColor} = ""; $OptionsInfo{HighlightStatus} = 0;
    1511   if ($Options{mode} =~ /^(highlight|shadedhighlight)$/i) {
    1512     my($HighlightMode, $HighlightBy);
    1513     $HighlightMode = $Options{mode}; $HighlightBy = $Options{highlightby};
    1514
    1515     $OptionsInfo{HighlightStatus} = 1;
    1516     $OptionsInfo{ValueOkColor} = "#0fff0f";
    1517     $OptionsInfo{ValueNotOkColor} = "#ff0f0f";
    1518     if ($Options{highlightstyle} =~ /^text$/i) {
    1519       $OptionsInfo{ValueOkColor} = "#0fbb0f";
    1520       $OptionsInfo{ValueNotOkColor} = "#ff0f0f";
    1521     }
    1522     if ($Options{highlightcolor}) {
    1523       # Make sure two values are specified...
    1524       @ColorValues = split ",", $Options{highlightcolor};
    1525       if (@ColorValues == 2) {
    1526         $OptionsInfo{ValueOkColor} = $ColorValues[0];
    1527         $OptionsInfo{ValueNotOkColor} = $ColorValues[1];
    1528       }
    1529       else {
    1530         die "Error: Invalid number of values, ", scalar(@ColorValues), ", specified by \"--highlightcolor\" option.\nIt must contain only two value for $HighlightMode value specified using \"-m --mode\" option.\n";
    1531       }
    1532     }
    1533     if (!$Options{highlight}) {
    1534       die "Error: Specify columns to be highlighted using \"--hightlight\" option\n";
    1535     }
    1536     # Retrieve quartet values from "hightlight" option...
    1537     my(@HighlightValueQuartets);
    1538
    1539     @HighlightValueQuartets = ();
    1540     @HighlightValueQuartets = split ",", $Options{highlight};
    1541     if ((@HighlightValueQuartets % 4)) {
    1542       die "Error: Quartets not found in values specified using \"--highlight\" option for $HighlightMode \"-m --mode\"\n";
    1543     }
    1544     # Process quartets...
    1545     my($Index, $Label, $DataType, $Criterion, $Value);
    1546
    1547     @{$OptionsInfo{SpecifiedHighlightDataFieldLabels}} = ();
    1548     %{$OptionsInfo{SpecifiedHighlightDataFieldLabelsMap}} = ();
    1549     %{$OptionsInfo{SpecifiedHighlightDataFieldTypesMap}} = ();
    1550     %{$OptionsInfo{SpecifiedHighlightDataFieldCriteriaMap}} = ();
    1551     %{$OptionsInfo{SpecifiedHighlightDataFieldValueMap}} = ();
    1552
    1553     for ($Index = 0; $Index < @HighlightValueQuartets; $Index = $Index + 4) {
    1554       $Label = $HighlightValueQuartets[$Index];
    1555       $DataType = $HighlightValueQuartets[$Index + 1];
    1556       $Criterion = $HighlightValueQuartets[$Index + 2];
    1557       $Value = $HighlightValueQuartets[$Index + 3];
    1558       if ($DataType !~ /^(numeric|text)$/i) {
    1559         die "Error: Invalid column data type, $DataType, specified in quartet, \"$Label,$DataType,$Criterion,$Value\", using \"--hightlight\" option: Valid values: numeric or text\n";
    1560       }
    1561       if ($Criterion !~ /^(eq|le|ge)$/i) {
    1562         die "Error: Invalid criterion value, $Criterion, specified in quartet, \"$Label,$DataType,$Criterion,$Value\", using \"--hightlight\" option: Valid values: le, ge, or eq\n";
    1563       }
    1564       if ($DataType =~ /^numeric$/i) {
    1565         if (!IsFloat($Value)) {
    1566           die "Error: Invalid criterion value, $Value, specified in quartet, \"$Label,$DataType,$Criterion,$Value\", using \"--hightlight\" option: Numeric value required for numeric data type\n";
    1567         }
    1568       }
    1569       if (exists($OptionsInfo{SpecifiedHighlightDataFieldLabelsMap}{$Label})) {
    1570         die "Error: Invalid field label value, $Label, in quartet, \"$Label,$DataType,$Criterion,$Value\", using \"--hightlight\" option: Multiple occurences of label.  \n";
    1571       }
    1572       push @{$OptionsInfo{SpecifiedHighlightDataFieldLabels}}, $Label;
    1573       $OptionsInfo{SpecifiedHighlightDataFieldLabelsMap}{$Label} = $Label;
    1574       $OptionsInfo{SpecifiedHighlightDataFieldTypesMap}{$Label} = $DataType;
    1575       $OptionsInfo{SpecifiedHighlightDataFieldCriteriaMap}{$Label} = $Criterion;
    1576       $OptionsInfo{SpecifiedHighlightDataFieldValueMap}{$Label} = $Value;
    1577     }
    1578   }
    1579 }
    1580
    1581 # Set up default archive and code values for a specific applet...
    1582 sub SetupDefaultAppletArchiveAndCode {
    1583   my($ViewerType) = @_;
    1584   my($Archive, $Code, $Nothing);
    1585
    1586  STRVIEWERTYPE: {
    1587     if ($OptionsInfo{StrViewerType} =~ /^JME$/i) { $Archive = "JME.jar"; $Code = "JME"; last STRVIEWERTYPE; }
    1588     if ($OptionsInfo{StrViewerType} =~ /^Jmol$/i) {$Archive = "JmolApplet.jar"; $Code = "JmolApplet";  last STRVIEWERTYPE; }
    1589     if ($OptionsInfo{StrViewerType} =~ /^MarvinView$/i) { $Archive = "marvin.jar"; $Code = "MView"; last STRVIEWERTYPE; }
    1590     $Nothing = 1;
    1591   }
    1592   return ($Archive, $Code);
    1593 }
    1594
    1595 # Retrieve information about input SD files...
    1596 sub RetrieveSDFilesInfo {
    1597   my($SDFile, $FileDir, $FileName, $HTMLFile, $CSSFile, $HTMLRoot, $HTMLTitle, $FileExt, $Index, $TopHTMLDir);
    1598
    1599   %SDFilesInfo = ();
    1600
    1601   @{$SDFilesInfo{FileOkay}} = ();
    1602   @{$SDFilesInfo{CmpdCount}} = ();
    1603   @{$SDFilesInfo{SpecifiedDataFieldLabels}} = ();
    1604
    1605   @{$SDFilesInfo{HTMLRoot}} = ();
    1606   @{$SDFilesInfo{HTMLTitle}} = ();
    1607   @{$SDFilesInfo{MultipleHTMLTables}} = ();
    1608
    1609   @{$SDFilesInfo{TopHTMLDir}} = ();
    1610   @{$SDFilesInfo{SubHTMLDir}} = ();
    1611   @{$SDFilesInfo{SubMolDir}} = ();
    1612
    1613
    1614   FILELIST: for $Index (0 .. $#SDFilesList) {
    1615     $SDFile = $SDFilesList[$Index];
    1616
    1617     $SDFilesInfo{FileOkay}[$Index] = 0;
    1618     $SDFilesInfo{CmpdCount}[$Index] = 0;
    1619     $SDFilesInfo{HTMLRoot}[$Index] = "";
    1620     $SDFilesInfo{HTMLTitle}[$Index] = "";
    1621     $SDFilesInfo{MultipleHTMLTables}[$Index] = 0;
    1622     $SDFilesInfo{TopHTMLDir}[$Index] = "";
    1623     $SDFilesInfo{SubHTMLDir}[$Index] = "";
    1624     $SDFilesInfo{SubMolDir}[$Index] = "";
    1625
    1626     @{$SDFilesInfo{SpecifiedDataFieldLabels}[$Index]} = ();
    1627
    1628     if (!(-e $SDFile)) {
    1629       warn "Warning: Ignoring file $SDFile: It doesn't exist\n";
    1630       next FILELIST;
    1631     }
    1632     if (!CheckFileType($SDFile, "sd sdf")) {
    1633       warn "Warning: Ignoring file $SDFile: It's not a SD file\n";
    1634       next FILELIST;
    1635     }
    1636     ($FileDir, $FileName, $FileExt) = ParseFileName($SDFile);
    1637
    1638     if (!open SDFILE, "$SDFile") {
    1639       warn "Warning: Ignoring file $SDFile: Couldn't open it: $! \n";
    1640       next FILELIST;
    1641     }
    1642     # Count number of compounds and collect all possible data field labels...
    1643     my($CmpdCount, $CmpdString, @DataFieldLabels, @CommonDataFieldLabels);
    1644     $CmpdCount = 0;
    1645     @DataFieldLabels = ();
    1646     @CommonDataFieldLabels = ();
    1647     if ($OptionsInfo{SpecifiedDataFields} =~ /^(All|Common)$/i ) {
    1648       my($DataFieldLabelsRef, $CommonDataFieldLabelsRef);
    1649       ($CmpdCount, $DataFieldLabelsRef, $CommonDataFieldLabelsRef) = GetAllAndCommonCmpdDataHeaderLabels(\*SDFILE);
    1650       push @DataFieldLabels, @{$DataFieldLabelsRef};
    1651       push @CommonDataFieldLabels, @{$CommonDataFieldLabelsRef};
    1652     }
    1653     else {
    1654       while ($CmpdString = ReadCmpdString(\*SDFILE)) {
    1655         $CmpdCount++;
    1656       }
    1657     }
    1658     close SDFILE;
    1659
    1660     $FileDir = ""; $FileName = ""; $FileExt = "";
    1661     ($FileDir, $FileName, $FileExt) = ParseFileName($SDFile);
    1662     $HTMLRoot = $FileName;
    1663     if ($Options{root} && (@SDFilesList == 1)) {
    1664       my ($RootFileDir, $RootFileName, $RootFileExt) = ParseFileName($Options{root});
    1665       if ($RootFileName && $RootFileExt) {
    1666         $HTMLRoot = $RootFileName;
    1667       }
    1668       else {
    1669         $HTMLRoot = $Options{root};
    1670       }
    1671     }
    1672     $HTMLTitle = $HTMLRoot;
    1673     if ($Options{title} && (@SDFilesList == 1)) {
    1674       $HTMLTitle = $Options{title};
    1675     }
    1676     $HTMLFile = lc($HTMLRoot) . "-html";
    1677     if (!$Options{overwrite}) {
    1678       if (-d $HTMLFile) {
    1679         warn "Warning: Ignoring file $SDFile: The directory $HTMLFile already exists\n";
    1680         next FILELIST;
    1681       }
    1682     }
    1683     $SDFilesInfo{FileOkay}[$Index] = 1;
    1684     $SDFilesInfo{CmpdCount}[$Index] = $CmpdCount;
    1685     $SDFilesInfo{HTMLRoot}[$Index] = "$HTMLRoot";
    1686     $SDFilesInfo{HTMLTitle}[$Index] = "$HTMLTitle";
    1687     if ($OptionsInfo{MaxCmpdsPerTable} == 0 || $CmpdCount <= $OptionsInfo{MaxCmpdsPerTable}) {
    1688       $SDFilesInfo{MultipleHTMLTables}[$Index] = 0;
    1689     }
    1690     else {
    1691       $SDFilesInfo{MultipleHTMLTables}[$Index] = 1;
    1692     }
    1693     if ($OptionsInfo{SpecifiedDataFields} =~ /^All$/i ) {
    1694       push @{$SDFilesInfo{SpecifiedDataFieldLabels}[$Index]}, @DataFieldLabels;
    1695     }
    1696     elsif ($OptionsInfo{SpecifiedDataFields} =~ /^Common$/i) {
    1697       push @{$SDFilesInfo{SpecifiedDataFieldLabels}[$Index]}, @CommonDataFieldLabels;
    1698     }
    1699     else {
    1700       push @{$SDFilesInfo{SpecifiedDataFieldLabels}[$Index]}, split(",", $OptionsInfo{SpecifiedDataFields});
    1701     }
    1702
    1703     # Setup HTML data directories paths...
    1704     $TopHTMLDir = lc($SDFilesInfo{HTMLRoot}[$Index]) . "-html";
    1705     $SDFilesInfo{TopHTMLDir}[$Index] = "$TopHTMLDir";
    1706     $SDFilesInfo{SubHTMLDir}[$Index] = "$TopHTMLDir\/html";
    1707     $SDFilesInfo{SubMolDir}[$Index] = "$TopHTMLDir\/mol";
    1708   }
    1709 }
    1710
    1711 # Setup information...
    1712 sub SetupMultipleTablesAndMiscInfo {
    1713   SetupMultipleTablesInfo();
    1714   SetupMiscInfo();
    1715 }
    1716
    1717 # Setup navigation link information for multiple tables...
    1718 sub SetupMultipleTablesInfo {
    1719   my($Index, $LinesPerTable);
    1720
    1721   $LinesPerTable = $OptionsInfo{MaxCmpdsPerTable};
    1722
    1723   @{$SDFilesInfo{TableCount}} = ();
    1724   @{$SDFilesInfo{TableHTMLFiles}} = ();
    1725   @{$SDFilesInfo{TableStartCmpdNum}} = ();
    1726   @{$SDFilesInfo{TableEndCmpdNum}} = ();
    1727
    1728   for $Index (0 .. $#SDFilesList) {
    1729     $SDFilesInfo{TableCount}[$Index] = 1;
    1730     @{$SDFilesInfo{TableHTMLFiles}[$Index]} = ();
    1731     @{$SDFilesInfo{TableStartCmpdNum}[$Index]} = ();
    1732     @{$SDFilesInfo{TableEndCmpdNum}[$Index]} = ();
    1733
    1734     if ($SDFilesInfo{FileOkay}[$Index]) {
    1735       if ($SDFilesInfo{MultipleHTMLTables}[$Index]) {
    1736         my($TableIndex, $TotalLines, $TableCount, $TableStartLineNum, $TableEndLineNum, $Name);
    1737
    1738         $TotalLines = $SDFilesInfo{CmpdCount}[$Index];
    1739         $TableCount = ($TotalLines % $LinesPerTable) ? (int($TotalLines/$LinesPerTable) + 1) : ($TotalLines/$LinesPerTable);
    1740         $SDFilesInfo{TableCount}[$Index] = $TableCount;
    1741         for $TableIndex (1 .. $TableCount) {
    1742           $TableStartLineNum = ($TableIndex - 1) * $LinesPerTable + 1;
    1743           $TableEndLineNum = ($TableIndex == $TableCount) ? $TotalLines : ($TableIndex * $LinesPerTable);
    1744           push @{$SDFilesInfo{TableStartCmpdNum}[$Index]}, $TableStartLineNum;
    1745           push @{$SDFilesInfo{TableEndCmpdNum}[$Index]}, $TableEndLineNum;
    1746
    1747           # Setup HTML file names for all the tables...
    1748           $Name = "Cmpd" . "$TableStartLineNum" . "To" . "$TableEndLineNum";
    1749           if ($TableIndex == 1) {
    1750             $Name = "";
    1751           }
    1752           $Name = $SDFilesInfo{HTMLRoot}[$Index] . $Name . ".html";
    1753           push @{$SDFilesInfo{TableHTMLFiles}[$Index]}, $Name;
    1754         }
    1755         #print "$SDFilesList[$Index]: $TableCount -  @{$SDFilesInfo{TableStartCmpdNum}[$Index]} - @{$SDFilesInfo{TableEndCmpdNum}[$Index]} -  @{$SDFilesInfo{TableHTMLFiles}[$Index]}\n";
    1756       }
    1757     }
    1758   }
    1759 }
    1760
    1761 # Setup HTML tags and other information...
    1762 sub SetupMiscInfo {
    1763   $SDFilesInfo{RowHeaderTags} = "";
    1764   $SDFilesInfo{RowEndTags} = "";
    1765   $SDFilesInfo{BgFilledOddRowHeaderTags} = "";
    1766   $SDFilesInfo{BgFilledEvenRowHeaderTags} = "";
    1767   $SDFilesInfo{TableRowHeaderTags} = "";
    1768
    1769   $SDFilesInfo{RowHeaderTags} = SetupHTMLTableRowHeader($OptionsInfo{RowHAlignment}, "", $OptionsInfo{RowVAlignment});
    1770   $SDFilesInfo{RowEndTags} = SetupHTMLTableRowEnd();
    1771
    1772   if ($OptionsInfo{ShadeRowsStatus}) {
    1773     $SDFilesInfo{BgFilledOddRowHeaderTags} = SetupHTMLTableRowHeader($OptionsInfo{RowHAlignment}, $OptionsInfo{OddRowsShadeColor}, $OptionsInfo{RowVAlignment});
    1774     $SDFilesInfo{BgFilledEvenRowHeaderTags} = SetupHTMLTableRowHeader($OptionsInfo{RowHAlignment}, $OptionsInfo{EvenRowsShadeColor}, $OptionsInfo{RowVAlignment});
    1775   }
    1776
    1777   $SDFilesInfo{TableRowHeaderTags} = SetupHTMLTableRowHeader($OptionsInfo{TableHeaderRowHAlignment}, $OptionsInfo{TableHeaderRowColor}, $OptionsInfo{TableHeaderRowVAlignment});
    1778
    1779   $SDFilesInfo{MolEndTag} = "M  END";
    1780   $SDFilesInfo{White} = qq(#ffffff);
    1781 }
    1782
    1783 # Setup various data directories to hold HTML and other related files...
    1784 sub SetupDataDirs {
    1785   my($Index) = @_;
    1786   my($TopHTMLDir, $SubHTMLDir, $SubMolDir, $CreateTopHTMLDir, $CreateSubHTMLDir, $CreateSubMolDir);
    1787
    1788   $TopHTMLDir = $SDFilesInfo{TopHTMLDir}[$Index];
    1789   $SubHTMLDir = $SDFilesInfo{SubHTMLDir}[$Index];
    1790   $SubMolDir = $SDFilesInfo{SubMolDir}[$Index];
    1791
    1792   # Clean up existing directories...
    1793   if (-d $TopHTMLDir) {
    1794     unlink "<$TopHTMLDir/*.html>";
    1795     unlink "<$TopHTMLDir/*.css>";
    1796   }
    1797   if (-d $SubHTMLDir) {
    1798     unlink "<$SubHTMLDir/*.html>";
    1799   }
    1800   if (-d $SubMolDir) {
    1801     unlink "<$SubMolDir/*.mol>";
    1802   }
    1803
    1804   # What directories need to be created...
    1805   $CreateTopHTMLDir = (-d $TopHTMLDir) ? 0 : 1;
    1806   $CreateSubHTMLDir = (-d $SubHTMLDir) ? 0 : 1;
    1807   $CreateSubMolDir = 0;
    1808   if ($OptionsInfo{StrViewerType} =~ /^(Jmol|Chime|Chem3DActiveX|ChemDrawActiveX|ChemDrawPlugIn|ViewerActiveX)$/i) {
    1809     $CreateSubMolDir = (-d $SubMolDir) ? 0 : 1;
    1810   }
    1811
    1812   # Create appropriate directories...
    1813   if ($CreateTopHTMLDir) {
    1814     mkdir $TopHTMLDir or die "Couldn't mkdir $TopHTMLDir: $! \n";
    1815   }
    1816   if ($CreateSubHTMLDir) {
    1817     mkdir $SubHTMLDir or die "Error: Couldn't mkdir $SubHTMLDir: $! \n";
    1818   }
    1819   else {
    1820     unlink <$SubHTMLDir/*.html>;
    1821   }
    1822   if ($CreateSubMolDir) {
    1823     mkdir $SubMolDir or die "Error: Couldn't mkdir $SubMolDir: $! \n";
    1824   }
    1825   return ($TopHTMLDir, $SubHTMLDir, $SubMolDir);
    1826 }
    1827
    1828 # Setup script usage  and retrieve command line arguments specified using various options...
    1829 sub SetupScriptUsage {
    1830
    1831   # Retrieve all the options...
    1832   %Options = ();
    1833
    1834   $Options{mode} = "shade";
    1835   $Options{highlightstyle} = "background";
    1836
    1837   $Options{cellpadding} = 2;
    1838   $Options{cellspacing} = 1;
    1839
    1840   $Options{displaylinks} = "both";
    1841   $Options{displaylinksinfo} = "both";
    1842   $Options{stylesheet} = "new";
    1843
    1844   $Options{structure} = "display";
    1845   $Options{strlinktype} = "href";
    1846   $Options{strlinkmode} = "plain";
    1847   $Options{strlinknavigation} = "yes";
    1848   $Options{strlinktitledisplay} = "no";
    1849
    1850   $Options{strviewertype} = "Jmol";
    1851   $Options{strviewerembed} = "direct";
    1852
    1853   $Options{titledisplay} = "yes";
    1854
    1855   if (!GetOptions(\%Options, "align|a=s", "border|b=i", "cellpadding=i", "cellspacing=i", "cmpddatafield|c=s", "datafields=s", "footer=s", "displaylinks|d=s", "displaylinksinfo=s", "help|h", "headeralign=s", "headercolor=s", "highlight=s", "highlightcolor=s", "highlightstyle=s", "mode|m=s", "numcmpds|n=i", "overwrite|o", "root|r=s", "shadecolor=s", "stylesheet=s", "stylesheetname=s", "structure|s=s", "strlinkmode=s", "strlinknavigation=s", "strlinkshadecolor=s", "strlinktitle=s", "strlinktitledisplay=s", "strlinktype=s", "strviewertype=s", "strviewerconfig=s", "strviewerparams=s", "strviewerembed=s",  "strviewerjsfile=s", "strtablesize=s", "title|t=s", "titledisplay=s", "workingdir|w=s")) {
    1856     die "\nTo get a list of valid options and their values, use \"$ScriptName -h\" or\n\"perl -S $ScriptName -h\" command and try again...\n";
    1857   }
    1858
    1859   if ($Options{workingdir}) {
    1860     if (! -d $Options{workingdir}) {
    1861       die "Error: The value specified, $Options{workingdir}, for option \"-w --workingdir\" is not a directory name.\n";
    1862     }
    1863     chdir $Options{workingdir} or die "Error: Couldn't chdir $Options{workingdir}: $! \n";
    1864   }
    1865   if ($Options{displaylinks} !~ /^(top|bottom|both)$/i) {
    1866     die "Error: The value specified, $Options{displaylinks}, for option \"-d --displaylinks\" is not valid. Allowed values: top, bottom, or both\n";
    1867   }
    1868   if ($Options{displaylinksinfo} !~ /^(compound|table|both)$/i) {
    1869     die "Error: The value specified, $Options{displaylinksinfo}, for option \"--displaylinksinfo\" is not valid. Allowed values: compound, table, or both\n";
    1870   }
    1871   if ($Options{highlightstyle} !~ /^(background|text)$/i) {
    1872     die "Error: The value specified, $Options{highlightstyle}, for option \"--highlightstyle\" is not valid. Allowed values: background or text\n";
    1873   }
    1874   if ($Options{mode} !~ /^(plain|shade|highlight|shadedhighlight|structuresonly|shadedstructuresonly)$/i) {
    1875     die "Error: The value specified, $Options{mode}, for option \"-m --mode\" is not valid. Allowed values: plain, shade, hightlight, shadedhighlight, structuresonly, or shadedstructuresonly\n";
    1876   }
    1877   if ($Options{stylesheet} !~ /^(old|new|none)$/i) {
    1878     die "Error: The value specified, $Options{stylesheet}, for option \"-s --stylesheet\" is not valid. Allowed values: old, new, or none\n";
    1879   }
    1880   if ($Options{structure} !~ /^(display|link)$/i) {
    1881     die "Error: The value specified, $Options{structure}, for option \"-s --structure\" is not valid. Allowed values: display or link\n";
    1882   }
    1883   if ($Options{strlinkmode} !~ /^(plain|shade)$/i) {
    1884     die "Error: The value specified, $Options{strlinkmode}, for option \"--strlinkmode\" is not valid. Allowed values: plain or shade\n";
    1885   }
    1886   if ($Options{strlinktype} !~ /^(href|button)$/i) {
    1887     die "Error: The value specified, $Options{strlinktype}, for option \"--strlinktype\" is not valid. Allowed values: href or button\n";
    1888   }
    1889   if ($Options{strlinknavigation} !~ /^(yes|no)$/i) {
    1890     die "Error: The value specified, $Options{strlinknavigation}, for option \"--strlinknavigation\" is not valid. Allowed values: yes or no\n";
    1891   }
    1892   if ($Options{strlinktitledisplay} !~ /^(yes|no)$/i) {
    1893     die "Error: The value specified, $Options{strlinktitledisplay}, for option \"--strlinktitledisplay\" is not valid. Allowed values: yes or no\n";
    1894   }
    1895   if ($Options{strviewertype} !~ /^(JME|Jmol|Chime|MarvinView|ChemDrawPlugIn|Chem3DActiveX|ChemDrawActiveX|ViewerActiveX)$/i) {
    1896     die "Error: The value specified, $Options{strviewertype}, for option \"--strviewertype\" is not valid. Allowed values: Chem3DActiveX, ChemDrawActiveX, ChemDrawPlugIn, Chime, JME, Jmol, MarvinView, or ViewerActiveX.\n";
    1897   }
    1898   if ($Options{strviewerembed} !~ /^(direct|javascript)$/i) {
    1899     die "Error: The value specified, $Options{strviewerembed},  for option \"--strviewerembed\" is not valid. Allowed values: direct or javascript \n";
    1900   }
    1901   if (exists $Options{numcmpds} && $Options{numcmpds} < 0) {
    1902     die "Error: The value specified, $Options{numcmpds},  for option \"-n --numcmpds\" is not valid. Allowed values: >= 0 \n";
    1903   }
    1904   if ($Options{titledisplay} !~ /^(yes|no)$/i) {
    1905     die "Error: The value specified, $Options{titledisplay}, for option \"--titledisplay\" is not valid. Allowed values: yes or no\n";
    1906   }
    1907   if (exists($Options{border})) {
    1908     if ($Options{border} < 0) {
    1909       die "Error: The value specified, $Options{border},  for option \"--border\" is not valid. Allowed values: >= 0 \n";
    1910     }
    1911   }
    1912   if ($Options{cellpadding} < 0) {
    1913     die "Error: The value specified, $Options{cellpadding},  for option \"--cellpadding\" is not valid. Allowed values: >= 0 \n";
    1914   }
    1915   if ($Options{cellspacing} < 0) {
    1916     die "Error: The value specified, $Options{cellspacing},  for option \"--cellspacing\" is not valid. Allowed values: >= 0 \n";
    1917   }
    1918 }
    1919