#!/home/rebelsky/perl/bin/perl

# Sarah Luebke
# started 06/15/99
# last modified 07/28/99

# This script is called from search_form.cgi, which
# asks for a search string and whether the search was
# a keyword or exact string search.  The url is a hidden
# variable in search_form.
# This script will search through
# all the files associated with the URL (annotations and replies) 
# and returns all matches.

#package declaration
package SearchAnnotations;
use Exporter ();
@ISA = (Exporter);
@EXPORT = qw(search_execute);

########################
#IMPORT MODULES
########################
use Search;
use AFile; # ::readFile
use History; # to get last_time
use Network; #This sets up the readInFile subroutine which talks
             # to the annotation server (thanks to Andrew!)
use HTTP::Request;
use HTTP::Daemon;
use URI::Escape;

sub search_execute 
  {
############################################################################
# This subroutine parses the form (http://www.math.grin.edu/~rebelsky/     #
# Blazers/Annotations/Summer1999/search_form.cgi) and stores the results   #
# in $form.                                                  #
############################################################################
    #read arguments
    my $name = shift; #id of the user for this request
    my $user_info = shift; #a string wit info on the user
    my $client = shift; #client connection
    my $client_request = shift; #request from the client
    #other variables
    local(*form); #the data from the form
    my $query; #the original query string
    

    #parse the string of user information
    $user_info =~ /<GROUPLIST>(.*)<\/GROUPLIST>/;
    $form{'groups'} = $1;
    $query = $client_request->url;
    $query =~ /\?(.*)/i;
    $query = $1;
    $query = uri_unescape($query);

    #split the query into parts
    $query =~ /url=([^\&]*)/i;
    $form{'url'}= $1;
    $query =~ /string=([^\&]*)/i;
    $form{'string'}= $1;
    # added by Sarah 08/17/99 to replace '+' by ' '
    $form{'string'} =~ s/\+/ /g;
    $query =~ /type=([^\&]*)/i;
    $form{'type'} = $1;
    $query =~ /last_time=([^\&]*)/i;
    $form{'lasttime'} = $1;
    $form{'name'} = $name;

    # call the search subroutine with the URL and keywords
    &search(*form,$client);

    #return the true value to show that it ran correctly
    return 1;
  }#search_execute


