#!/usr/bin/perl
package Tsuyoshi::Email;

# 1, you need to config SMTP and email in print_statement subroutine
# 2. Spinner does not spin until mail is sent. I tried with threads pragram and got a similar outcome.
# 3. when click a button, spinner shows and start spinning til email is sent and stop and hides. This is w
#   what i want to do.
# am i on a right track or doing entirely wrong from the beginning?? 

use Moose;
use utf8;
use Encode;

use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP;
use Email::MIME;
use Data::Recursive::Encode;
use MIME::Base64 qw(encode_base64);
use Path::Class;

# for SMTP
has 'smtp' => (
	is => 'rw',
	isa => 'Str',
	required => 1,
);
has 'ssl' => (
	is => 'rw',
	isa => 'Bool',
	required => 1,
);
has 'port' => (
	is => 'rw',
	isa => 'Int',
	required => 1,
);

# for emailing
has 'sasl_username' => (
	is => 'rw',
	isa => 'Str',
	required => 1,
);
has 'sasl_password' => (
	is => 'rw',
	isa => 'Str',
	required => 1,
);
has 'receiver_email_address' => (
	is => 'rw',
	isa => 'ArrayRef[Str]',
);
has 'email_subject' => (
	is => 'rw',
	isa => 'Str',
);
has 'email_content' => (
	is => 'rw',
	isa => 'Str',
);
has 'email_attachment' => (
	is => 'rw',
	isa => 'Str',
	predicate => 'has_attachment',
	clearer   => 'remove_attachment',
);
sub write_mail {
	my ( $self, $attr ) = @_;

	$self->receiver_email_address($$attr{'receiver_email_address'});
	$self->email_subject($$attr{'email_subject'});
	$self->email_content($$attr{'email_content'});
	if ( exists $$attr{'email_attachment'} ){
		$self->email_attachment($$attr{'email_attachment'});
	}
}
sub send_mail {
	my ( $self ) = @_;
	# config SMTP
	 my $transport = Email::Sender::Transport::SMTP->new({
	 ssl => $self->ssl,
	 host => $self->smtp,
	 port => $self->port,
	 sasl_username => $self->sasl_username,
	 sasl_password => $self->sasl_password,
	});
	# creating email
	my $email = Email::MIME->create(
		header =>Data::Recursive::Encode->encode( 'MIME-Header-ISO_2022_JP' => [ ]), 
		parts => [
			Email::MIME->create(
				attributes => {
					content_type => 'text/plain',
					charset => 'ISO-2022-JP',
					encoding => '7bit',
				},
				body => encode('iso-2022-jp' => $self->email_content),
			), # create
		]
	); # create
	$email->header_str_set( To => @{ $self->receiver_email_address } );

	$email->header_str_set( From => $self->sasl_username  );
	$email->header_str_set( Subject => $self->email_subject  );

	if ( $self->has_attachment ){
			$email->parts_add( 
				[ 
						Email::MIME->create(
						attributes => {
							content_type => 'text/plain',
							name => $self->email_attachment,
							filename => $self->email_attachment,
							encoding => 'base64',
							disposition => 'attachment',
						},
						body => scalar file($self->email_attachment)->slurp,
					), # create
				]
			); # parts_add
		} # if	

	# sending email
	eval{
		sendmail($email, { transport => $transport });
	};
	if ($@){
		return "failed to send: $@\n";
	}else{
		return 1;
	};

} # send_mail()

__PACKAGE__->meta->make_immutable;
no Moose;
1;

package main;

use Parallel::ForkManager;
use Gtk3 -init;

my $pm = new Parallel::ForkManager(2);
my $window = Gtk3::Window->new('toplevel');
$window->signal_connect(delete_event => sub { Gtk3->main_quit() });

# spinner spinning and sending email
sub print_statement {
	my ( $self, $attr ) = @_;
	my @pid;
	# spin spinner
	$pid[0] = $pm->start;
		$$attr{'spinner'}->show;
		$$attr{'spinner'}->start;
	$pm->finish;
	# send email
	$pid[1] = $pm->start;
			my @to = (
				'add email here',
				'add email here',
			);
			my $email = Tsuyoshi::Email->new({
					'smtp' => 'smtp host name',
					'ssl' => 1,
					'port' => 465,
					'sasl_username' => 'user name comes here',
					'sasl_password' => 'passowrd comes here',
				});
			$email->write_mail({
					'receiver_email_address' => \@to,
					'email_subject' => 'subject comes here',
					'email_content' => "main content comes here",
			#		'email_attachment' => 'test.txt',
				});
			print $email->send_mail;

			#-----------------------------
			# this is the problem!!
			#-----------------------------
			$$attr{'spinner'}->stop;
			#$$attr{'spinner'}->hide;
	$pm->finish;

	$pm->wait_all_children;
}

my $grid = Gtk3::Grid->new();

my $spinner = Gtk3::Spinner->new;

my $start_button = Gtk3::Button->new_with_label("Start Spin");
$start_button->signal_connect( clicked => \&print_statement,
									      { 'spinner' => $spinner, }		  
); # signal_connect
#my $stop_button = Gtk3::Button->new_with_label("Stop Spin");
#$stop_button->signal_connect( clicked => sub {
#		#	$spinner->hide;
#			$spinner->stop;
#			print $spinner->get_visible,"\n";
#			$spinner->set_visible(0);
#	} # sub
#); # signal_connect
$grid->attach($start_button,1,1,1,1);
#$grid->attach($stop_button,1,2,2,1);
$grid->attach($spinner,1,3,3,1);
$window->add($grid);
$window->show_all();
$spinner->set_visible(0);

Gtk3->main();

