#!/usr/bin/perl
# ----------------------------------------------------------------------------
# This software is Copyright (C) 2006, All Rights Reserved
# ----------------------------------------------------------------------------
# This program is protected by local and international copyright laws. Any
# use of this program is subject to the the terms of the license agreement
# included as part of this distribution archive. Any other uses are strictly
# prohibited without the written permission of the Vendor and all
# other rights are reserved.
# -----------------------------------------------------------------------------
# Warning : Modifying this program violates your license agreement!
# -----------------------------------------------------------------------------

  use strict;

  ### Get Script Directory
  use vars qw($CGIDIR);
  BEGIN {
    foreach my $scriptFilepath ($0, $ENV{'SCRIPT_FILENAME'}) {
      if ($scriptFilepath =~ m/^\./) { next; }              # skip relative paths (eg: ./admin.cgi)
      unless ($scriptFilepath =~ m|^(.+)[\\\/]|) { next; }  # match path but not filename
      $CGIDIR = $1;
      $CGIDIR =~ s|\\|/|g;
      last;
    }
  };

  ### Load Modules
  use Time::Local;
  use lib ("$CGIDIR/modules/");

  use IT::AutoLoader;
  use IT::Globals;

  ### Define Globals
  $PROGRAM_VERSION = '2.14';
  $PROGRAM_BUILD   = '11';
  $PROGRAM_KEY     = 35797;
  $PROGRAM_ID      = 15;

  ### Run Program
  eval { &main(); };
  if ($@) {   # display program errors
    print "Content-type: text/html\n\n" unless $IT::COMMON::CONTENT_HEADERS_SENT;
    print "<p><b>Alert:</b> $IT::App::ALERT_MESSAGES</p>\n" if $IT::App::ALERT_MESSAGES;
    print "<p><xmp>Error: $@</xmp></p>\n"; # eval error
    print "<p><b>Debug:</b> $IT::App::DEBUG_MESSAGES</p>\n" if $IT::App::DEBUG_MESSAGES;
  }
  exit;

# ----------------------------------------------------------------------------
# Function    : main
# Description : main program
# ----------------------------------------------------------------------------

sub main {

  # initialize program
  &IT::App::Init::loadCustomPatches('customPatches.pl');
  &IT::ArtMan::Init::appInit();
  &IT::App::Init::appInit();

  # display error if not installed
  unless ($SETTINGS->{'isInstalled'}) {
    print &IT::Common::contentType('text/html');
    print qq|You must <a href="admin.cgi">install the program</a> before you can use the search engine.|;
    exit;
  }

  # get output
  my $htmlWithSSIs;
  if ($FORM->{'action'} eq 'search') { $htmlWithSSIs = &getSearchResults(); }
  else                               { $htmlWithSSIs = &getSearchForm(); }
  my $html = &IT::SSIResolver::resolveSSIs($htmlWithSSIs);

  # display output
  print &IT::Common::contentType('text/html');
  print &IT::App::alert();
  print $html;
  exit;
}

# ------------------------------------------------------------------------------
# Function    : getSearchForm
# Description :
# Usage       : &getSearchForm();
# ------------------------------------------------------------------------------

sub getSearchForm {
  my $template = "searchEngine/searchForm.html";

  # get placeholders
  my $category     = {};
  my $article      = {};
  my $placeholders = &IT::ArtMan::CustomMenus::Publish::createPlaceholders($category, $article, $template);
  foreach (qw(startMon startDay startYear endMon endDay endYear includeSubcats)) { $placeholders->{"$_"} = ''; }

  $placeholders->{'category.optionListForSearchEngineAsBreadcrumbs'} = &IT::ArtMan::CustomMenus::Category::createCategoryOptionListForSearchEngineAs('breadcrumbs');
  $placeholders->{'category.optionListForSearchEngineAsBranches'}    = &IT::ArtMan::CustomMenus::Category::createCategoryOptionListForSearchEngineAs('branches');

  # generate output
  my $htmlWithSSIs = &template($template, $placeholders);
  return $htmlWithSSIs;
}

# ------------------------------------------------------------------------------
# Function    : getSearchResults
# Description :
# Usage       : &getSearchResults();
# ------------------------------------------------------------------------------

