#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#------------------------------------------------------------
package RPS::Contract::ArtistContract;

use strict;
use Carp;
use Data::Dumper;

use lib '/app/tools/rps/lib';
use RPS::Catalog::AlbumContract;
use RPS::Contract::TermList;
use RPS::Contract::RegionList;
use RPS::Contract::UnitEscalationList;
use RPS::ControlledComposition::ControlledComposition;
use RPS::Payee::ArtistPayee;
use RPS::DB::Item::ArtistContract;
use RPS::DB::Item::Artist;

use RPS::XMLObject;
use base 'RPS::XMLObject';

sub _init {
    my ( $self, %args ) = @_;

    $self->SUPER::_init(%args);

    my %properties;
    if ( $args{_dbItem} ) {
        $self->_propertiesFromDBItem( \%properties, $args{_dbItem} );
    } elsif ( $args{artistContractID} ) {
        $self->_propertiesFromDB( \%properties, $args{artistContractID} );
    } else {
        $self->_propertiesFromDefaults( \%properties );
    }

    $self->_initProperties( \%properties );
    $self->_initSubs( \%properties );

    return $self;
}

sub _propertiesFromDB {
    my ( $self, $hrProperties, $id ) = @_;

    my $dbItem = RPS::DB::Item::ArtistContract->Lookup( artist_contract_id => $id );
    $self->_propertiesFromDBItem( $hrProperties, $dbItem );
}

sub _propertiesFromDBItem {
    my ( $self, $hrProperties, $dbItem ) = @_;

    $hrProperties->{artist_contract_id} = $dbItem->artist_contract_id;
    $hrProperties->{title}              = $dbItem->title;
    $hrProperties->{artist_description} = $dbItem->artist_description;
    $hrProperties->{artist_payee_id}    = $dbItem->artist_payee_id;
    $hrProperties->{client_contract_id} = $dbItem->client_contract_id;
    $hrProperties->{issue_date}         = $dbItem->issue_date;

    $hrProperties->{unit_based_enabled}      = $dbItem->unit_based_enabled;
    $hrProperties->{unit_based_rate_type}    = $dbItem->unit_based_rate_type;
    $hrProperties->{unit_based_rate}         = $dbItem->unit_based_rate;
    $hrProperties->{unit_based_rate_basis}   = $dbItem->unit_based_rate_basis;
    $hrProperties->{unit_based_reserve_rate} = $dbItem->unit_based_reserve_rate;

    $hrProperties->{unit_based_digital_enabled}          = $dbItem->unit_based_digital_enabled;
    $hrProperties->{unit_based_digital_rate_type}        = $dbItem->unit_based_digital_rate_type;
    $hrProperties->{unit_based_digital_album_rate}       = $dbItem->unit_based_digital_album_rate;
    $hrProperties->{unit_based_digital_single_rate}      = $dbItem->unit_based_digital_single_rate;
    $hrProperties->{unit_based_digital_reserves_enabled} = $dbItem->unit_based_digital_reserves_enabled;

    $hrProperties->{net_based_rate}                     = $dbItem->net_based_rate;
    $hrProperties->{net_based_reserve_rate}             = $dbItem->net_based_reserve_rate;
    $hrProperties->{net_based_digital_reserves_enabled} = $dbItem->net_based_digital_reserves_enabled;

    $hrProperties->{date_created}  = $dbItem->date_created;
    $hrProperties->{date_modified} = $dbItem->date_modified;
    $hrProperties->{created_by}    = $dbItem->created_by;
    $hrProperties->{modified_by}   = $dbItem->modified_by;

}

