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

use strict;
use warnings;
use Carp;
use Date::Calc;

use lib '/app/tools/common/lib';
use Common::Assert;

use lib '/app/tools/rps/lib';
use RPS::DB::Item::ControlledComposition;
use RPS::License::ReserveLiquidationList;
use RPS::DB::Item::TrackLicense;

use Common::FormObject;
use base 'Common::FormObject';

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

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

    my %properties;
    if ( $args{_dbItem} ) {
        $self->_propertiesFromDBItem( \%properties, $args{_dbItem} );
    } elsif ( $args{controlledCompositionID} ) {
        $self->_propertiesFromDBWithControlledCompID( \%properties, $args{controlledCompositionID} );
    } elsif ( $args{contractID} ) {
        $self->_propertiesFromDBWithContractID( \%properties, $args{contractID} );
    } else {
        $self->_propertiesFromDefaults( \%properties );
    }

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

    return $self;
}

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

    my $dbItem = RPS::DB::Item::ControlledComposition->Lookup( controlled_composition_id => $id );
    if ($dbItem) {
        $self->_propertiesFromDBItem( $hrProperties, $dbItem );
    }
}

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

    my $dbItem = RPS::DB::Item::ControlledComposition->GetByContractID($id);
    if ($dbItem) {
        $self->_propertiesFromDBItem( $hrProperties, $dbItem );
    }
}

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

    assert($dbItem);

    $hrProperties->{controlled_composition_id} = $dbItem->controlled_composition_id;
    $hrProperties->{artist_contract_id}        = $dbItem->artist_contract_id;
    $hrProperties->{track_cap}                 = $dbItem->track_cap;
    $hrProperties->{rate_type}                 = $dbItem->rate_type;
    $hrProperties->{penny_rate}                = $dbItem->penny_rate;
    $hrProperties->{rate_basis}                = $dbItem->rate_basis;
    $hrProperties->{rate_percentage}           = $dbItem->rate_percentage;
    $hrProperties->{reserve_percentage}        = $dbItem->reserve_percentage;
    $hrProperties->{lock_date}                 = $dbItem->lock_date;
}

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

    $self->{ControlledCompositionID} = Common::FormObject::Scalar->new( value => $props->{controlled_composition_id} );
    $self->{ArtistContractID}        = Common::FormObject::Scalar->new( value => $props->{artist_contract_id}, required => 1 );
    $self->{TrackCap}                = Common::FormObject::Scalar->new( value => $props->{track_cap}, required => 1 );
    $self->{RateType}                = Common::FormObject::Scalar->new( value => $props->{rate_type}, required => 1 );
    $self->{RatePercentage} = Common::FormObject::Scalar::Percent->new( value => $props->{rate_percentage}, required => 1 );
    $self->{PennyRate} = Common::FormObject::Scalar::Decimal->new( value => $props->{penny_rate} );
    $self->{RateBasis} = Common::FormObject::Scalar->new( value => $props->{rate_basis} );
    $self->{ReservePercentage} = Common::FormObject::Scalar::Percent->new( value => $props->{reserve_percentage} );
    $self->{LockDate} = Common::FormObject::Scalar::Date->new( value => $props->{lock_date} );
}

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

    if ( $self->loadSubs() ) {
        $self->{ReserveLiquidationList} = RPS::License::ReserveLiquidationList->new(
            id   => $props->{controlled_composition_id},
            type => RPS::DB::Item::ReserveLiquidation::kTypeControlledComposition(),
        );
    }
}

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

    $hrProperties->{rate_percentage} = 100;
}

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

    my $valid = $self->SUPER::validate();

    # penny rate is required if type is penny rate
    #
    if ( RPS::DB::Item::TrackLicense::kRateTypePenny == $self->RateType() && !$self->PennyRate() ) {
        $self->{PennyRate}->setError(Common::FormObject::kErrFieldBlank);
        $valid = 0;
    }

    # RateBasis is not required if the rate type is penny rate
    #
    if ( !$self->RateBasis() && $self->RateType() != RPS::DB::Item::TrackLicense::kRateTypePenny ) {
        $self->{RateBasis}->setError(Common::FormObject::kErrFieldBlank);
        $valid = 0;
    }

    if ( RPS::DB::Item::TrackLicense::kRateBasisLock == $self->RateBasis() && !$self->LockDate() ) {
        $self->{LockDate}->setError(Common::FormObject::kErrFieldBlank);
        $valid = 0;
    }

    my $sum = 0;
    if ( $self->ReservePercentage() ) {
        foreach my $liq ( @{ $self->{ReserveLiquidationList}->getList() } ) {
            if ( defined $liq && $liq->Percent() ) {
                $sum += $liq->Percent();
            }
        }
        if ( $sum == 0 ) {
            $self->{ReserveLiquidationList}->setError(Common::FormObject::kErrFieldBlank);
            $valid = 0;
        }

    }

    return $valid;
}

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

    # -------------------------------
    # Save myself (ControlledComposition)
    # -------------------------------
    #
    my $dbObj;
    if ( $self->ControlledCompositionID() ) {
        $dbObj = RPS::DB::Item::ControlledComposition->Lookup( controlled_composition_id => $self->ControlledCompositionID() );
    } else {
        $dbObj = RPS::DB::Item::ControlledComposition->Create();
    }

    $dbObj->artist_contract_id( $self->ArtistContractID() );
    $dbObj->track_cap( $self->TrackCap() );
    $dbObj->rate_type( $self->RateType() );
    $dbObj->penny_rate( $self->PennyRate() );
    $dbObj->rate_percentage( $self->RatePercentage() );
    $dbObj->rate_basis( $self->RateBasis() );
    $dbObj->reserve_percentage( $self->ReservePercentage() );
    $dbObj->lock_date( $self->LockDate() );

    $dbObj->save();

    # let's save the liquidation list
    #
    foreach my $liq ( @{ $self->{ReserveLiquidationList}->getList() } ) {
        if ( defined $liq && $liq->Percent() ) {

            # assign from the newly saved dbObj
            $liq->ID( $dbObj->controlled_composition_id );

            # just to be safe
            $liq->Type(RPS::DB::Item::ReserveLiquidation::kTypeControlledComposition);
        }
    }
    $self->{ReserveLiquidationList}->save();

    # reload the state
    #
    $self->_init( _dbItem => $dbObj );
}

###
1;    #
###

