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

#   /home/rebelsky/public_html/Blazers/Annotations/Summer1999/Insert.pm
#   Sarah Luebke
#   converted from insert.cgi to Insert.pm to work
#   with Ravel 07/15/99
#
#   This script gets a URL, html, name, email and group info from
#   Plugin.pm.  Then it reads information from 
#   /home/rebelsky/public_html/Blazers/Annotations/Stored_Annotations/index.txt 
#   and determines if annotations exist for that URL.
#   If there are annotations for that document, find the directory containing
#   those annotations and search the document for the correct placement
#   of the annotations.  Then insert the annotation flags (small triangles)
#   and the Javascript code to open a window. 
#
#   INPUT: URL, html name, email and group info from Plugin.pm
#   
#   OUTPUT: returns the page with the proper
#   javascript and annotation flags added (and prints it out).


#Package ID
package Insert;
use Exporter ();
@ISA = (Exporter);
@EXPORT = qw(main);

use LWP::Simple;
use HTML::Parse;
use URI::Escape;
use AFile; 
use Search;
use History;

# call the subroutines
#&main;
# extractInfo is called in main and 
# insertAnnotation is called in extractInfo

sub main {
  

  ##########################################################################
  # This subroutine takes url, html and user info and calls                
  # extractInto to do the rest.
  # INPUT: url, html, name of user, email of user, a list of
  #         the user's groups
  # OUTPUT: The new html page
  ##########################################################################

  #VARIABLES                    
  my $url = shift;
  my $html = shift;
  my $name = shift; #the users name
  my $email = shift; #the email address of the user
  my @groups = shift; #groups that user belongs to
  my $first; #boolean: first group in list
  my $group; #each group individually
  my $lasttime; #last time that this page was accessed as returned by History->history

  #update the history and get the last time that the page was accessed by 
  #this user.
  $lasttime = history($name,$url); 


  #read in the groups....added by Rachel Heck on 7/12/99
  $first = 1;
  foreach $group (@groups)
    {
      if ($first == 1)
        {
          $groups = $group;
          $first = 0;
        }                       #if ($first == 1)
      else
        {
          $groups = "$groups,$group";
        }                       #else
    }                           #foreach $group (param("groups")

 
################################################################
  
  # Call extractInfo with $url and $html
  &extractInfo($url,$html,$name,$email,$groups,$lasttime);
} # main