sub _initProperties {
    my ( $self, $props ) = @_;

    $self->{ArtistContractID} = RPS::XMLObject::Scalar::Integer->new( value => $props->{artist_contract_id}, readOnly => 1 );
    $self->{Title} = RPS::XMLObject::Scalar::String->new( value => $props->{title}, required => 1 );
    $self->{ArtistDescription} = RPS::XMLObject::Scalar::String->new( value => $props->{artist_description} );
    $self->{ArtistPayeeID} = RPS::XMLObject::Scalar::Integer->new( value => $props->{artist_payee_id}, required => 1 );
    $self->{ClientContractID} = RPS::XMLObject::Scalar::String->new( value => $props->{client_contract_id} );
    $self->{IssueDate} = RPS::XMLObject::Scalar::Date->new( value => $props->{issue_date} );

    $self->{UnitBasedEnabled}     = RPS::XMLObject::Scalar::Boolean->new( value => $props->{unit_based_enabled} );
    $self->{UnitBasedRateType}    = RPS::XMLObject::Scalar::Integer->new( value => $props->{unit_based_rate_type} );
    $self->{UnitBasedRate}        = RPS::XMLObject::Scalar::Percent->new( value => $props->{unit_based_rate} );
    $self->{UnitBasedRateBasis}   = RPS::XMLObject::Scalar::Integer->new( value => $props->{unit_based_rate_basis} );
    $self->{UnitBasedReserveRate} = RPS::XMLObject::Scalar::Percent->new( value => $props->{unit_based_reserve_rate} );

    $self->{UnitBasedDigitalEnabled}    = RPS::XMLObject::Scalar::Boolean->new( value => $props->{unit_based_digital_enabled} );
    $self->{UnitBasedDigitalRateType}   = RPS::XMLObject::Scalar::Integer->new( value => $props->{unit_based_digital_rate_type} );
    $self->{UnitBasedDigitalAlbumRate}  = RPS::XMLObject::Scalar::Decimal->new( value => $props->{unit_based_digital_album_rate} );
    $self->{UnitBasedDigitalSingleRate} = RPS::XMLObject::Scalar::Decimal->new( value => $props->{unit_based_digital_single_rate} );
    $self->{UnitBasedDigitalReservesEnabled} =
      RPS::XMLObject::Scalar::Boolean->new( value => $props->{unit_based_digital_reserves_enabled} );

    $self->{NetBasedRate}                   = RPS::XMLObject::Scalar::Percent->new( value => $props->{net_based_rate} );
    $self->{NetBasedReserveRate}            = RPS::XMLObject::Scalar::Percent->new( value => $props->{net_based_reserve_rate} );
    $self->{NetBasedDigitalReservesEnabled} = RPS::XMLObject::Scalar::Boolean->new( value => $props->{net_based_digital_reserves_enabled} );

    $self->{CreatedDate}  = RPS::XMLObject::Scalar::DateTime->new( value => $props->{date_created},  readOnly => 1 );
    $self->{ModifiedDate} = RPS::XMLObject::Scalar::DateTime->new( value => $props->{date_modified}, readOnly => 1 );
    $self->{CreatedBy}    = RPS::XMLObject::Scalar::UserName->new( value => $props->{created_by},    readOnly => 1 );
    $self->{ModifiedBy}   = RPS::XMLObject::Scalar::UserName->new( value => $props->{modified_by},   readOnly => 1 );

    # -jff- the artist contract by itself is fairly useless,
    # so I feel like ArtistPayee is a pretty integral part of this object.
    # It was in the _initSubs, but I moved it here.
    #
    $self->{ArtistPayee} = RPS::Payee::ArtistPayee->new( artistPayeeID => $props->{artist_payee_id}, loadSubs => 0, readOnly => 1 );

    # the basic contract object needs to know if it has a ControlledComp or not.
    # So we'll look for one here and save it internally so we can reuse it later
    # on in loadSubs (if necessary)
    #
    $self->{_ccomp} = RPS::ControlledComposition::ControlledComposition->new( contractID => $props->{artist_contract_id}, readOnly => 1 );
    my $hasCComp = 0;
    if ( defined $self->{_ccomp} && $self->{_ccomp}->ControlledCompositionID() ) {
        $hasCComp = 1;
    }
    $self->{HasCComp} = RPS::XMLObject::Scalar->new( value => $hasCComp, readOnly => 1 );

    # I need this object when creating a new contract.
    # But I don't want to load all the other subs
    #
    $self->{UnitBasedReserveLiquidationList} = RPS::License::ReserveLiquidationList->new(
        id   => $props->{artist_contract_id},
        type => RPS::DB::Item::ReserveLiquidation::kTypeContractUnitBased,
    );

    $self->{NetBasedReserveLiquidationList} = RPS::License::ReserveLiquidationList->new(
        id   => $props->{artist_contract_id},
        type => RPS::DB::Item::ReserveLiquidation::kTypeContractNetBased,
    );

}