sub getSearchResults {
  my $articleTable = $TABLE_PREFIX . "article";
  my @whereQuery;

  # add keyword query
  my $keywordFilterQuery = &_createKeywordFilterQuery();
  push(@whereQuery, $keywordFilterQuery) if $keywordFilterQuery;

  # get category nums
  my @categoryNums;
  if ($FORM->{'categoryNum'})  { @categoryNums = @{$FORM_ARRAYS->{'categoryNum'}}; }
  if ($FORM->{'categoryNums'}) { @categoryNums = split(/\s*,\s*/, $FORM->{'categoryNums'}); }

  # define placeholder
  &IT::Template::setGlobalPlaceholder('categoryNums', join(',', @categoryNums));

  # search all cats by default
  if (!@categoryNums) { # default to all categories (except disabled or nonsearchable)
    my $categoryArray = &IT::ArtMan::CustomMenus::Category::getSortedFilteredCategoryArray({
                          showUnlinkedCategories      => 1,
                          showDisabledCategories      => 0,
                          limitToSearchableCategories => 1,
                        });
    @categoryNums = map { $_->{'num'} } @$categoryArray;
  }

  # add date range query
  my $startDate  = eval { timegm($FORM->{'startSec'}, $FORM->{'startMin'}, $FORM->{'startHour'}, $FORM->{'startDay'}, $FORM->{'startMon'}-1, $FORM->{'startYear'}-1900); };
  my $endDate    = eval { timegm($FORM->{'endSec'}, $FORM->{'endMin'}, $FORM->{'endHour'}, $FORM->{'endDay'}, $FORM->{'endMon'}-1, $FORM->{'endYear'}-1900); };
  push @whereQuery, "article.date >= '$startDate'" if ($startDate);
  push @whereQuery, "article.date < '$endDate'"    if ($endDate);

  # create results limit
  my $thisPageNumber = $FORM->{'page'} || 1;
  my $startNum       = &IT::Common::mathMax(($thisPageNumber-1) * $FORM->{'perpage'}, 0);
  my $perpage        = int($FORM->{'perpage'} || 10);
  my $limitArray     = [$startNum, $perpage];

  # define sorting fields
  my @sortFields   = split(/\s*,\s*/, $FORM->{'sortBy'});
  my $sortByArray  = @sortFields ? \@sortFields : undef;

  # set template
  my $template = $FORM->{'template'} || "searchEngine/searchResults.html";
  unless (&IT::Template::isValidTemplate($template)) { die "The specified template is not in valid templates list!\n"; };

  # get articleList html
  my $whereQuery           = join ' AND ', @whereQuery;
  my $html                 = &IT::ArtMan::CustomMenus::Publish::ArticleLists::getHtmlForList({
                               'template'             => $template,
                               'categoryNums'         => \@categoryNums,
                               'includeChildArticles' => $FORM->{'includeSubcats'},
                               'sortBy'               => $sortByArray,
                               'limit'                => $limitArray,
                               'where'                => $whereQuery,
                               'pageNumber'           => $thisPageNumber,
                               'ruleNumber'           => undef,
                             });

  #
  return $html;
}

# ------------------------------------------------------------------------------
# Function    : _createKeywordFilterQuery
# Description :
# Usage       : my $keywordFilterQuery = &_createKeywordFilterQuery();
# ------------------------------------------------------------------------------

sub _createKeywordFilterQuery {
  my $articleTable = $TABLE_PREFIX . "article";

  # return if no keyword
  if ($FORM->{'keyword'} eq '') { return; }

  # escape keyword
  my $escapedKeyword = &IT::DB::getEscapedValue( $FORM->{'keyword'} );
  $escapedKeyword    = &IT::DB::escapeWildcardChars( $escapedKeyword );

  # get keyword search fields
  my $searchFields = [];
  if ($FORM->{'keywordSearchFields'}) { @$searchFields = split(/\s*,\s*/, $FORM->{'keywordSearchFields'}); }
  else                                { $searchFields  = &IT::DB::Schema::getTableAttributes($articleTable, 'appDefaultSearchFields'); }

  # create keyword query
  my $keywordQuery;
  foreach my $fieldname (@$searchFields) {
    unless (&IT::DB::Schema::existsField($articleTable, $fieldname)) { die "Unknown fieldname '$fieldname'!\n"; }

    my($fieldType)       = &IT::DB::Schema::getFieldAttributes($articleTable, $fieldname, 'type');
    my $operator         = ($fieldType eq 'int') ? '=' : 'CONTAINS ALL';

    $keywordQuery .= " OR " if $keywordQuery;
    $keywordQuery .= "article.$fieldname $operator '$escapedKeyword'";
  }

  # bracket and return query
  $keywordQuery = "($keywordQuery)";
  return $keywordQuery;

}

# ----------------------------------------------------------------------------
# Function    : defineGlobalPlaceholders
# Description :
# Usage       : &defineGlobalPlaceholders()
# ----------------------------------------------------------------------------

sub defineGlobalPlaceholders {

  # Define default global placeholders
  &IT::App::defineGlobalTemplatePlaceholders();

  # Define application specific global placeholders
  &IT::Template::setGlobalPlaceholder('keyword',                    $FORM->{'keyword'});  # deprecated
  &IT::Template::setGlobalPlaceholder('search.keyword',             $FORM->{'keyword'});
  &IT::Template::setGlobalPlaceholder('keywordSearchFields',        $FORM->{'keywordSearchFields'});   # deprecated
  &IT::Template::setGlobalPlaceholder('search.keywordSearchFields', $FORM->{'keywordSearchFields'});

}

# ----------------------------------------------------------------------------
# end of file
1;

