# Copyright 2002-2008 Josh Clark and Global Moxie, LLC. This code cannot be
# redistributed without permission from globalmoxie.com.  For more
# information, consult your Big Medium license.
#
# $Id: Person.pm 3043 2008-03-31 14:00:38Z josh $

package BigMed::Person;
use strict;
use warnings;
use utf8;
use Carp;

use base qw(BigMed::Library);

my @data_schema = (
    {   name  => 'last_name',
        type  => 'simple_text',
        index => 1,
    },
    {   name  => 'first_name',
        type  => 'simple_text',
        index => 1,
    },
    {   name  => 'email',
        type  => 'email',
        index => 1,
    },
    {   name    => 'url',
        type    => 'url',
        default => 'http://',
    },
    {   name => 'title',
        type => 'simple_text',
    },
    {   name => 'company',
        type => 'simple_text',
    },
    {   name => 'home_phone',
        type => 'simple_text',
    },
    {   name => 'work_phone',
        type => 'simple_text',
    },
    {   name => 'mobile_phone',
        type => 'simple_text',
    },
    {   name => 'fax',
        type => 'simple_text',
    },
    {   name => 'home_address',
        type => 'simple_text',
    },
    {   name => 'home_city',
        type => 'simple_text',
    },
    {   name => 'home_state',
        type => 'simple_text',
    },
    {   name => 'home_zip',
        type => 'simple_text',
    },
    {   name => 'work_address',
        type => 'simple_text',
    },
    {   name => 'work_city',
        type => 'simple_text',
    },
    {   name => 'work_state',
        type => 'simple_text',
    },
    {   name => 'work_zip',
        type => 'simple_text',
    },
    {   name => 'text',
        type => 'rich_text',
    },
    {   name => 'summary',
        type => 'rich_text_brief',
    },
);

BigMed::Person->register_minicontent(
    source         => 'people',
    elements       => \@data_schema,
    alpha_sort_col => ['last_name', 'first_name'],
    editor_abbr    => [
        { column => 'first_name', required => 1, },
        { column => 'last_name',  required => 1, },
        { column => 'email' },
        { column => 'url' },
        { column => 'title' },
        { column => 'company' },
        {   column       => 'shared',
            option_label => 'LIBRARY_Allow others to use this item',
            default      => 1,
        },
        {   column       => 'in_lib',
            option_label => 'LIBRARY_Display in library for reuse',
            default      => 1,
        },
    ],
    editor_fields => [
        { column => 'first_name', required => 1, },
        { column => 'last_name',  required => 1, },
        { column => 'email' },
        { column => 'url' },
        { column => 'title' },
        { column => 'company' },
        { column => 'home_phone' },
        { column => 'work_phone' },
        { column => 'mobile_phone' },
        { column => 'fax' },
        { column => 'home_address' },
        { column => 'home_city' },
        { column => 'home_state' },
        { column => 'home_zip' },
        { column => 'work_address' },
        { column => 'work_city' },
        { column => 'work_state' },
        { column => 'work_zip' },
        { column => 'text' },
        { column => 'summary' },
        {   column       => 'shared',
            option_label => 'LIBRARY_Allow others to use this item',
            default      => 1,
        },
        {   column       => 'in_lib',
            option_label => 'LIBRARY_Display in library for reuse',
            default      => 1,
        },
    ],
    preview => { html => \&preview_html },
);

sub name {    #provides the full name, from first/last
    my $self = shift;
    my $name = defined $self->first_name ? $self->first_name : q{};
    $name .= q{ } . $self->last_name if defined $self->last_name;
    return $name;
}

sub preview_html {
    my ( $app, $obj, $roptions ) = @_;

    my @contact;
    if ( $obj->email ) {
        push @contact,
          '<a href="mailto:' . $obj->email . '">' . $obj->email . '</a>';
    }
    if ( $obj->url && $obj->url ne 'http://' ) {
        my $text = $obj->url;
        $text = substr( $text, 0, 30 ) . '...' if length $text > 30;
        push @contact,
          '<a href="' . $obj->url . '" class="preview">' . $text . '</a>';
    }
    my $html = $app->html_template(
        'wi_person_preview.tmpl',
        FIRST_NAME => $obj->first_name,
        LAST_NAME  => $obj->last_name,
        TITLE      => $obj->title,
        COMPANY    => $obj->company,
    );
    return (
        PREVIEW_HTML => $html,
        STATUS_HTML  => join( ' | ', @contact ) || '&nbsp;'
    );
}

sub lib_preview_image {

    #    my ($obj, $site) = @_;
    return BigMed->bigmed->env('BMADMINURL') . '/img/bmcp_lib_person.png';
}

sub lib_namesearch_col {
    return ['first_name', 'last_name'];
}

