package Egg::View::Mail::Base;
#
# Masatoshi Mizuno E<lt>lusheE<64>cpan.orgE<gt>
#
# $Id: Base.pm 285 2008-02-28 04:20:55Z lushe $
#
use strict;
use warnings;
use Carp qw/ croak /;
use base qw/ Egg::Base Egg::Component /;

our $VERSION = '0.01';

sub setup_plugin {
	my $class= shift;
	$class->isa_register(1, "Egg::View::Mail::Plugin::$_")
	        for (ref($_[0]) eq 'ARRAY' ? @{$_[0]}: @_);
	$class->isa_terminator(__PACKAGE__);
	$class;
}
sub setup_mailer {
	my $class = shift;
	my $m_name= shift || croak q{I want mailer name.};
	my @comps;
	if (@_) { push @comps, $_ for (ref($_[0]) eq 'ARRAY' ? @{$_[0]}: @_) }
	$class->isa_register
	        (1, $_, "Egg::View::Mail::$_") for (@comps, "Mailer::$m_name");
	$class->isa_terminator(__PACKAGE__);
	$class;
}
sub setup_template {
	my $class    = shift;
	my $view_name= shift || croak q{I want view name.};
	my $template = shift || "";
	$class->mk_classdata('default_template');
	$class->default_template($template);
	no strict 'refs';  ## no critic.
	no warnings 'redefine';
	*{"${class}::___view"}=
	   sub { $_[0]->{___view} ||= $_[0]->e->view($view_name) };
	$class;
}
sub send {
	my $self= shift;
	$self->mail_send( $self->create_mail_data(@_) );
}
sub create_mail_data {
	my $self= shift;
	my $data= { %{$self->config},
	  %{ $_[0] ? ($_[1] ? {@_}: $_[0]) : croak q{I want mail data.} },
	  };
	$data->{body}= $self->create_mail_body($data);
	$data;
}
sub create_mail_body {
	my($self, $data)= @_;
	\<<END_BODY;
@{[ $self->create_mail_header($data) ]}
@{[ ${$self->__get_mailbody($data)} ]}
END_BODY
}
sub create_mail_header {
	my($self, $data)= @_;
	<<END_HEADER;
Content-Type: text/plain
To: $data->{to}
From: $data->{from}
Subject: $data->{subject}
X-Mailer: $data->{x_mailer}
END_HEADER
}
sub __get_mailbody {
	my($self, $data)= @_;
	return ($data->{template} or ! $data->{body}) ? do {
		$self->can('___view')
		     || croak q{I want setup of 'setup_template' method.};
		my $param= { %{$self->config}, %$data };
		my $tmpl = $data->{template} || $self->default_template
		     || croak q{I want 'template'.};
		my $view= $self->___view;
		@{$view->params}{keys %$param}= values %$param;
		$view->render($tmpl);
	  }: do {
		  ref($data->{body}) eq 'ARRAY'   ? \join "\n\n", @{$data->{body}}
		: ref($data->{body}) eq 'SCALAR'  ? $data->{body} : \$data->{body};
	  };
}

1;

__END__

=head1 NAME

Egg::View::Mail::Base - Base class for MAIL controller.

=head1 SYNOPSIS

  package MyApp::View::Mail::MyController;
  use base qw/ Egg::View::Mail::Base /;
  
  __PACKAGE__->config( ...... );
  
  __PACKAGE__->setup_mailer( SMTP => qw/ MIME::Entity / );

=head1 DESCRIPTION

It is a base class to succeed to from the MAIL controller who generates it in 
the helper script.

see L<Egg::Helper::View::Mail>.

=head1 METHODS

In addition, L<Egg::Base> and L<Egg::Component> have been succeeded to.

=head2 setup_plugin ([PLUGIN_LIST])

It is made to use by building the plug-in into the MAIL controller.
The name that omits the part of 'Egg::View::Mail::Plugin' is passed to PLUGIN_LIST
by the list.

  __PACKAGE__->setup_plugin(qw/
     PortCheck
     Signature
     /);

There is a thing that the competition of the method is generated by the built-in
order, it doesn't operate normally, and the result of the expectation is not
 obtained. Please adjust the built-in order to solve it.

=head2 setup_mailer ([MAILER_NAME] => [COMP_LIST])

The component that does processing that actually transmits mail is built in.

L<Egg::View::Mail::Mailer::CMD> and L<Egg::View::Mail::Mailer::SMTP> are included
 in this package.

The name that omits the part of 'Egg::View::Mail::Mailer' to MAILER_NAME is passed.

  __PACKAGE__->setup_mailer('SMTP');

In addition, other components can be specified for COMP_LIST if necessary.
Please pass the name that omits the part of 'Egg::View::Mail' by the list.

  __PACKAGE__->setup_mailer( CMD => qw/
     MIME::Entity
     Encode::ISO2022JP
     / );

There is a thing that the competition of the method is generated by the 
component as well as 'setup_plugin'.

=head2 setup_template ( [VIEW_LABEL] => [DEFAULT_TEMPLATE] )

When the content of mail is generated with a template, the template used by the
 template engine and default is set.

   __PACKAGE__->setup_template( Mason => 'mail/text.tt' );

The argument and the configuration passed to 'send' method are set in the 
parameter of the template engine. It is possible to access it by '$p' from 
among the template engine.

  To Address   : <% $p->{to} %>
  From Address : <% $p->{from} %>

=head2 send ([MAIL_DATA_HASH])

It prepares, and transmit mail processing is passed to 'mail_send' method of 
Mailer system component.

MAIL_DATA_HASH overwrites the configuration.

Therefore, the item that can be specified becomes it as well as the 
configuration.

'body' or 'template' is always necessary. 
However, this is not necessary if the template of default is set by 'setup_template'
either.

  $mail->send( body => <<END_BODY );
  Will the movie go to see ?
  END_BODY
  
     Or
  
  $mail->send( template => 'mail.tt' );

The SCALAR reference and ARRAY can be passed to 'body'.

  # Changing line enters between each element when passing it with ARRAY.
  $mail->send( body => [qw/ Will the movie go to see ? /] );
  
  # If you pass it by the SCALAR reference ...
  $mail->send( body => \"Will the movie go to see ?\n" );

=head2 create_mail_data (MAIL_DATA_HASH)

The data to do Mail Sending is made.

After merging MAIL_DATA_HASH with the configuration and making the content of 
the transmission, this method returns the data.

=head2 create_mail_body (MAIL_DATA_HASH)

The content of the transmission including the mail header is returned.

The processing of this method is not practicable. Please build in 
L<Egg::View::Mail::MIME::Entity>.

=head2 create_mail_header (MAIL_DATA_HASH)

A basic mail header is returned.

=head2 SEE ALSO

L<Egg::Release>,
L<Egg::Base>,
L<Egg::Component>,
L<Egg::View::Mail>,
L<Egg::View::Mail::MIME::Entity>,
L<Egg::Helper::View::Mail>,

=head2 AUTHOR

Masatoshi Mizuno E<lt>lusheE<64>cpan.orgE<gt>

=head2 COPYRIGHT AND LICENSE

Copyright (C) 2008 Bee Flag, Corp. E<lt>L<http://egg.bomcity.com/>E<gt>, All Rights Reserved.

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.6 or,
at your option, any later version of Perl 5 you may have available.

=cut

