#!/usr/bin/perl 

use lib ("../");
use strict 'vars';
use Slash;

###############################################################################
# search.pl - this code is the search page 
#
# Copyright (C) 1997 Rob "CmdrTaco" Malda
# malda@slashdot.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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
#
#  $Id: search.pl,v 1.2 2000/01/28 14:49:25 CaptTofu Exp $
###############################################################################

#################################################################
sub main
{
        getSlash();

	# Set some defaults
	$$F{query}||="";
	$$F{section}||="";
	$$F{op}||="";
	$$F{min}||="0";
	$$F{max}||="30";
	$$F{last}||=$$F{min}+$$F{max}; 

	$$F{query} = stripByMode($$F{query}, 'nohtml');

#	header("Pesquisa $sitename: $query",$$F{section});
	header("Pesquisa $sitename ",$$F{section});
	titlebar("99%","Pesquisando $$F{query}");


	searchForm();

	if   ($$F{op} eq "comments") { commentSearch() }
	elsif($$F{op} eq "users")    { userSearch()    }
 	else			     { storySearch()   }
	writelog("search",$$F{query});
	footer();	
}

#################################################################
sub linkSearch
{
	my $C = shift;
	my $r;

	foreach ("threshold", "query", "min", "author", "op", "sid",
		 "topic", "section", "total") {
		my $x="";
		$x=$$C{$_} if defined $$C{$_};
		$x=$$F{$_} if defined $$F{$_} and !$x;
		$x=~s/ /+/g;
		$r.="$_=$x\&" if defined $x;
	}

	$r="<A href=$ENV{SCRIPT_NAME}?$r>$$C{link}</A>";
}