sub exists_at_site {
    my ( $obj, $site, $rparam ) = @_;
    croak 'site object required' if !ref $site || !$site->isa('BigMed::Site');
    my $sid = $site->id;
    $rparam ||= {};

    my ( $sfirst, $slast, $semail ) =
      map { $_ || undef } ( $obj->first_name, $obj->last_name, $obj->email );
    return 0 if ( !$sfirst && !$slast && !$semail );
    my $seek = $rparam->{selection} || ref $obj;
    my $select = $seek->select(
        {   site       => $sid,
            first_name => $sfirst,
            last_name  => $slast,
            email      => $semail
        }
      )
      or return;
    return 0 if !$select->count;

    #need to have an exact lc match on all three fields
    my ( $first, $last, $email ) =
      map { $_ ? lc $_ : q{} } ( $sfirst, $slast, $semail );
    my $test;
    while ( $test = $select->next ) {
        my ( $tfirst, $tlast, $temail ) =
          map { $_ ? lc $_ : q{} }
          ( $test->first_name, $test->last_name, $test->email );
        return $test
          if $first eq $tfirst && $last eq $tlast && $email eq $temail;
    }
    return 0;
}

1;

__END__

=head1 NAME

BigMed::Person - Big Medium person object

=head1 DESCRIPTION

A BigMed::Person object represents a contact profile in the Big Medium
content management system.

=head1 USAGE

BigMed::Person is a subclass of BigMed::Library (and, thus, of BigMed::Data).
In addition to the methods documented below, please see the BigMed::Data
documentation for details about topics including:

=over 4

=item Creating a new data object

=item Saving a data object

=item Finding and sorting saved data objects

=item Data access methods

=item Error handling

=back

=head1 METHODS

=head2 Data Access Methods

BigMed::Person objects hold the following pieces of data. They can be
accessed and set using the standard data access methods described in the
BigMed::Data documentation. See the L<"Searching and Sorting"> section below
for details on the data columns available to search and sort BigMed::Site
objects.

=over 4

=item * id

The numeric ID of the tag object

=item * site

The numeric ID of the site to which the object belongs

=item * owner

The numeric ID of the user to which the object belongs

=item * in_lib

Boolean value indicating whether the item should be included in the library
display.

=item * shared

Boolean value indicating whether other users (other than webmasters
and admins) may include the item in their pages.

=item * last_name

=item * first_name

=item * text

Full description, biography or any other text about the person.

=item * summary

Brief description or bio blurb about the person.

=item * email

=item * 'url

=item * home_phone

=item * work_phone

=item * mobile_phone

=item * fax

=item * home_address

=item * home_city

=item * home_state

=item * home_zip

=item * work_address

=item * work_city

=item * work_state

=item * work_zip

=item * mod_time

Timestamp for when the last time the object was saved.

=item * create_time

Timestamp for when the object was first created.

=back

=head3 Searching and Sorting

You can look up and sort records by any combination of the following fields.
See the C<collect_lib> documentation in BigMed::Library and the C<fetch> and
C<select> documentation in BigMed::Data for more info.

=over 4

=item * id

=item * last_name

=item * first_name

=item * email

=item * site

=item * owner

=item * shared

=item * in_lib

=item * mod_time

=back

=head3 Checking for duplicates

BigMed::Person extends BigMed::Library's C<exists_at_site> stub
method. It returns the matching object if a similar object exists at the
argument site, otherwise a false value (undef on error).

    my $test;
    $test = $pers->exists_at_site($site_obj);
    $app->error_stop if !defined $test;
    if ($test) {
        print $test->id, ' has the same content as ', $pers->id, "\n";
    }

    #providing optional selection parameter in the second argument can provide
    #a performance boost
    my $select = BigMed::Person->select( { site => $site->id } )
      or $app->error_stop;
    $test = $pers->exists_at_site( $site, { selection => $select } );
    $app->error_stop if !defined $test;
    if ($test) {
        print $test->id, ' has the same content as ', $pers->id, "\n";
    }

The check searches for people with matching first name, last name and
e-mail address entries.

The optional second argument is a hash reference with one parameter.
Providing that parameter can provide a performance boost if you're
calling the method multiple times:

=over 4

=item * selection => $data_selection

A cached selection of person objects at the site to search.

=back

=head2 UTILITY METHODS

=over 4

=item * C<< $obj->name >>

Returns a concatenated string with the first and/or last name (depending on
whether values exist in either or both columns).

=back

=head1 SEE ALSO

=over 4

=item * BigMed::Library

=item * BigMed::MiniContent

=item * BigMed::Data

=back

=head1 AUTHOR & COPYRIGHTS

This module and all Big Medium modules are copyright Josh Clark
and Global Moxie. All rights reserved.

Use of this module and the Big Medium content
management system are governed by Global Moxie's software licenses
and may not be used outside of the terms and conditions outlined
there.

For more information, visit the Global Moxie website at
L<http://globalmoxie.com/>.

Big Medium and Global Moxie are service marks of Global Moxie
and Josh Clark. All rights reserved.

=cut