sub extractInfo {
  ##########################################################################
  # This subroutine checks if the page has been annotated by looking in    #
  # index.txt.  If it has, then extract the annotation info from the       #
  # files in the appropriate directory.                                    #
  ##########################################################################
  
  #VARIABLES
  my $url = shift;
  my $html = shift;
  my $name = shift;              #the users name
  my $email_user = shift;        #the users email addres
  my $groups = shift;            #the groups that the user is a member
  my $lasttime = shift;          #the last time this url was accessed
  my $dir;
  my @stored;
  my $author;                    #author of annotation
  my $email;                     #email of the author of the annotation
  my $date;                      #date and time of the annotation
  my $title;                     #Title of the annotation
  my $annotated_text;            #text that was annotated - the flags 
                                   #go on either side of this
  my $annotation;                #text of annotation
  my $context;                   #context of the annotation
  my $times;                     #number of times annotated_text exists
  my $protection;                #boolean of whether the user has 
                                   #permission to view the annotation
  my $permission;
  my $time;                      #the time that the annotation was made
  my @user_groups;
  my @annotation_groups;
  my $file;
  local (*fields);
  
  # 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.  It takes a url and returns the directory
  # associated with that url.
  $dir = readIndex($url);
  # Now look at each file in the directory (only 
  # the .txt files)
  if ($dir ne 0) {
    foreach $file (<$dir\/*.txt>) { 
      #call readFile from the AFile module.  This will parse the annotation file.
      readFile(*fields,$file);
      
      #store the results from parsing the file
      $author = $fields{'author'};
      $email = $fields{'email'};
      $date = $fields{'date'};
      $time = $fields{'time'};
      $title = $fields{'title'};
      $annotated_text = $fields{'annotated_text'};
      $annotation = $fields{'annotation'};
      $context = $fields{'context'};
      $times = $fields{'times'}; # number of times the annotated_text occurs
      $protection = $fields{'protection'}; #whether it's public, private or groups
      #strip extra white-space characters from the beginning and ending of
      #variables
      @stored = ($author,$email,$date,$time,$title,$annotated_text,$annotation,$context,$times,$protection);    
      foreach $thing (@stored) {
        # Strip extra white-space characters from the beginning and end.
        # Written with help from Sam
        $thing =~ s/^\s*//;
        $thing =~ s/\s*$//;
      }                         #foreach
      
      # extract the author's name, email, date and title, annotated_text,
      # annotation, context and times
      $author = $stored[0];
      $email = $stored[1];
      $date = $stored[2];
      $time = $stored[3];
      $title = $stored[4];
      $annotated_text = $stored[5];
      $annotation = $stored[6];
      $context = $stored[7];
      $times = $stored[8];
      $protection = $stored[9];
      
      # Call insertAnnotation with $html, $author, $email, $date, $time, 
      # $title, $annotated_text, $annotation, $context, $times, $file, 
      # $url, and $lasttime
      # Check if the user has permissions.  Taken from TreeCreation.pm,
      # written by Rachel Heck.
      
      #remove extra spaces
      $fields{'protection'} =~ s/^(\s*)//i;
      $fields{'protection'} =~ s/(\s*)$//i;
      
      # Check if the user is the author, or the sysadmin
      if (($fields{'author'} eq $name) || ("sysadmin" eq $name))
        {
          $permission = 1;
        }
      elsif ($fields{'protection'} eq "private")
        {
          $permission = 0;
        }
      elsif ($fields{'protection'} eq "public")
        {
          $permission = 1;
        }
      else
        {
          $permission = 0;
          @user_groups = split(/\,/,$groups);
          @annotation_groups = split(/\,/,$fields{'protection'});
          foreach $annotation_group (@annotation_groups)
            {
              foreach $user_group (@user_groups)
                {
                  if ($annotation_group eq $user_group)
                    {
                      $permission = 1;
                    }
                }
            }
        }
      if ($permission == 1) {
        $html = &insertAnnotation($html,$author,$email,$date,$time,$title,$annotated_text,$annotation,$context,$times,$file,$url,$name,$email_user,$groups,$lasttime);
      }                         # if (permission == 1)
  }                             #foreach $file (<$dir\/*.txt>)
 } 
  # Add a toolbar at the top of the page with the code for calling the add page
  my $disclaimer = "<small><center>This page was created as part of a research project with Samuel Rebelsky, Rachel Heck and Sarah Luebke.</center></small>";

  # call load_add.cgi and give it the URL, name, users's email and groups
  my $add_button = "<a href=\"javascript:OpenWindow('http://ravel/Annotation/load_add.cgi?new\&$url\&\&$lasttime',500,500)\"><img src=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/add.gif\" border=0 alt=\"Add Annotation\"><\/a>";
  
  # call search.cgi and give it the URL, name, users's email and groups
  my $search_button = "<a href=\"javascript:OpenWindow2('http://ravel/Annotation/search_form.cgi?$url\&$lasttime', 500, 500)\"><img src=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/search.gif\" border=0 alt=\"Search Annotations\"><\/a>";


  #my $help_button = "<a href=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/help.html\"0><img border=0 src=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/help.gif\"></a>";
  my $help_button = "<a href=\"javascript:OpenWindow3('http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/help.html')\"><img src=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/help.gif\" border=0 alt=\"Help page\"><\/a>";

  my $red_arrow = "<img src= \"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/red_arrow_forward.gif\">";
  my $green_arrow = "<img src= \"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/green_arrow_forward.gif\">";
  my $yellow_arrow = "<img src=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/forward_arrow_small.gif\">";
  # We don't need the arrow key anymore since it is on the help page
  #my $arrow_key = "$red_arrow = New annotation since last visit<br>$green_arrow = New reply since last visit<br>$yellow_arrow = Annotation and all replies added prior to last visit";
  

  if ($html =~ /<html>/i) {
    $html =~ s/(<html>)/$1$add_button$search_button$help_button<br>\n/i;
  } #if
  
  #add javascript script for opening a new window into the head of the document
  my $java = "\n<SCRIPT LANGUAGE=\"Javascript1.1\">\nfunction OpenWindow(path,wdth,hght) {\nAnnotations = window.open(path,'Annotations','toolbar=no,location=no,directories=no,menubar=yes,status=yes,scrollbars=yes,resizable=yes,copyhistory=no,width=wdth,height=hght');\nAnnotations.focus();\n} </SCRIPT>\n";
  # add javascript for opening a new window for the search
  my $java_search = "\n<SCRIPT LANGUAGE=\"Javascript1.1\">\nfunction OpenWindow2(path,wdth,hght) {\nSearch = window.open(path,'Search','toolbar=no,location=no,directories=no,status=yes,menubar=yes,scrollbars=yes,resizable=yes,copyhistory=no,width=wdth,height=hght');\nSearch.focus();\n} </SCRIPT>\n";
 # add javascript for opening a new window for the help page
  my $java_help =  "\n<SCRIPT LANGUAGE=\"Javascript1.1\">\nfunction OpenWindow3(path,wdth,hght) {\nHelp = window.open(path,'Help','toolbar=no,location=no,directories=no,status=yes,menubar=yes,scrollbars=yes,resizable=yes,copyhistory=no,width=wdth,height=hght');\nHelp.focus();\n} </SCRIPT>\n";

  
  if ($html =~ /<head>/i) {
    #insert the javascripts
    $html =~ s/(<head>)/$1$java \n $java_search \n $java_help/i;
  } # if
  elsif ($html =~ /<html>/i) {
    $html =~ s/(<html>)/$1<head>$java \n $java_search \n $java_help<\/head>\n/i;
  } # elsif
  else {
    $html = "<head>$java \n $java_search \n $java_help<\/head>\n" . $html;
  } # else
  
  # We're done, so return the new document
  return "$html";
} # extractInfo()

