package Cardinal::OutlookReader;

use strict;
use Data::Dumper;
use Win32::OLE;
use vars qw (@folderNames %folders $mailbox $oFolder $Outlook $targetFolder $topFolderName 
             $VERSION);

###########################################################################
# prototypes
###########################################################################
sub LoadFolders($);

sub BEGIN 
{
    $VERSION = '1.0';	
    print "Initializing OutlookReader package - $VERSION  11/22/05\n";

}	

###########################################################################
# 
#    FUNCTION:    CountUnreadItems()
# 
#    DESCRIPTION: This function loops through the items in a mailbox looking
#                 for as-yet unread items.  The count of unread items if returned.
# 
#    RETURNS:     $unreadItemCount
# 
#    DATE:        11-22-05
# 
#    BY:          Ken LeFevre
# 
#    REVISED:     
# 
############################################################################
sub CountUnreadItems($$$)
{
    my ($self) = @_;
    my $count = 0;
    my $oFolder = $self->GetCurrentFolderObject();
    return ($oFolder->UnreadItemCount);
}

sub DESTROY
{   
    print "Destroying the OutlookReader object\n";   
    Win32::OLE->Uninitialize;
}

###########################################################################
# 
#    FUNCTION:    GetCurrentFolderName()
# 
#    DESCRIPTION: This function returns the name of the current folder.
# 
#    RETURNS:     void
# 
#    DATE:        11-17-05
# 
#    BY:          Ken LeFevre
# 
#    REVISED:     
# 
############################################################################
sub GetCurrentFolderName($)
{
    my ($self) = @_;

    return($targetFolder);
}

###########################################################################
# 
#    FUNCTION:    GetCurrentFolderObject()
# 
#    DESCRIPTION: This function returns the object that represents the 
#                 current folder.
# 
#    RETURNS:     void
# 
#    DATE:        11-17-05
# 
#    BY:          Ken LeFevre
# 
#    REVISED:     
# 
############################################################################
sub GetCurrentFolderObject($)
{
    my ($self) = @_;
    my $folderId = $folders{$targetFolder};
    print "(GetCurrentFolderObject) folderId: $folderId\n";
    my $oFolder = $self->{namespace}->GetFolderFromID($folderId);
    die "Dying in GetCurrentFolderObject " . Win32::OLE->LastError(),"\n" if Win32::OLE->LastError(  );

    return($oFolder);
}

###########################################################################
# 
#    FUNCTION:    GetCurrentMailbox()
# 
#    DESCRIPTION: This function returns the name of the current mailbox.
# 
#    RETURNS:     void
# 
#    DATE:        11-17-05
# 
#    BY:          Ken LeFevre
# 
#    REVISED:     
# 
############################################################################
sub GetCurrentMailbox($)
{
    my ($self) = @_;

    return($mailbox);
}

###########################################################################
# 
#    FUNCTION:    LoadFolders()
# 
#    DESCRIPTION: This function loads the folders and subfolders that are
#                 part of $mailbox.
# 
#    RETURNS:     void
# 
#    DATE:        11-17-05
# 
#    BY:          Ken LeFevre (based on code from Shawn A. Clifford)
# 
#    REVISED:     
# 
############################################################################
sub LoadFolders($)
{
    my ($Top, $depth) = @_;
    my $cmdBase = '$folders{' . "'" . $topFolderName . "'}";
    my $cmd = $cmdBase;
    my $cnt = 0;

    #
    #  Collection indexes start at 1, not 0
    #
    foreach my $j (1..$Top->Folders->Count) 
    {
        my $folderName = $Top->Folders->Item($j)->Name;
        if ($folderName ne 'Calendar' &&        # don't bother with folders we'll never process
            $folderName ne 'Contacts' &&
            $folderName ne 'Drafts' &&
            $folderName ne 'Journal' &&
            $folderName ne 'Notes' &&
            $folderName ne 'Outbox' &&
            $folderName ne 'Sent Items' &&
            $folderName ne 'Tasks')
        {
            $folders{$folderName} = $Top->Folders->Item($j)->EntryID;

            if ($Top->Folders->Item($j)->Folders->Count > 0) 
            {
                LoadFolders($Top->Folders->Item($j));
            }
        }
    }
}

