###############################################################################
# UB_DoSearch.src                                                             #
###############################################################################
# UltraBoard 2000 by UltraScripts.com, Inc.                                   #
# Scripts written by Jacky Wing Wa Yung, WebMaster@UltraScripts.com           #
# Available from http://www.UltraBoard.org/                                   #
# =========================================================================== #
# COPYRIGHT NOTICE :                                                          #
#                                                                             #
# Copyright (c) 1999-2000 UltraScripts.com, Inc. All Rights Reserved.         #
#                                                                             #
# This program is being distributed as shareware. It may be used and modified #
# free for personal, government or non-profit. Any commercial use must be     #
# registered. However, modified versions cannot be sold or distributed. You   #
# cannot alter the copyright and "powered by" notices throughout the scripts. #
# These notices must be clearly visible to the end users.                     #
#                                                                             #
# WARRANTY DISCLAIMER:                                                        #
#                                                                             #
# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT #
# ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR       #
# FITNESS FOR A PARTICULAR PURPOSE.                                           #
###############################################################################

package Source;

use strict;

sub DoSearch {
  my $tmpResult = $UB::QUERY{'tmp'};
  my $IsNewSearch = 1;

  my $time = time;

  my (@FORM_BOARDS, @FORM_KEYWORDS, $FORM_BOOLEAN, $FORM_METHOD, $FORM_DATE_BOOLEAN, $FORM_DATE_DAYS, $FORM_SORT_ORDER, $FORM_SORT_FIELD, $FORM_VIEW);
  my $FOUND = 0;
  my %TRACK;
  my @Results;

  &Standard::lock("search.lock");

  if ((defined $tmpResult) && (-e $SYSTEM::TEMP_PATH."/S".$tmpResult.".tmp")) {
    my $Commands;
    &Standard::FileOpen(*TEMP, "r", $SYSTEM::TEMP_PATH."/S".$tmpResult.".tmp");
      ($Commands, $FOUND) = <TEMP>;
    close (TEMP);
    chomp ($Commands, $FOUND);

    my @Commands = split (/;/, $Commands);
    pop (@Commands);

    my %Command;
    foreach (@Commands) {
      my ($KEY, $VALUE) = (/^(\w+)\s=\s(.*)$/);
      $Command{$KEY} = $VALUE;
    }

    @FORM_BOARDS        = split (/ /, $Command{'FORM_BOARDS'});
    for (my $i = 0; $i <= $#FORM_BOARDS; $i++) {
      splice (@FORM_BOARDS, $i, 1) if ($FORM_BOARDS[$i] eq "");
    }

    @FORM_KEYWORDS      = split (/ /, $Command{'FORM_KEYWORDS'});
    $FORM_BOOLEAN       = $Command{'FORM_BOOLEAN'};
    $FORM_METHOD        = $Command{'FORM_METHOD'};
    $FORM_DATE_BOOLEAN  = $Command{'FORM_DATE_BOOLEAN'};
    $FORM_DATE_DAYS     = $Command{'FORM_DATE_DAYS'};
    $FORM_SORT_ORDER    = $Command{'FORM_SORT_ORDER'};
    $FORM_SORT_FIELD    = $Command{'FORM_SORT_FIELD'};
    $FORM_VIEW          = $Command{'FORM_VIEW'};

    goto RESULT_PAGE if (scalar (@FORM_BOARDS) < 1);

    $IsNewSearch = 0;

  } else {
    NEW_SEARCH:
    @FORM_BOARDS        = $UB::CGI->param('FORM_BOARDS');
    for (my $i = 0; $i <= $#FORM_BOARDS; $i++) {
      splice (@FORM_BOARDS, $i, 1) if ($FORM_BOARDS[$i] eq "");
    }

    @FORM_KEYWORDS      = split (/\s+/, $UB::QUERY{'FORM_KEYWORDS'});
    $FORM_BOOLEAN       = $UB::QUERY{'FORM_BOOLEAN'};
    $FORM_METHOD        = $UB::QUERY{'FORM_METHOD'};
    $FORM_DATE_BOOLEAN  = $UB::QUERY{'FORM_DATE_BOOLEAN'};
    $FORM_DATE_DAYS     = $UB::QUERY{'FORM_DATE_DAYS'};
    $FORM_SORT_ORDER    = $UB::QUERY{'FORM_SORT_ORDER'};
    $FORM_SORT_FIELD    = $UB::QUERY{'FORM_SORT_FIELD'};
    $FORM_VIEW          = $UB::QUERY{'FORM_VIEW'};

    if (scalar (@FORM_BOARDS) < 1) {
      &HTML::Error (CODE => "SEARCH_MISSING_BOARD");
    }

    @FORM_KEYWORDS = &Standard::trim(@FORM_KEYWORDS);

    $tmpResult = $time;
  }

  my $BOARD = shift @FORM_BOARDS;

  my $POST_SECOND;
  if (($FORM_DATE_DAYS ne "*") && ($FORM_DATE_DAYS ne "NA")) {
    if ($FORM_DATE_BOOLEAN eq "GT") {
      $POST_SECOND = "<";
    } else {
      $POST_SECOND = ">";
    }
    $POST_SECOND .= $time - ($FORM_DATE_DAYS * 60 * 60 * 24);
  } else {
    if ($FORM_DATE_DAYS eq "*") {
      $POST_SECOND = "*";
    } else {
      $POST_SECOND = "";
    }
  }

  my ($FirstStep, $FirstStepIndex) = &DB::Query (
    TABLE   => "B".$BOARD,
    COLUMNS => ["ID", "ROOT", "SUBJECT", "USERNAME", "NICKNAME", "NUMBER_REPLIES", "APROVED", "SYMBOL", "READ_ONLY", "ATTACHMENT", "POST_SECOND", "POST_DATE", "POST_TIME", "LAST_POST_SECOND", "LAST_POST_DATE", "LAST_POST_TIME"],
    WHERE   => {
      POST_SECOND => [$POST_SECOND],
      APROVED     => [1]
    },
    MATCH   => "ALL",
    SORT    => $FORM_SORT_FIELD || "",
    BY      => $FORM_SORT_ORDER || "",
  );

  my $KEYWORDS = scalar (@FORM_KEYWORDS);
  my $MATCH    = "";

  RESULT: foreach my $Result (@$FirstStep) {
    $MATCH = "";

    if ($FORM_VIEW eq "TopicOnly") {
      if ($Result->{'ROOT'} != 0) {
        if (exists $TRACK{ $Result->{'ROOT'} }) {
          next RESULT;
        }
      } else {
        if (exists $TRACK{ $Result->{'ID'} } ) {
          next RESULT;
        }
      }
    }

    if ($KEYWORDS == 0) {
      $MATCH = $Result->{'ID'};
      goto FOUND;
    }

    KEYWORD: foreach my $Keyword ( @FORM_KEYWORDS ) {
      if (($FORM_METHOD =~ /S/) && ($Result->{'SUBJECT'} =~ /$Keyword/i)) {
        $MATCH = $Result->{'ID'};
        goto FOUND if $FORM_BOOLEAN ne "ALL";
      } elsif ( ($FORM_METHOD =~ /U/) && ( ($Result->{'NICKNAME'} =~ /$Keyword/i) || ($Result->{'USERNAME'} =~ /$Keyword/i) ) ) {
        $MATCH = $Result->{'ID'};
        goto FOUND if $FORM_BOOLEAN ne "ALL";
      } elsif ($FORM_METHOD =~ /B/) {
        &Standard::FileOpen(*BODY, "r", $SYSTEM::DB_PATH."/B".$BOARD."/".$Result->{'ID'}.".src");
          my $Body = join ("", <BODY>);
        close (BODY);

        if ($Body =~ /$Keyword/i) {
          $MATCH = $Result->{'ID'};
          goto FOUND if $FORM_BOOLEAN ne "ALL";
        }
      } else {
        if ($FORM_BOOLEAN eq "ALL") {
          next RESULT;
        } else {
          next KEYWORD;
        }
      }
    }

    FOUND:
    if ($MATCH ne "") {
      if ($FORM_VIEW eq "TopicOnly") {
        if ($Result->{'ROOT'} != 0) {
          if (exists $TRACK{ $Result->{'ROOT'} }) {
            next RESULT;
          } else {
            push (@Results, $FirstStep->[$FirstStepIndex->{ $Result->{'ROOT'} }] );
            $TRACK{ $Result->{'ROOT'} } = 1;
            $FOUND++;
          }
        } else {
          if (exists $TRACK{ $MATCH }) {
            next RESULT;
          } else {
            push (@Results, $Result);
            $TRACK{ $MATCH } = 1;
            $FOUND++;
          }
        }
      } else {
        push (@Results, $Result);
        $FOUND++;
      }
    }
  }

  &SaveStatus (
    $tmpResult,
    {
      FORM_BOARDS       => \@FORM_BOARDS      ,
      FORM_KEYWORDS     => \@FORM_KEYWORDS    ,
      FORM_BOOLEAN      => $FORM_BOOLEAN      ,
      FORM_METHOD       => $FORM_METHOD       ,
      FORM_DATE_BOOLEAN => $FORM_DATE_BOOLEAN ,
      FORM_DATE_DAYS    => $FORM_DATE_DAYS    ,
      FORM_SORT_ORDER   => $FORM_SORT_ORDER   ,
      FORM_SORT_FIELD   => $FORM_SORT_FIELD   ,
      FORM_VIEW         => $FORM_VIEW
    },
    $BOARD,
    $FOUND,
    \@Results
  );

  if (scalar (@FORM_BOARDS) > 0) {
    my ($Categories, $CategoriesIndex) = &DB::Query (
      TABLE   => "Categories"   ,
      COLUMNS => ["ID", "TITLE"]
    );

    my ($Boards, $BoardsIndex) = &DB::Query (
      TABLE   => "Boards"       ,
      COLUMNS => ["ID", "TITLE", "CATEGORY"]
    );

    &Standard::Require("UB_Searching.src", "$UB::INTERFACES_PATH/$SYSTEM::DEFAULT_THEME/UB_Searching.src");

    my $SearchingBoard = $Boards->[ $BoardsIndex->{ $FORM_BOARDS[0] } ];
    my $SearchedBoard  = $Boards->[ $BoardsIndex->{ $BOARD } ];

    my %SEARCHING = (
      "SEARCHING.BOARD" => $Categories->[ $CategoriesIndex->{ $SearchingBoard->{'CATEGORY'} } ]{'TITLE'}."/".$SearchingBoard->{'TITLE'},
      "SEARCHED.BOARD"  => $Categories->[ $CategoriesIndex->{ $SearchedBoard ->{'CATEGORY'} } ]{'TITLE'}."/".$SearchedBoard ->{'TITLE'},

      "SEARCHING.FOUND"       => scalar (@Results),
      "SEARCHING.TOTAL_FOUND" => $FOUND           ,

      "SEARCHING.FORWARD" => $SYSTEM::UB_URL."/UltraBoard.".$SYSTEM::EXT."?action=Result&tmp=$tmpResult&SID=".$UB::MEMBER{'SESSION'},
      "SEARCHING.RELOAD"  => $SYSTEM::UB_URL."/UltraBoard.".$SYSTEM::EXT."?action=DoSearch&tmp=$tmpResult&SID=".$UB::MEMBER{'SESSION'},

      &Standard::ExtraVariables()
    );

    &Standard::PrintHTMLHeader();
    print &Searching::Parse(\%SEARCHING);
  } else {
    RESULT_PAGE:
    print "Location: ".$SYSTEM::UB_URL."/UltraBoard.".$SYSTEM::EXT."?action=Result&tmp=$tmpResult&SID=".$UB::MEMBER{'SESSION'}."\n\n";
  }

  &Standard::unLock("search.lock");
}