#################################################################
sub keysearch
{
	my $keywords=shift;
	my @columns=@_;

	$keywords=~s/[^A-Z0-9'\. ]//gi;
	my @words=split(/ /,$keywords);
	my $sql;

	my $x=0;
	foreach my $w (@words) {
		next if length $w < 3;
		last if $x++ > 3;
		foreach my $c (@columns) { 
			$sql.="+" if $sql;
			$sql.="($c LIKE ".$dbh->quote("%$w%").")";
		}
	}
	substr $sql, 1, length($sql)-1;
	$sql="0" unless $sql;
	$sql.=" as kw";	
	return $sql;
}

#################################################################
sub searchForm
{

	my $SECT=getSection($$F{section});

	my $t=lc($sitename);
	$t=$$F{topic} if $$F{topic};
	my $tref=Slash::getTopic($t);
	print "<IMG src=\"$imagedir/topics/$$tref{image}\"
			ALIGN=right BORDER=0 ALT=\"$$tref{alttext}\"
			HSPACE=30 VSPACE=10 WIDTH=$$tref{width} 
			HEIGHT=$$tref{height}>

	<FORM action=\"$ENV{SCRIPT_NAME}\" method=POST>
		<INPUT type=text name=query value=\"$$F{query}\">
		<INPUT type=submit value=\"Procurar\">\n";

	$$F{op}||="stories";

	my %ch;
	$ch{$$F{op}}="CHECKED" if $$F{op};
	print "<INPUT type=radio name=op value=stories $ch{stories}> Artigos
	      <INPUT type=radio name=op value=comments $ch{comments}> Comentários
	      <INPUT type=radio name=op value=users $ch{users}> Utilizadores<BR>";
	if($$F{op} eq "stories") {
		selectTopic("topic",$$F{topic});
		selectGeneric("authors","author","aid","name",$$F{author});
	} elsif($$F{op} eq "comments") {
		print "Visibilidade <INPUT type=text size=3 name=threshold 
			value=$$U{threshold}>";
		print "<INPUT type=hidden name=sid value=$$F{sid}>";
	}

	selectSection("section",$$F{section},$SECT) unless $$F{op} eq "users";
	print "<P></FORM>";
}

#################################################################
sub commentSearch
{
	print "<P>Esta pesquisa engloba o nome, email, assunto e conteúdos
		de cada um dos cerca de 30000 comentários submetidos. 
		Comentários mais antigos são removidos e de momento estão
		apenas visiveis sob a forma de HTML estático.<P>";
	
	$$F{min}=int($$F{min});
	my $prev=$$F{min}-20;
	print linkSearch({link=>"<B>$$F{mind} correspondências anteriores...</B>",
				  min=>$prev}), "<P>" if $prev >= 0;
	
	# select comment ID, comment Title, Author, Email, link to comment
        # and SID, article title, type and a link to the article
	my $sqlquery="SELECT section, newstories.sid, aid, title, 
			     pid, subject,".
			     Slash::getDateFormat("time","d").",".
			     Slash::getDateFormat("date","t").", 
			     uid, cid, ";

	$sqlquery.="	  ".keysearch($$F{query},"subject","comment") if $$F{query};
	$sqlquery.="	  1 as kw " unless $$F{query};
	$sqlquery.="    FROM newstories, comments
		       WHERE newstories.sid=comments.sid ";
	$sqlquery.="     AND newstories.sid=".$dbh->quote($$F{sid}) if $$F{sid};
	$sqlquery.="     AND points >= $$U{threshold} ";
	$sqlquery.="     AND section=".$dbh->quote($$F{section}) if $$F{section};
	$sqlquery.=" ORDER BY kw DESC, date DESC, time DESC LIMIT $$F{min},20 ";
	
	if($$F{sid}) {
		my ($t)=sqlSelect("title","newstories",
				  "sid=".$dbh->quote($$F{sid}) );
		$t ||= "discussion";
		print "<B>Voltar a ", 
	      		Slash::linkComment({ sid=>$$F{sid},
			pid=>0,
			subject=>$t });
		print "</B><P>";
		return unless $$F{query};
	}

	my $cursor=$dbh->prepare($sqlquery);
	$cursor->execute;
	
	my $x=$$F{min};
	MATCH:while(my ($section, $sid, $aid, $title, $pid, $subj, $sdate, $cdate, $uid, $cid, $match) = 
		$cursor->fetchrow) {
		last MATCH if ($$F{query} and !$match); 
$cdate=Slash::nunoHackData($cdate);
$sdate=Slash::nunoHackData($sdate);
		$x++;
		my ($cname,$cemail)=sqlSelect("nickname,fakeemail","users","uid=$uid");
		print "<BR><B>", $match?$match:$x, "</B>
		       <A href=comments.pl?sid=$sid\&pid=$pid\#$cid>$subj</A> 
		       por <A href=mailto:$cemail>$cname</A> em $cdate<BR>
		       <FONT size=2> relativo a
		       <A href=$section/$sid.shtml>$title</A> 
		       submetido em $sdate por $aid</FONT><BR>";
	}
	$cursor->finish();

	print "Não foram encontradas correspondências para a sua pesquisa" unless ($x > 0 or $$F{query});
	
	my $remaining="";
	print "<P>", linkSearch({ link=>"<B>$remaining Correspondências restantes</B>",
			   min=>$x } ) unless $x-$$F{min}<20;
}

#################################################################
sub userSearch
{
	my $prev=int($$F{min})-$$F{max};
	print linkSearch( { link=>"<B>$$F{min} correspondências anteriores...</B>",
			     min=>$prev } ), "<P>" if $prev >=0;
	
	my $c=sqlSelectMany("fakeemail,nickname,uid,".
			keysearch($$F{query},"nickname"),
			"users",
			"",
			"ORDER BY kw DESC LIMIT 10") if $$F{query};
	return unless $c;

	my $total=$c->{rows};
	my ($x,$cnt)=0;
	MATCH:while(my $U=$c->fetchrow_hashref() ) {
		last MATCH unless $$U{kw};
		my $ln=$$U{nickname};
		$ln=~s/ /+/g;
		print "<LI><A 
		   href=$rootdir/users.pl?nick=$ln>$$U{nickname}</A> \&nbsp;";
		print "<A href=mailto:$$U{fakeemail}>$$U{fakeemail}</A>" 
			if $$U{fakeemail};
		print " ($$U{uid}) ";
		$x++;
	}
	$c->finish();

	print "Não foram encontradas correspondências para a sua pesquisa" if $x<1;

	my $remaining=$total - $$F{last};
	print linkSearch( { link=>"<B>$remaining correspondências restantes</B>",
			     min=>$$F{last} } ) unless $x<$$F{max};
}

#################################################################
sub storySearch
{
	my $prev=$$F{min}-$$F{max};
	print linkSearch( { link=>"<B>$$F{min} correspondências anteriores...</B>",
			    min=>$prev } ), "<P>" if $prev >= 0;
	
	my $sqlquery="SELECT aid,title,sid,".
			Slash::getDateFormat("time","t").",
			commentcount,section ";
	$sqlquery.=",".keysearch($$F{query},"title","introtext")." " if $$F{query};
	$sqlquery.="	,0 " unless $$F{query};
	if($$F{query}) {
		$sqlquery.="  FROM stories ";
	} else {
		$sqlquery.="  FROM newstories ";
	}

	$sqlquery.=" WHERE ((displaystatus = 0 and \"$$F{section}\"=\"\")
		            OR (section=\"$$F{section}\" and displaystatus>=0))
		       AND time < now() ";
	$sqlquery.="   AND writestatus >= 0  ";
	$sqlquery.="   AND aid=\"$$F{author}\" " if $$F{author};
	$sqlquery.="   AND section=\"$$F{section}\" " if $$F{section};
	$sqlquery.="   AND tid=\"$$F{topic}\" " if $$F{topic};

	$sqlquery.=" ORDER BY ";
	$sqlquery.=" kw DESC, " if $$F{query};
	$sqlquery.=" time DESC LIMIT $$F{min},$$F{max} ";
	my $cursor=$dbh->prepare($sqlquery);
	$cursor->execute;
	my ($x,$cnt)=0;
	# print $sqlquery if $$U{uid}==1;
	print " ";

	MATCH:while(my ($aid, $title, $sid,$time,$commentcount,$section,$cnt) = 
		$cursor->fetchrow) {
		last MATCH if ($cnt==0 and $$F{query});
		print $cnt?$cnt:$x+$$F{min};
		print " ";
$time=Slash::nunoHackData($time);
		print linkStory( { section=>$section,
			   sid=>$sid, link=>"<B>$title</B>" }), " por $aid 
			<FONT size=2>em $time <b>$commentcount</b></FONT><BR>";
		$x++;
	}
	$cursor->finish();

	print "Não foram encontradas correspondências para a sua pesquisa" if $x < 1;

	my $remaining="";
	print "<P>", linkSearch( { link=>"<B>$remaining correspondências restantes</B>",
				    min=>$$F{last} } ) unless $x < $$F{max};
}

main;
$dbh->disconnect() if $dbh;
1;