sub search {
############################################################################
# This subroutine takes the URL and a search string and looks up           #
# the strin in each file associated with that URL.                         #
############################################################################

########################
#VARIABLES
########################
  local(*form) = shift;
  my $client = shift; #client connection
  my $url = $form{'url'}; #url that called search
  my $string = $form{'string'}; #the string they are searching for
  my $type = $form{'type'}; #the type of search: keyword or exact
  my $name = $form{'name'}; #user's name
  my $groups = $form{'groups'}; #groups that user belongs to
  my $author; #author of annotation
  my $title; # title of annotation
  my $annotation; #text of the annotation
  my $protection; #whether the annotation is public, private, group
  my $lasttime = $form{'lasttime'};
  my $permission = 0; # boolean used to determine if the user has privs to
                      # view the annotation
  my $response; #the response to send the client
  my $response_object; #the client response object
  my $string_temp;
  my @matched = (); #an array to keep a list of the annotation files that
               # were matched
  my @words;
  my @files;
  my $keyword = 0;
  my $count = 0;
  my $test = 0;
  my $found = 0;
  my $dir;
  local(*fields);


  # Check if this is a keyword search or exact string
  if ($type eq "keyword") {
    $keyword = "1";
  } #if
  elsif ($type eq "exact") {
    $keyword = "0";
  }
  elsif ($type eq "author") {
    $keyword = "-1";
  }
         

  $response = <<"Print_tag";
<HTML>
<HEAD>

<SCRIPT LANGUAGE=\"Javascript1.1\">\nfunction OpenWindow(path,wdth,hght) {\nwindow.open(path,'Annotations','toolbar=no,location=no,directories=no,status=yes,menubar=yes,scrollbars=yes,resizable=yes,copyhistory=no,width=wdth,height=hght');\n} </SCRIPT>

<meta name=\"Ravel\" content=\"disallow: .*?-.*?-.*?-.*?\$\"><br>
<TITLE>Search Annotations for $url</TITLE></HEAD>

<BODY BGCOLOR=\"WHITE\">
Print_tag


  # Open index.txt and check if the URL is there.  If it is, get the name 
  # of the directory associated with it.
  # readIndex is from Search.pm
  $dir = readIndex($url); 

  # Print a header
  if ($keyword == 1) {
    $response = $response . "<h1>You did a keyword search for: $string</h1>";
    #split the search string into words
    @words = split ' ', $string;
  }#if ($keyword == 1)
  elsif ($keyword == 0) {
    $response = $response . "<h1>You searched for: \'$string\'</h1>";
    # We only want to slashify $string once, so do it
    # now, before looping thru each file.
    # Save a copy of the unslashified string in string_temp  
    $string_temp = $string;
    # call textToSearch from the Search module to
    $string = textToSearch($string);
  }#elsif
  elsif ($keyword == -1) {
    $response = $response . "<h1>You searched for the author: \'$string\'</h1>";
  } #else
  # Now look at each file in the directory
  @files = glob("$dir/*.txt"); #all files with extension .txt
  push @files, glob("$dir/*.r"); #add all files with extension .r (reply)
  foreach $file (@files) {
    # call AFile::readFile to get the contents of the annotation
    readFile(*fields,$file);
    $author = $fields{'author'};
    $title = $fields{'title'};
    $annotation = $fields{'annotation'};
    $protection = $fields{'protection'}; #whether it's public, private or groups
    #strip extra white-space from beginning and end
    $author =~ s/^\s*//;
    $author =~ s/\s*$//;
    $title =~ s/^\s*//;
    $title =~ s/\s*$//;
    $annotation =~ s/^\s*//;
    $annotation =~ s/\s*$//;
    $protection =~ s/^\s*//;
    $protection =~ s/\s*$//;


# Check if the user doing the search has permission to view the annotation
    # Check if the user is the author, or the sysadmin
    if (($author eq $name) || ("sysadmin" eq $name)) {
        $permission = 1;
      }
    elsif ($protection eq "private") {
          $permission = 0;
        }
    elsif ($protection eq "public") {
        $permission = 1;
      }
    else {
        $permission = 0;
        my @user_groups = split(/\,/,$groups);
        my @annotation_groups = split(/\,/,$protection);
        foreach $annotation_group (@annotation_groups)
          {
            foreach $user_group (@user_groups)
              {
                if ($annotation_group eq $user_group)
                  {
                    $permission = 1;
                  }
              }
          }
      } #else
    
    # Now search each annotation for the correct thing

    #this is a keyword search
    if ($keyword == 1) {
      foreach $word (@words) {
         $word = textToSearch($word);
         if (($annotation =~ m/$word/igs) && ($permission == 1)) {
           # A match was found, so print the annotation
           $found = 1;
           if (check_matched(@matched, $file) == 0) {
             # This is a new match, so add $file to the array
             push @matched, $file;
             #print the match
             $response = $response . "\n";         
             $response = $response . "<hr align=left width=\"50\">";   
             $resposne = $response .  "<h3>\'$word\' was found:</h3>";
             #$response = $response . "<p>File name: $file<br>";
             $response = $response . "Text of annotation: <br> $annotation \n";
             # Print an icon that includes the javascript for displaying 
             # the annotation.  When the button is clicked, annotation.cgi
             # is called which displays the annotation.
             $response = $response . "<a href=\"javascript:OpenWindow('http://ravel/Annotation/annotation.cgi?" . $file . "\&" . $url . "\&" . $lasttime . "',500,500)\"><img border=0 src=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/forward_arrow_small.gif\" alt=\"" . $title . "\"><\/a> </P>";
           } # if
         } #if
         elsif (($title =~ m/$word/igs) && ($permission == 1)) {
           $found = 1; 
           if (check_matched(@matched, $file) == 0) {
             # This is a new match, so add $file to the array
             push @matched, $file; # add the file to the list of matches
             #print the match
             $response = $response . "\n";         
             $response = $response . "<hr align=left width=\"50\">";
             $response = $response . "<h3>\'$word\' was found:</h3>";
             #$response = $response . "<p>File name: $file<br>";
             $response = $response . "The text was found in the title: $title <br>\n";
             $response = $response . "Annotation:  <br> $annotation \n";
             # Print an icon that includes the javascript for displaying 
             # the annotation.  When the button is clicked, annotation.cgi
             # is called which displays the annotation.
             $response = $response . "<a href=\"javascript:OpenWindow('http://ravel/Annotation/annotation.cgi?" . $file . "\&" . $url . "\&" . $lasttime . "',500,500)\"><img border=0 src
=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/forward_arrow_small.gif\" alt=\"" . $title . "\"><\/a> </P>";
           } #if
         } #if
       } #foreach $word
    } #if
    elsif ($keyword == 0) { #exact string match
        if (($annotation =~ m/$string/igs) && ($permission == 1)) {
          $found = 1;
           if (check_matched(@matched, $file) == 0) {
             # This is a new match, so add $file to the array
             push @matched, $file; # add the file to the list of matches
             #print the match
             $response = $response . "\n";
             $response = $response . "<hr align=left width=\"50\">";
             $response = $response . "<h3>\'$string_temp\' was found:</h3>";
             #$response = $response . "<p>File name: $file<br>\n";
             $response = $response . "Text of annotation: <br> $annotation \n";
             # Print an icon that includes the javascript for displaying the annotation
             $response = $response . "<a href=\"javascript:OpenWindow('http://ravel/Annotation/annotation.cgi?" . $file . "\&" . $url . "\&" . $lasttime . "',500,500)\"><img border=0 src=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/forward_arrow_small.gif\" alt=\"" . $title . "\"><\/a> </P>";
           }#if
        } #if
        elsif (($title =~ m/$string/igs) && ($permission == 1)) {
          $found = 1;
          # A match was found, so print the annotation
          if (check_matched(@matched, $file) == 0) {
            # This is a new match, so add $file to the array
            push @matched, $file; # add the file to the list of matches
            #print the match
            $response = $response . "\n";
            $response = $response . "<hr align=left width=\"50\">";
            $response = $response . "<h3>\'$string_temp\' was found:</h3>";
            #$response = $response . "<p>File name: $file<br>\n";
            $response = $response . "Match was found in the title: $title <br>\n";
            $response = $response . "Text of annotation: <br> $annotation \n";
            # Print an icon that includes the javascript for 
            #  displaying the annotation
            $response = $response . "<a href=\"javascript:OpenWindow('http://ravel/Annotation/annotation.cgi?" . $file . "\&" . $url . "\&" . $lasttime . "',500,500)\"><img border=0 src=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/forward_arrow_small.gif\" alt=\"" . $title . "\"><\/a> </P>";
          } #if
        } #elsif
      } #elsif ($keyword == 0)
    else { # Author Search
      if (($author =~ m/$string/igs) && ($permission == 1)) {
        # The author was found, and the permission is readable by
        # this user, so display the annotation.
        $found = 1;
        $response = $response . "\n";
        $response = $response . "<hr align=left width=\"50\">";
        $response = $response . "<h3>\'$string\' was found:</h3>";
        #$response = $response . "<p>File name: $file<br>";
        $response = $response . "An annotation was found by $author. <br>";
        $response = $response . "Text of annotation: <br> $annotation<br>\n";
        $response = $response . "<a href=\"javascript:OpenWindow('http://ravel/Annotation/annotation.cgi?" . $file . "\&" . $url . "\&" . $lasttime . "',500,500)\"><img border=0 src=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/forward_arrow_small.gif\" alt=\"" . $title . "\"><\/a> </P>";

      } #if
    } #elsif
  } #foreach $file (@files)

  # If the string (or keywords) was never found
  if ($found == 0) {
    $response = $response . "<p>That string was not matched</p>";
  } #if

  # Now print the rest of the HTML
  $response = $response . "<FORM>";
  $response = $response . "<input type=\"button\" name=\"close\" value=\"Close\" onClick=self.close()>";
  $response = $response . "<input type=\"button\" name=\"search\" value=\"Search Again\" onClick=\"document.location=\'http://ravel/Annotation/search_form.cgi?$url\&$lasttime'\">";
  $response = $response . "</FORM>";
  $response = $response . "</BODY>";
  $response = $response . "</HTML>";

  #create the response object and send it to the client
  $response_object = HTTP::Response->new(200);
  $response_object->content($response);
  $client->send_response($response_object);
} #search()