###########################################################################
# 
#    FUNCTION:    LoadMailbox()
# 
#    DESCRIPTION: This function loads the folders and subfolders that make
#                 up the mailbox named by $mailbox.
# 
#    RETURNS:     void
# 
#    DATE:        11-17-05
# 
#    BY:          Ken LeFevre (loosely based on code by Shawn A. Clifford)
# 
#    REVISED:     
# 
############################################################################
sub LoadMailbox($$)
{
    my ($self, $mailbox) = @_;

    foreach my $i (1..$self->{namespace}->Folders->Count) 
    {
        my $folderName = $self->{namespace}->Folders($i)->Name;
        my $oFolder = $self->{namespace}->Folders($i);
        print "(LoadMailbox) Folder:  $folderName\n";

        if ($folderName eq $mailbox)
        {   
            $self->{mailboxFound} = 1;
            $topFolderName = $folderName;
            LoadFolders($oFolder);   
            last;
        }
    }
#    print "Here are the subfolders found in $mailbox\n";
#    print Dumper(%folders);
#    print "\n";
}

###########################################################################
# 
#    FUNCTION:    new()
# 
#    DESCRIPTION: This function creates the OutlookReader object.
# 
#    RETURNS:     void
# 
#    DATE:        11-17-05
# 
#    BY:          Ken LeFevre
# 
#    REVISED:     
# 
############################################################################
sub new($$$$)
{
    my ($this, $profileName, $password, $_mailbox, $_targetFolder) = @_;

    my $self = {};
    bless $self, $this;
    Win32::OLE->Initialize(Win32::OLE::COINIT_OLEINITIALIZE); # needs this magic incantation
    die Win32::OLE->LastError(),"\n" if Win32::OLE->LastError(  );

    eval { $Outlook = Win32::OLE->GetActiveObject('Outlook.Application') };
        die "Outlook is not installed" if $@;
    unless (defined $Outlook) {
        $Outlook = Win32::OLE->new('Outlook.Application', sub {$_[0]->Quit;})
        or die "Oops, cannot start Outlook " . Win32::OLE->LastError() . "\n";
    }
    print "Just called Win32::OLE->Initialize(Win32::OLE::COINIT_OLEINITIALIZE)\n";
    $self->{namespace} = $Outlook->GetNamespace("MAPI");
    $self->{namespace}->Logon($profileName, $password, 0, 1);
    $mailbox = $_mailbox;
    $targetFolder = $_targetFolder;
    $self->{mailboxFound} = 0;
    $self->LoadMailbox($mailbox);
    die "Couldn't find mailbox $mailbox" if !$self->{mailboxFound};

    return($self);
}

###########################################################################
# 
#    FUNCTION:    ProcessItems()
# 
#    DESCRIPTION: This function loops through the items in a mailbox, calling
#                 the callback function provided on against each item.
# 
#    RETURNS:     void
# 
#    DATE:        11-17-05
# 
#    BY:          Ken LeFevre
# 
#    REVISED:     
# 
############################################################################
sub ProcessItems($$$)
{
    my ($self, $callbackFunc, $deleteFlag) = @_;
    print "=====>callbackFunc: $callbackFunc\n";
    print "=====>deleteFlag: $deleteFlag\n";
    print "(ProcessItems) TargetFolder: $targetFolder\n";
    my $oFolder = $self->GetCurrentFolderObject();
    
    if (!$oFolder)
    {   print "%%%%%>Unable to getFolderFromId\n";    }
    my $oItems = $oFolder->Items;
    if ($oItems->Count == 0) 
    {   print "No messages found\n";   } 
    else 
    {
        print "There are " . $oItems->Count . " messages in $targetFolder:\n";

        foreach my $oItem (in $oItems) 
        {
            my $redemption = Win32::OLE->new('Redemption.SafeMailItem');
            $redemption->{item} = $oItem;
            my $Sender    = $redemption->SenderName;
            my $Subject   = $redemption->Subject;
            my $Received  = $redemption->ReceivedTime;
            my $Body      = $redemption->Body;
            my $ReadStatus = $redemption->Unread;
            $oItem->Delete if $deleteFlag;
            &{$callbackFunc}($Sender, $Subject, $Received, $Body, $ReadStatus);
       }
    }
}

###########################################################################
# 
#    FUNCTION:    SetCurrentFolder()
# 
#    DESCRIPTION: This function returns the name of the current mailbox.
# 
#    RETURNS:     void
# 
#    DATE:        11-17-05
# 
#    BY:          Ken LeFevre
# 
#    REVISED:     
# 
############################################################################
sub SetCurrentFolder($$)
{
    my ($self, $_targetFolder) = @_;
    
    $targetFolder = $_targetFolder;
}

###########################################################################
# 
#    FUNCTION:    SetCurrentMailbox()
# 
#    DESCRIPTION: This function returns the name of the current mailbox.
# 
#    RETURNS:     void
# 
#    DATE:        11-17-05
# 
#    BY:          Ken LeFevre
# 
#    REVISED:     
# 
############################################################################
sub SetCurrentMailbox($$)
{
    my ($self, $_mailbox) = @_;
    
    $mailbox = $_mailbox;
    $self->LoadMailbox($mailbox);
}

1;