#---------------------------------------------------------------
# ____                   _ _         ____  _                    
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___ 
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/                            
#
# Copyright (C) 2012 RoyaltyShare, Inc.   All Rights Reserved
#---------------------------------------------------------------

package RPS::ArtistRoyalty::Fast::Final::ArtistRoyaltyAlbum;

use strict;
use Data::Dumper;
use File::Path;

use lib '/app/tools/common/lib';
use lib '/app/tools/rps/lib';
use lib '/app/tools/raptor/lib';
use Common::RSApp;
use Common::Assert;

use Data::Dumper;
use DB_File;

use RPS::ArtistRoyalty::Fast::Final::ArtistRoyaltyStatement;
use RPS::ArtistRoyalty::Fast::Mapped::Data;


use Common::Log;

use base 'RPS::ArtistRoyalty::Fast::Final';

use constant kArtistRoyaltyAlbumID          => 0;
use constant kArtistRoyaltyStatementID      => 1;
use constant kArtistContractID              => 2;
use constant kAlbumID                       => 3;
use constant kUnitLevelIncome               => 4;
use constant kNetRevenueIncome              => 5;
use constant kNetRevenueExpenses            => 6;
use constant kNetRevenueExpensesSubtotal    => 7;
use constant kRecoupableExpenses            => 8;
use constant kTotalIncome                   => 9;
use constant kTotalExpenses                 => 10;
use constant kPreviousBalance               => 11;
use constant kTotal                         => 12;
use constant kLicenseIncomeSubtotal         => 13;
use constant kDefaultNetRevenueRate         => 14;
use constant kIsCrossCollateralized         => 15;

# Private
use constant kStatementRef                  => 16;




my @gFields = 
(
'artist_royalty_album_id',
'artist_royalty_statement_id',
'artist_contract_id',
'album_id',
'unit_level_income',
'net_revenue_income',
'net_revenue_expenses',
'net_revenue_expenses_subtotal',
'recoupable_expenses',
'total_income',
'total_expenses',
'previous_balance',
'total',
'license_income_subtotal',
'default_net_revenue_rate',
'is_cross_collateralized',
);
sub Fields { return \@gFields; }


#root@localhost [C_WELK]> desc artist_royalty_album;
#+-------------------------------+------------------+------+-----+---------+----------------+
#| Field                         | Type             | Null | Key | Default | Extra          |
#+-------------------------------+------------------+------+-----+---------+----------------+
#| artist_royalty_album_id       | int(10) unsigned | NO   | PRI | NULL    | auto_increment | 
#| artist_royalty_statement_id   | int(10) unsigned | NO   | MUL | 0       |                | 
#| artist_contract_id            | int(10) unsigned | NO   |     | 0       |                | 
#| album_id                      | int(10) unsigned | NO   |     | 0       |                | 
#| unit_level_income             | decimal(16,4)    | NO   |     | 0.0000  |                | 
#| net_revenue_income            | decimal(16,4)    | NO   |     | 0.0000  |                | 
#| net_revenue_expenses          | decimal(16,4)    | NO   |     | 0.0000  |                | 
#| net_revenue_expenses_subtotal | decimal(16,4)    | NO   |     | 0.0000  |                | 
#| recoupable_expenses           | decimal(16,4)    | NO   |     | 0.0000  |                | 
#| total_income                  | decimal(16,4)    | NO   |     | 0.0000  |                | 
#| total_expenses                | decimal(16,4)    | NO   |     | 0.0000  |                | 
#| previous_balance              | decimal(16,4)    | NO   |     | 0.0000  |                | 
#| total                         | decimal(16,4)    | NO   |     | 0.0000  |                | 
#| license_income_subtotal       | decimal(16,4)    | NO   |     | 0.0000  |                | 
#| default_net_revenue_rate      | decimal(8,4)     | NO   |     | 0.0000  |                | 
#| is_cross_collateralized       | tinyint(1)       | NO   |     | 0       |                | 
#+-------------------------------+------------------+------+-----+---------+----------------+
#16 rows in set (0.00 sec)


sub FileName { 'artist_royalty_album' }
sub _MaxIDSql { 'SELECT MAX(artist_royalty_album_id) FROM artist_royalty_album' }


sub new
{
    my ($class, $data, $statement) = @_;

    my $item = $class->BlankItem();
    $class->_IncrementID();


    $item->[kArtistRoyaltyAlbumID] = $class->_CurrentID();
    $item->[kArtistRoyaltyStatementID] = $statement->id();

    $item->[kArtistContractID] = $data->[RPS::ArtistRoyalty::Fast::Mapped::Data::kArtistContractID];
    $item->[kAlbumID] = $data->[RPS::ArtistRoyalty::Fast::Mapped::Data::kAlbumID];
    $item->[kIsCrossCollateralized] = $data->[RPS::ArtistRoyalty::Fast::Mapped::Data::kCrossed];


    push @$item, $statement;

    # !!! We are eventually going to need to keep the reference to $statement around,
    # !!! so we can call it upon destruction to update summary data.
    # !!! We'll do that by pushing it onto the end of the array.
    # !!! Once we've sent over the summary data, we need to remember to pop that off so we
    # !!! don't write it out to the output file...
    #
    bless $item, $class;

    return $item;
}

