#!/usr/bin/perl
#
# DW::Controller::Search::Directory
#
# Directory search, based on code from LiveJournal.
#
# Authors:
#      Jen Griffin <kareila@livejournal.com>
#
# Copyright (c) 2011 by Dreamwidth Studios, LLC.
#
# This program is free software; you may redistribute it and/or modify it under
# the same terms as Perl itself. For a copy of the license, please reference
# 'perldoc perlartistic' or 'perldoc perlgpl'.
#

package DW::Controller::Search::Directory;

use strict;

use DW::Routing;
use DW::Template;
use DW::Controller;

use LJ::Directory::Search;    # also loads Results and Constraint
use LJ::Widget;

DW::Routing->register_string( '/directorysearch',  \&directory_handler, app => 1 );
DW::Routing->register_string( '/community/search', \&directory_handler, app => 1 );

sub directory_handler {
    my $r    = DW::Request->get;
    my $args = $r->get_args;

    my ( $ok, $rv ) = controller();
    return $rv unless $ok;

    my $remote = $rv->{remote};
    return error_ml('cprod.directory.text3.v1')
        unless $remote->can_use_directory;

    # check for the /community/search path (same form)
    if ( $r->uri =~ m:^/community/search: ) {
        $rv->{comm_page} = 1;
    }

    # see if we submitted the form (the directory.bml section)
    if ( $args->{opt_pagesize} || $args->{s_loc} ) {

        # if the search hasn't started, show the interstitial
        unless ( $args->{start_search} ) {

            # do a refresh to the page with the finished results.
            $rv->{refurl} = LJ::ehtml( LJ::page_change_getargs( start_search => 1 ) );
            $rv->{dots}   = LJ::img( 'searchdots', '' );
            return DW::Template->render_template( 'directory/searchdots.tt', $rv );
        }

        my $journaltype = $rv->{journaltype} = uc( $args->{journaltype} || '' );
        $rv->{searchurl} = $journaltype eq 'C' ? "community/search" : "directorysearch";

        $rv->{filter_linkbar} = sub {

            # create the links to filter by journal type
            my $filter_url = sub {
                my $jt  = $_[0] || '';
                my %get = ( start_search => 1, journaltype => $jt, page => '' );
                return LJ::ehtml( LJ::page_change_getargs(%get) );
            };
            my $linkify = sub {
                my ( $text, $filter ) = @_;
                return $text if $journaltype eq $filter;
                my $url = $filter_url->($filter);
                return "<a href='$url'>$text</a>";
            };

            my $strings = $_[0] or return '';
            my @links;

            push @links, $linkify->( $strings->{all},   '' );
            push @links, $linkify->( $strings->{comm},  'C' );
            push @links, $linkify->( $strings->{user},  'P' );
            push @links, $linkify->( $strings->{ident}, 'I' );

            return join "&nbsp;|&nbsp;", @links;
        };

        $rv->{ignore} = LJ::Hooks::run_hook( "interest_search_ignore", query => $args->{int_like} );
        unless ( $rv->{ignore} ) {

            # manipulate form arguments
            my %searchargs = (
                page      => delete $args->{page} || 1,
                page_size => $args->{opt_pagesize},
                format    => $args->{opt_format}
            );

            # country, state and city fields are generated by
            # LJ::Widget::GeoSearchLocation widget, hence all
            # corresponding <input>-tags have widget-specific
            # prefixed 'name' attribute.
            # calling post_fields to fix this
            my $widget_params = LJ::Widget::GeoSearchLocation->post_fields($args);

            $args->{loc_cn} ||= $widget_params->{country};
            $args->{loc_ci} ||= $widget_params->{city};
            $args->{loc_st} ||= $widget_params->{statedrop}
                || $widget_params->{stateother};

            # parse GET args into search constraints
            my @constraints = LJ::Directory::Constraint->constraints_from_formargs($args);

            # do the actual search (synchronous)
            my $dir = LJ::Directory::Search->new( %searchargs, constraints => \@constraints );
            my LJ::Directory::Results $res = $dir->search;
            $res = $dir->search while !$res;

            if ($res) {
                my $self_link = {
                    self_link => sub {
                        LJ::page_change_getargs(
                            page         => $_[0],
                            start_search => ''
                        );
                    }
                };

                $rv->{paging_bar} =
                    LJ::paging_bar( $searchargs{page}, $res->pages, $self_link );

                my @users = $res->users;
                $rv->{numusers} = scalar @users;
                $rv->{results}  = $res->render;

            }
            else {
                $rv->{search_err} = 1;
            }
        }

        return DW::Template->render_template( 'directory/results.tt', $rv );
    }

    # show the search form
    my $w = LJ::Widget::GeoSearchLocation->new;
    $rv->{location_widget} = $w->render( country => '', state => '', city => '' );

    return DW::Template->render_template( 'directory/index.tt', $rv );
}

1;