sub _initSubs {
    my ( $self, $props ) = @_;

    if ( $self->loadSubs() ) {
        my $contractID = $props->{artist_contract_id};

        # MOVED to initProperties so we can always know if a CComp exists -jff-
        #
        # Load the controlled composition clause.
        #
        # $self->{ControlledComposition} = RPS::ControlledComposition::ControlledComposition->new
        # (
        # contractID => $contractID,
        # readOnly => 1,
        # );
        $self->{ControlledComposition} = $self->{_ccomp};

        $self->{UnitBasedRegionList} = RPS::Contract::RegionList->new(
            contractID   => $contractID,
            contractMode => RPS::DB::Item::ArtistContract::kModeUnit
        );

        $self->{NetBasedRegionList} = RPS::Contract::RegionList->new(
            contractID   => $contractID,
            contractMode => RPS::DB::Item::ArtistContract::kModeNetRevenue
        );

        # Load the terms and deductions for unit_based and net_based.
        #
        $self->{UnitBasedTermList} = RPS::Contract::TermList->new(
            contractID   => $contractID,
            contractMode => RPS::DB::Item::ArtistContract::kModeUnit,
            readOnly     => 1,
        );

        $self->{UnitBasedDeductionList} = RPS::Contract::DeductionList->new(
            contractID   => $contractID,
            contractMode => RPS::DB::Item::ArtistContract::kModeUnit,
            readOnly     => 1,
        );

        $self->{UnitBasedDigitalDeductionList} = RPS::Contract::DeductionList->new(
            contractID   => $contractID,
            contractMode => RPS::DB::Item::ArtistContract::kModeUnitDigital,
            readOnly     => 1,
        );

        $self->{UnitBasedUnitEscalationList} = RPS::Contract::UnitEscalationList->new(
            contractID   => $contractID,
            contractMode => RPS::DB::Item::ArtistContract::kModeUnit,
            readOnly     => 1,
        );

        $self->{UnitBasedDigitalAlbumUnitEscalationList} = RPS::Contract::UnitEscalationList->new(
            contractID   => $contractID,
            contractMode => RPS::DB::Item::ArtistContract::kModeUnitDigital,
            readOnly     => 1,
        );

        $self->{UnitBasedDigitalSingleUnitEscalationList} = RPS::Contract::UnitEscalationList->new(
            contractID   => $contractID,
            contractMode => RPS::DB::Item::ArtistContract::kModeUnitDigitalSingle,
            readOnly     => 1,
        );

        $self->{NetBasedTermList} = RPS::Contract::TermList->new(
            contractID   => $contractID,
            contractMode => RPS::DB::Item::ArtistContract::kModeNetRevenue,
            readOnly     => 1,
        );

        $self->{NetBasedDeductionList} = RPS::Contract::DeductionList->new(
            contractID   => $contractID,
            contractMode => RPS::DB::Item::ArtistContract::kModeNetRevenue,
            readOnly     => 1,
        );

        $self->{NetBasedUnitEscalationList} = RPS::Contract::UnitEscalationList->new(
            contractID   => $contractID,
            contractMode => RPS::DB::Item::ArtistContract::kModeNetRevenue,
            readOnly     => 1,
        );
    }

}

sub _propertiesFromDefaults {
    my ( $self, $hrProperties ) = @_;

    # JPK - Don't have any canned defaults (yet)
    #
}

sub save {
    my ($self) = @_;

    my $dbObj;
    if ( $self->ArtistContractID() ) {
        $dbObj = RPS::DB::Item::ArtistContract->Lookup( artist_contract_id => $self->ArtistContractID() );
    } else {
        $dbObj = RPS::DB::Item::ArtistContract->Create();
    }

    # set fields here
    #
    $dbObj->artist_payee_id( $self->ArtistPayeeID() );
    $dbObj->client_contract_id( $self->ClientContractID() );
    $dbObj->title( $self->Title() );
    $dbObj->artist_description( $self->ArtistDescription() );
    $dbObj->issue_date( $self->IssueDate() );

    $dbObj->unit_based_enabled( $self->UnitBasedEnabled() );
    $dbObj->unit_based_rate_type( $self->UnitBasedRateType() );
    $dbObj->unit_based_rate( $self->UnitBasedRate() );
    $dbObj->unit_based_rate_basis( $self->UnitBasedRateBasis() );
    $dbObj->unit_based_reserve_rate( $self->UnitBasedReserveRate() );

    $dbObj->unit_based_digital_enabled( $self->UnitBasedDigitalEnabled() );
    $dbObj->unit_based_digital_rate_type( $self->UnitBasedDigitalRateType() );
    $dbObj->unit_based_digital_album_rate( $self->UnitBasedDigitalAlbumRate() );
    $dbObj->unit_based_digital_single_rate( $self->UnitBasedDigitalSingleRate() );
    $dbObj->unit_based_digital_reserves_enabled( $self->UnitBasedDigitalReservesEnabled() );

    $dbObj->net_based_rate( $self->NetBasedRate() );

    #	$dbObj->net_based_rate_basis($self->NetBasedRateBasis());
    $dbObj->net_based_reserve_rate( $self->NetBasedReserveRate() );
    $dbObj->net_based_digital_reserves_enabled( $self->NetBasedDigitalReservesEnabled() );

    # save db item
    #
    $dbObj->save();

    # Now save the liquidation list.
    #
    foreach my $liq ( @{ $self->{UnitBasedReserveLiquidationList}->getList() } ) {
        if ( defined $liq && $liq->Percent() ) {

            # assign from the newly saved dbObj
            $liq->ID( $dbObj->artist_contract_id );
        }
    }
    $self->{UnitBasedReserveLiquidationList}->save();

    foreach my $liq ( @{ $self->{NetBasedReserveLiquidationList}->getList() } ) {
        if ( defined $liq && $liq->Percent() ) {

            # assign from the newly saved dbObj
            $liq->ID( $dbObj->artist_contract_id );
        }
    }
    $self->{NetBasedReserveLiquidationList}->save();

    $self->_init( _dbItem => $dbObj );
}

sub delete {
    my $self = shift;

    my $myDBObj = RPS::DB::Item::ArtistContract->Lookup( artist_contract_id => $self->ArtistContractID() );
    $myDBObj->delete();

    return 1;
}

###
1;    #
###