sub check_matched {
# This subroutine checks if the file has already been
# matched.  If it has, return true and do not print it again. 
# If it hasn't, return false and print the annotation.

  # Variables
  my @matched = shift;
  my $file = shift;
  my $temp;

  # Check that this file is in @mathced
  foreach $temp (@matched) {
    if ($temp eq $file) {
      # This has already been added to @matched
      return 1;
    } #if ($line =~ m/$temp/)
  } #foreach $temp (@matched)
  
  # If we make it this far, $file is not in @matched,
  # so return 0
  return 0;
}

#return the true value to show that the package loaded correctly
return 1;

######################################################################
# Pod Documentation #
#####################

#=head1 Name

#SearchAnnotations (Previously known as search)

#=over 4

#=item search_execute

 #This subroutine parses the form (http://www.math.grin.edu/~rebelsky/     
 #Blazers/Annotations/Summer1999/search_form.cgi) and stores the results   
 #in $form.  It takes in a typeglob to be used as a hash.  It calls search 
 #at the end.                                                              

#=item search 

 #This subroutine takes the URL, a search string, and whether it's
 #a keyword or exact string search, and looks up      
 #the string in each file associated with that URL.                     
 #The results are then displayed in the same window, with a
 #link to display the full annotation.                                       

#=item check_matched

 # This subroutine checks if the file has already been
 # matched.  If it has, return true and do not print it again. 
 # If it hasn't, return false and print the annotation.

#=back

#=head 1 History

#=over 4

#=item [15 June 99]

#Began coding.

#=item [29 June 99]

# Now searches replies and displays everything in a better
# format.  Works as far as I can tell.

#=item [06 July 99]

# Added comments (e.g., commented closing braces).

#=item [7 July 99]

# Instead of opening and reading files, search now
# calls readInFile from DataBase.pm

#=item [12 July 1999]

#Gets and passes the name, email, and groups of the user.

#=item [27-28 July 1999]

# Added permissions checks

#=item [4 August 1999]

#Turned the script (search.cgi) into a package (SearchAnnotations.pm) in 
#order to use Proxy URLs.  This adds security.  All cgi calls are now Proxy 
#URLs.  The name, email, and groups information are no longer being passed to 
#cgi scripts.

#=back

#=cut