sub insertAnnotation {
  ########################################################################
  # This subroutine searches for the annotated text and inserts          #
  # the annotation markers around it, along with the javascript          #
  # to open a new window displaying the annotation.                      #
  # It calls textToSearch in the Search.pm module
  ########################################################################
  
  # VARIABLES
  my $html = shift;
  my $author = shift;
  my $email = shift;
  my $date = shift;
  my $time = shift; #the time that the annotation was made
  my $title = shift;
  my $annotated_text = shift;
  my $annotation = shift;
  my $context = shift;
  my $times = shift;
  my $file = shift;
  my $url = shift;
  my $name = shift; #the users name
  my $email_user = shift; #the email address of the user
  my $groups = shift; #the groups that the user is a part of
  my $lasttime = shift; #the last time that this page was accessed
  my $found = 0;
  my $new_html;
  my $before; #used to hold the stuff matched before the context
  my $after;  #stuff matched after the context
  my $stuff;  # the context that was matched
  my $temp_before; # stuff matched before the annotated_text
  my $temp_string; # the annotated_text that was matched
  my $temp_after;  # stuff after the annotated_text
  my $new; #boolean:  is the annotation new since last viewing
  my $forward_arrow;
  my $back_arrow;


  #determine whether this is an annotation that the user has not seen
  $new = lessThan($lasttime,substr($date,0,2) . "/" . substr($date,2,2) . "/" . substr($date,4,2) . "\|" . $time);
 
  #use the appropriate arrow
  if (($new == 1) || ($new eq "equal"))
    {
      $forward_arrow = "<img src=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/red_arrow_forward.gif\" border=0 alt=\"" . $title . "\">";
      $back_arrow = "<img src=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/red_arrow_back.gif\" border=0 alt=\"" . $title . "\">";
    }#if (($new == 1) || ($new eq "equal"))
  else
    {
      $new = replyTest($lasttime,$file,$name,$groups);
      if ($new == 1)
        {
          $forward_arrow = "<img src=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/green_arrow_forward.gif\" border=0 alt=\"" . $title . "\">";
          $back_arrow = "<img src=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/green_arrow_back.gif\" border=0 alt=\"" . $title . "\">";
        }#if ($new == 1)
      else
        {          
          $forward_arrow = "<img src=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/forward_arrow_small.gif\" border=0 alt=\"" . $title . "\">";
          $back_arrow = "<img src=\"http://www.math.grin.edu/~rebelsky/Blazers/Annotations/Summer1999/Gifs/back_arrow_small.gif\" border=0 alt=\"" . $title . "\">";
        }#else
    }#else

  # Forward_arrow and back_arrow are icons to mark the annotations
  # and add the code to open a new window when clicked
  $forward_arrow = "<a href=\"javascript:OpenWindow('http://ravel/Annotation/annotation.cgi?" . $file . "\&" . $url . "\&" . $lasttime . "',500,500)\">$forward_arrow<\/a>";
 
  $back_arrow = "<a href=\"javascript:OpenWindow('http://ravel/Annotation/annotation.cgi?" . $file . "\&" . $url . "\&" . $lasttime . "',500,500)\">$back_arrow<\/a>";

  # Call the textToSearch function from the Search module
  # to slashify, change all white-spaces to account 
  # for HTML tags or any number of white-spaces and
  # add possible <a> tags around parens and such.
  $annotated_text = textToSearch($annotated_text);
  $context = textToSearch($context);
  $context =~ s/<p>/<p>(<.\*>)\*/gi; #ACK!  I put this in because I had
  # "<p>Text" that wasn't matching and a general rule was too slow 

  # Search for $context in the html.  If it is found,
  # add the links and javascript for displaying the annotation.
  # FIX: Right now it is adding the annotate flags around the 
  # first instance of $annotated_text if the context is found!
  if ($html =~ m/($context)/i) {

    # save the parts of the document
    $before = "$`"; #everything before the context
    $after = "$'"; # everything after the context
    $stuff = "$1"; # the context that was matched

    # If the annotated text is matched, with a link around it,
    # keep the <a href> tag as part of the annotated text, unless
    # it is a javascript tag that I added.
    #if ($stuff =~ m/((?:<a \s*href\s*=\s*\"[^j].*?>\s*)+(?:[^<]*))($annotated_text(?:\s|.)*?(?:<\/a>)+)/i) 
    if ($stuff =~ m/(<a(?:\s)+href\s*=\s*\"[^j].*?>\s*)+($annotated_text(?:\s|[^>])*(?:<\/a>)+)/is) 
   
    {
      $found = 1;
      $temp_before = "$`"; # everything before the <a href>
      $temp_string = "$1" . "$2";   # the annotated text, including <a href>
      $temp_after = "$3" . "$'"; # everything after
    } #if ($stuff =~ m/(<a href.*?>\s*$annotated_text\s*<\/a>)/i)

    # If there isn't a link, match the annotated_text.
    # Also make sure it isn't inside a tag (taken from Rachel's code)
    elsif ($stuff =~ m/(>|(?:>[^<]*[^a-zA-Z_0-9<])|\W)($annotated_text)/is) 
    {
      $found = 1;
      $temp_before = "$`" . "$1"; # stuff before the annotated_text
      $temp_string = "$2"; # the annotated_text
      $temp_after =  "$'"; # stuff after
    } #elsif
    elsif ($stuff =~ m/($annotated_text)/is) {
     # In this case the annotated_text was only matched in a tag
print "Matched just annotated_text\n";
      $found = 1;
      $temp_before = "$`";
      $temp_string = "$1";
      $temp_after = "$'";
    }#elsif

    if ($found == 1) {
      # add the annotation flags around the annotated_text
      $temp_string = "$forward_arrow" . $temp_string  . "$back_arrow";
      # put the context string back together
      $stuff = "$temp_before" . "$temp_string" . "$temp_after";
      # put the html document back together
      $html = "$before" . "$stuff" . "$after";
      # we're done!
      $new_html = $html;
    }
    else {
      print "Annotated_text not found: $annotated_text\n";
    }
  } # if ($html =~ m/$context/i) {
  else { 
    # If the context wasn't matched,
    # look for the annotated text anyway.
    # WE SHOULD BE LOOKING FOR THE INSTANCE OF THE TEXT!
    if ($html =~ m/($annotated_text)/i) {
      $found = "-1"; # This is an exception because the context wasn't matched 
      $before = "$`";             #everything before the annotated text
      $after = "$'";              # everything after the text
      $stuff = "$1";              # the text that was matched

    # If the annotated text is matched, with a link around it,
    # keep the <a href> tag as part of the annotated text      
      if ($stuff =~ m/(<a \s*href\s*=\s*\"[^j].*?>\s*)+($annotated_text\s*(?:<\/a>)+)/i)  {
        # we have a match, with a link in front
        $temp_before = "$`";
        $temp_string = "$1";
        $temp_after = "$'";
      }                         #if
      # If there isn't a link, match the annotated_text.
      # Also make sure it isn't inside a tag (taken from Rachel's code)
      #elsif ($stuff =~ m/(>|(?:>[^<]*[^a-zA-Z_0-9<]))((?:$annotated_text)(?:s\*<a\s*href=\"javascript.*>)?)/i) 
#this new line was modeled after line 165 of Ambiguity.pm
       elsif ($stuff =~ m/((?:\W$annotated_text)(?:s\*<a\s*href=\"javascript.*>)?)(?:<|[^a-zA-Z_0-9<>][^>]*?<)/si)
        {
          $temp_before = "$`" . "$1";
          $temp_string = "$2";
          $temp_after = "$'";
        }#elsif
      else { # the annotated text was only matched w/in a tag
print "error! ";
#print "$annotated_text was only matched in a tag<br>\n";
        $temp_string = $stuff;
      } #else

      # add the annotation flags around the annotated_text
      $temp_string = "$forward_arrow" . $temp_string  . "$back_arrow";
      # rejoin the "stuff annotated_text stuff"
      $stuff = "$temp_before" . "$temp_string" . "$temp_after";
      # rejoin the "stuff context stuff"
      $html = "$before" . "$stuff" . "$after";
      # we're done
      $new_html = $html;
    } #if ($html =~ m/($annotated_text)/i)
  } #else  (the context wasn't matched)

  
  if ($found == 0) {
    print "Not Found<br>\n";    #ERROR:  What should we do if an annotation cannot be inserted?
    #print "annotated_text: $annotated_text <br>\n\n";
    #print "Context: $context\n\n";
    return $html;
  } # if ($found == 0)
  elsif ($found == -1) {
    print "Context wasn't matched for: $context<br>\n";
  }
  
  #return the edited source code
  return $new_html;
} # insertAnnotation()

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

#=head1 Name

#Insert

#=over 4

#=item main

#This subroutine gets the gets the URL, name, email and group info
#from the form geturl.html, calls unescape
#from the URI package, gets the HTML and calls extractInfo.

#=item extractInfo

#This subroutine takes the url and html page.  It checks if the page already
#has annotations by looking in index.txt.  If it does, it goes takes the 
#info from each annotation file in the appropriate directory.

#=item insertAnnotation

#This subroutine takes the html, author, email, date, title, annotated_text,
#annotation, context and file from extractInfo.  It searches for the 
#annotated text and inserts the annotation markers around it, 
#along with the javascript to open a new window displaying the annotation.

#=back

#=head 1 History

#=over 4

#=item [09 June 99]

#Began coding.

#=item [11 June 99]

#Edited by Rachel Heck.

#=item [14 June 99]

#Now works correctly.

#=item [29 June 99]

# Added call to textToSearch to slashify special characters.

#=item [6 July 99]

# Cleaned up a little and added comments (e.g., commented closing braces).

#=item [7 July 99]

# Look for context when matching annotation (it was matching
# the annotated_text before).

#=item [12 July 1999]

# Edited by Rachel Heck....program now gets and passes the groups that the user 
# belongs to

#=item [13 July 1999]

# Checks that user has permissions to read the file before
# inserting annotation flags around the annotated text.

#=item [14 July 1999]

# Fixed errors: If the annotated text is a link, insert the flags
#  outside of the link.

#=item [15 July 1999]

# Now receives the URL, html, name, email, and groups as
# parameters (from Plugin.pm) instead of a form.

#=item [16 July 1999]

# Works with Ravel.

#=item [20 July 1999]

#Editted by Rachel Heck to check whether annotations are new or
# added previous to the last visit to the page.

#=item [23 July 1999]

#When an annotation or search window opens, it will pop to the front.

=item [4 August 1999]

All cgi calls are now Proxy URLs.  The name, email, and groups information are 
no longer being passed to cgi scripts.

#=back

#=cut