sub SaveStatus {
  my ($tmpResult, $Variables, $Board, $Found, $Results) = @_;
  my @lines = ();

  if (($tmpResult) && (-e $SYSTEM::TEMP_PATH."/S".$tmpResult.".tmp")) {
    &Standard::FileOpen(*TEMP, "r", $SYSTEM::TEMP_PATH."/S".$tmpResult.".tmp");
      (@lines) = <TEMP>;
    close (TEMP);
    chomp (@lines);
  }

  $lines[0]  = "FORM_BOARDS = ".join (" ", @{ $Variables->{'FORM_BOARDS'} }).";";
  $lines[0] .= "FORM_KEYWORDS = ".join (" ", @{ $Variables->{'FORM_KEYWORDS'} }).";";
  $lines[0] .= "FORM_BOOLEAN = $Variables->{'FORM_BOOLEAN'};";
  $lines[0] .= "FORM_METHOD = $Variables->{'FORM_METHOD'};";
  $lines[0] .= "FORM_DATE_BOOLEAN = $Variables->{'FORM_DATE_BOOLEAN'};";
  $lines[0] .= "FROM_DATE_DAYS = $Variables->{'FORM_DATE_DAYS'};";
  $lines[0] .= "FORM_SORT_ORDER = $Variables->{'FORM_SORT_ORDER'};";
  $lines[0] .= "FORM_SORT_FIELD = $Variables->{'FORM_SORT_FIELD'};";
  $lines[0] .= "FORM_VIEW = $Variables->{'FORM_VIEW'};";

  $lines[1] = $Found;

  for (my $i = 0; $i <= $#{ $Results }; $i++) {
    my $Result = $Results->[$i];
    my $line  = $Board                        ."\0";
       $line .= $Result->{'ID'}               ."\0";
       $line .= $Result->{'ROOT'}             ."\0";
       $line .= $Result->{'SUBJECT'}          ."\0";
       $line .= $Result->{'USERNAME'}         ."\0";
       $line .= $Result->{'NICKNAME'}         ."\0";
       $line .= $Result->{'NUMBER_REPLIES'}   ."\0";
       $line .= $Result->{'SYMBOL'}           ."\0";
       $line .= $Result->{'READ_ONLY'}        ."\0";
       $line .= $Result->{'ATTACHMENT'}       ."\0";
       $line .= $Result->{'POST_DATE'}        ."\0";
       $line .= $Result->{'POST_TIME'}        ."\0";
       $line .= $Result->{'LAST_POST_SECOND'} ."\0";
       $line .= $Result->{'LAST_POST_DATE'}   ."\0";
       $line .= $Result->{'LAST_POST_TIME'}       ;
    push (@lines, ">".$line);
  }

  &Standard::FileOpen(*TEMP, "w", $SYSTEM::TEMP_PATH."/S".$tmpResult.".tmp");
    print TEMP join ("\n", @lines);
  close (TEMP);

  return 1;
}

###############################################################################
1; # end of UB_DoSearch.src file
###############################################################################