#!/usr/bin/perl
#
# TWiki WikiClone (see wiki.pm for $wikiversion and other info)
#
# Copyright (C) 2001-2002 Esteban Manchado Velzquez, zoso@foton.es
# Copyright (C) 2003 Joachim Nilsson <joachim.nilsson@vmlinux.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# 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.  See the
# GNU General Public License for more details, published at
# http://www.gnu.org/copyleft/gpl.html
#
# The GNUsearch script is based on PhotonSearch by Esteban Manchado
# Velzquez. It is only midly modified to fit in with the GNUskin
# plugin. Name change only made so the script does not collide with
# an existing installation - i.e., to preserve a sane name space.
#
# GNUsearch is called from a generic "search" box. It is able to
# perform different functions based on the "action" parameter.
# The operand text is available in the "topic" parameter.
#

use CGI::Carp qw(fatalsToBrowser);
use CGI;
use lib ( '.' );
use lib ( '../lib' );
use TWiki;

use strict;

use vars qw($debug);

$debug = "1";

&main();

sub main
{
    my $query = new CGI;

    my $thePathInfo = $query->path_info();
    my $theRemoteUser = $query->remote_user();
    my $theTopic = $query->param( 'topic' );
    my $theUrl = $query->url;
    my $theTemplate;
    my $newurl;

    if( $query->param( 'type' ) eq 'popup' ) {
        $theTemplate = 'searchpopup';
    } elsif( $query->param( 'type' ) eq 'sidebar' ) {
        $theTemplate = 'searchsidebar';
    } else {
        $theTemplate = 'search';
    }

    my( $topic, $webName ) =
	&TWiki::initialize( $thePathInfo, $theRemoteUser, $theTopic, $theUrl, $query );

    if( ! &TWiki::Store::webExists( $webName ) ) {
        my $url = &TWiki::getOopsUrl( $webName, $topic, "oopsnoweb" );
        TWiki::redirect( $query, $url );
        return;
    }
    # string to search
    my $search        = $query->param( "search" ) || "";

    # Redirect according to the look of the string
    if( $search =~ /^[A-Z]/ ) {          # Normal Go behaviour
        if( $search =~ /(.*)\.(.*)/ ) {  # Special web.topic notation
            $webName = $1;
            $search  = $2;
        }
	$newurl = "$TWiki::urlHost$TWiki::scriptUrlPath/view$TWiki::scriptSuffix/$webName/$search";
	TWiki::redirect( $query, $newurl );
    } elsif( $search =~ /^[\/?]/ ) {        # Normal search
	$search =~ s/^.//;
	$search =~ s/ /+/;
	$newurl = "$TWiki::urlHost$TWiki::scriptUrlPath/search$TWiki::scriptSuffix/$webName/?web=all&order=topic&search=$search&limit=all";
	TWiki::redirect( $query, $newurl );
    } else {                             # Topic name search
	my @dots = ();
	opendir DIR, $TWiki::dataDir;
	my @tmpList = readdir(DIR);
	closedir(DIR);
	my @webList = sort
		      grep { s#^.+/([^/]+)$#$1# }
		      grep { -d }
		      map  { "$TWiki::dataDir/$_" }
		      grep { ! /^[._]/ } @tmpList;

	my $totalresults = 0;
	my $lastResultWebName = "";
	my $lastResultNode = "";

	my $results = {};

	# Collect the results
	foreach my $thisWebName ( @webList ) {
	    my $twikidir = $TWiki::dataDir . '/' . $thisWebName;

	    opendir( DIR, $twikidir ) || die "can't opendir $twikidir: $!";
	    # Boys, don't try this at home!
	    @dots = map { s/\.txt$//; $_ }
		    grep { /\.txt$/ && -f "$twikidir/$_" }
		    readdir( DIR );
	    closedir DIR;

	    my @saco = @dots;
            if( $search eq '' ) {
                @saco = ();
            } else {
                foreach my $arg ( split ' ', $search ) {
                    @saco = grep( /$arg/i, @saco ); # AND
                }
            }

	    if( scalar @saco ) {
		$totalresults += scalar @saco;
		# Just in case there is only one result, to redirect
		$lastResultWebName = $thisWebName;
		$lastResultNode = $saco[0];

		$results->{$thisWebName} = [ @saco ] ;
	    }
	}

	# If there is only one result, redirect to that node
	if( $totalresults == 1 ) {
	    TWiki::redirect( $query, "$TWiki::urlHost$TWiki::scriptUrlPath/view$TWiki::scriptSuffix/$lastResultWebName/$lastResultNode" );
	    return;
	}

	# Else, print them
	&TWiki::writeHeader( $query );
	my $tmpl = &TWiki::Store::readTemplate( $theTemplate );
	my( $tmplHead, $tmplSearch,
	    $tmplTable, $tmplNumber, $tmplTail ) =
		    split( /%SPLIT%/, $tmpl );
	$tmplHead   = &TWiki::handleCommonTags( $tmplHead, $TWiki::mainWebName );
	$tmplSearch = &TWiki::handleCommonTags( $tmplSearch, $TWiki::mainWebName );
	$tmplNumber = &TWiki::handleCommonTags( $tmplNumber, $TWiki::mainWebName );
	$tmplTail   = &TWiki::handleCommonTags( $tmplTail, $TWiki::mainWebName );
	$tmplHead = &TWiki::getRenderedVersion( $tmplHead );
	$tmplHead =~ s|</*nop/*>||goi;
        $tmplHead =~ s/%SEARCHSTRING%/$search/;
	print $tmplHead;

	printResults( $tmplTable, $results );

	# print last part of full HTML page
	$tmplTail = &TWiki::getRenderedVersion( $tmplTail );
	$tmplTail =~ s|</*nop/*>||goi;   # remove <nop> tag
	print $tmplTail;
    }
}



sub printResults
{
    my( $theTemplate, $theResultsHash ) = @_;

    foreach my $web ( sort keys %{ $theResultsHash } ) {
        my( $beforeText, $repeatText, $afterText ) =
                    split( /%REPEAT%/, $theTemplate );

        my $thisWebBGColor     =
                &TWiki::Prefs::getPreferencesValue( "WEBBGCOLOR",
                                                    $web ) ||
                "\#FF00FF";
        $beforeText =~ s/%WEBBGCOLOR%/$thisWebBGColor/o;
        $beforeText =~ s/%WEB%/$web/o;
        $beforeText = &TWiki::handleCommonTags( $beforeText, $web );
        $afterText  = &TWiki::handleCommonTags( $afterText, $web );
        $beforeText = &TWiki::getRenderedVersion( $beforeText, $web );
        $beforeText =~ s|</*nop/*>||goi;   # remove <nop> tag
        print $beforeText;

        foreach my $topic ( @{ $theResultsHash->{$web} } ) {
            my $locked = "";
            my ( $meta, $text ) = &TWiki::Store::readTopic( $web, $topic );
            my ( $revDate, $revUser, $revNum ) = &TWiki::Store::getRevisionInfoFromMeta( $web, $topic, $meta, 1 );
            my $tempVal = &TWiki::Store::topicIsLockedBy( $web, $topic );
            if( $tempVal ) {
                $revUser = $tempVal;
                $locked = "(LOCKED)";
            }
            $revUser = &TWiki::userToWikiName( $revUser );

            my $tempVal = $repeatText;
            $tempVal =~ s/%WEB%/$web/go;
            $tempVal =~ s/%TOPICNAME%/$topic/go;
            $tempVal =~ s/%LOCKED%/$locked/o;
            $tempVal =~ s/%TIME%/$revDate/o;
            if( $revNum > 1 ) {
                $revNum = "r1.$revNum";
            } else {
                $revNum = "<b>NEW</b>";
            }
            $tempVal =~ s/%REVISION%/$revNum/o;
            $tempVal =~ s/%AUTHOR%/$revUser/o;
            $tempVal = &TWiki::handleCommonTags( $tempVal, $topic );
            $tempVal = &TWiki::getRenderedVersion( $tempVal );

            # regular search view
            my $head = &TWiki::Store::readFileHead( "$TWiki::dataDir\/$web\/$topic.txt", 16 );
            $head = &TWiki::makeTopicSummary( $head, $topic, $web );
            $tempVal =~ s/%TEXTHEAD%/$head/go;

            $tempVal = &TWiki::getRenderedVersion( $tempVal, $web );
            $tempVal =~ s|</*nop/*>||goi;   # remove <nop> tag
            print $tempVal;
        }

        $afterText = &TWiki::getRenderedVersion( $afterText, $web );
        $afterText =~ s|</*nop/*>||goi;   # remove <nop> tag
        print $afterText;
    }
}