sub statement 
{       
    my $self  = shift;
    return $self->[kStatementRef];
}

sub process
{
    my ($self, $data) = @_;

    # Test whether we're still looking at data for 'this' object.
    #
    if ($self->[kAlbumID] != $data->[RPS::ArtistRoyalty::Fast::Mapped::Data::kAlbumID]
     || $self->[kArtistContractID] != $data->[RPS::ArtistRoyalty::Fast::Mapped::Data::kArtistContractID])
    {
        return undef;
    }

    return 1;
}



sub _output
{
    my ($self, $fd) = @_;

    my $statement = pop @$self;

    # do nothing if we don't have an album id.
    # this comes into play when we've got payee transactions...
    #
    # !!! Actually, this will also come into play when we have contract-level
    # license income (at least I think it will).
    # In that case we'll need to send our accumulated license income up to the
    # statement.
    #
    if (0 == $self->[kAlbumID])
    {
        if ($self->[kLicenseIncomeSubtotal] != 0)
        {
            $statement->[RPS::ArtistRoyalty::Fast::Final::ArtistRoyaltyStatement::kContractLevelLicenseIncomeSubtotal] += $self->[kLicenseIncomeSubtotal];
        }

        # Don't actually output an album row.
        #
        return undef;
    }



    # Sum up some stuff.
    #
    if ($self->[kNetRevenueExpenses])
    {
        $self->[kNetRevenueExpensesSubtotal] = 
         Common::RSMath::round($self->[kNetRevenueExpenses] * ($self->[kDefaultNetRevenueRate] / 100), 4);       
    }

    $self->[kTotalExpenses] = $self->[kNetRevenueExpensesSubtotal] + $self->[kRecoupableExpenses];

    $self->[kTotalIncome] = $self->[kUnitLevelIncome] + $self->[kNetRevenueIncome];

    # !!! Need to start thinking about account balances...
    #
    # So, I'll need a data structure to access the ArtistRoyaltyAlbumBalanceAccount data.
    # It maps by artist_payee_id,album_id,artist_contract_id.
    # I think I'll just serialize a hash of {album_id}{artist_contract_id} = $previousBalance, and
    # store that in a berkeley db file keyed by the artist_payee_id.
    # I'll use a global variable to hold onto the last one I looked at, and stash the associated payee id.
    #
    # Ok, so build the account data first.
    # 

    # Actually, let's give the payee album balance to the Statement.
    # We're going to eval in a hash for each payee, so it makes sense.



    my $previousBalance = $statement->previousBalance($self->[kAlbumID], $self->[kArtistContractID]);
    Log->info("in ArtistRoyaltyAlbum, previous balance for album " . $self->[kAlbumID] . ", contract " . $self->[kArtistContractID] . " = $previousBalance");
    $self->[kPreviousBalance] = $previousBalance;



    # !!! Yes, this total seems correct.
    # !!! But I need to be careful how I update the statement summary data, which is broken up into a lot of different slots.
    # !!! EXCEPT many of these 'slots' don't appear to even get used anymore.  neat.
    #
    $self->[kTotal] = $previousBalance - $self->[kTotalExpenses] + $self->[kTotalIncome] + $self->[kLicenseIncomeSubtotal];


    # !!! Having trouble getting all this summary data to add up correctly.
    # !!! Let's restart.

    if ($self->[kIsCrossCollateralized])
    {
        $statement->[RPS::ArtistRoyalty::Fast::Final::ArtistRoyaltyStatement::kCrossCollateralizedIncomeSubtotal] += $self->[kTotalIncome];
        $statement->[RPS::ArtistRoyalty::Fast::Final::ArtistRoyaltyStatement::kCrossCollateralizedSubtotal] += $self->[kTotal];
        $statement->[RPS::ArtistRoyalty::Fast::Final::ArtistRoyaltyStatement::kCrossCollateralizedExpenseSubtotal] += $self->[kTotalExpenses];

        $statement->[RPS::ArtistRoyalty::Fast::Final::ArtistRoyaltyStatement::kCrossCollateralizedPreviousBalance] += $previousBalance;

        # It's weird how the arithmetic seems to change here...
        # !!! I keep on going back and forth with when these fucking Totals get updated.  driving me nuts.
        #
        # !!! It just seems pointless and wrong to update the statement totals here.
        # !!! Why can't the statement do that itself?
#        my $crossSubtotal = $self->[kTotalIncome] - $self->[kTotalExpenses] + $self->[kLicenseIncomeSubtotal];
#        $statement->[ArtistRoyaltyStatement::kTotal] += $crossSubtotal if $crossSubtotal > 0;

        # JPK - Stupidly, this column is only supposed to contain _crossed_ license income subtotals.
        #
        $statement->[RPS::ArtistRoyalty::Fast::Final::ArtistRoyaltyStatement::kLicenseIncomeSubtotal] += $self->[kLicenseIncomeSubtotal];
    }
    else
    {
        $statement->[RPS::ArtistRoyalty::Fast::Final::ArtistRoyaltyStatement::kUncrossedSubtotal] += $self->[kTotal];
        $statement->[RPS::ArtistRoyalty::Fast::Final::ArtistRoyaltyStatement::kTotal] += $self->[kTotal] if $self->[kTotal] > 0;
    }


    $self->SUPER::_output($fd);
}

1;

