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

use strict;
use warnings;
use Carp;
use Date::Calc qw(Days_in_Month Decode_Month);

use lib '/app/tools/rps/lib';
#use RPS::ArtistContract::TermList;
use RPS::ArtistContract::TermHash;
use RPS::ArtistContract::DefaultTerm;
use RPS::Payee::ArtistPayee;
use RPS::ArtistContract::UnitEscalationList;
use RPS::ControlledComposition::ControlledComposition;

use RPS::DB::Item::NewArtistContract;
use RPS::DB::Item::Artist;
use RPS::DB::Item::ContractRateType;

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{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::NewArtistContract->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->{payor_id} = $dbItem->payor_id;
    $hrProperties->{client_contract_id} = $dbItem->client_contract_id;
    $hrProperties->{issue_date} = $dbItem->issue_date;
    $hrProperties->{term_start} = $dbItem->term_start;
    $hrProperties->{term_end} = $dbItem->term_end;
    $hrProperties->{reserve_rate} = $dbItem->reserve_rate;

    $hrProperties->{comments} = $dbItem->comments;

    # !!! JPK - Going to ignore this property - We'll want to drop this column from the table soon.
    #
#    $hrProperties->{digital_reserves_enabled} = $dbItem->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}	= Common::FormObject::Scalar->new(value => $props->{artist_contract_id}, readOnly => 1);
    $self->{Title}				= Common::FormObject::Scalar::String->new(value => $props->{title}, required => 1);
    $self->{ArtistDescription}	= Common::FormObject::Scalar::String->new(value => $props->{artist_description});
    $self->{ArtistPayeeID}		= Common::FormObject::Scalar->new(value => $props->{artist_payee_id}, required => 1);
    $self->{PayorID}		    = Common::FormObject::Scalar->new(value => $props->{payor_id}, required => 1);
    $self->{ClientContractID}	= Common::FormObject::Scalar::String->new(value => $props->{client_contract_id});
    $self->{IssueDate}			= Common::FormObject::Scalar::Date->new(value => $props->{issue_date});
    $self->{TermStart}			= Common::FormObject::Scalar::Date->new(value => $props->{term_start});     
    $self->{TermEnd}			= Common::FormObject::Scalar::Date->new(value => $props->{term_end});      
    $self->{ReserveRate}		= Common::FormObject::Scalar::Percent->new(value => $props->{reserve_rate});

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

	$self->{Comments}	        = Common::FormObject::Scalar::String->new(value => $props->{comments});

	# Combining Title and ClientContractID for autocomplete purposes
	#
	my $titleAndClientContractID = "(" . $props->{client_contract_id} . ") " . $props->{title};
	$self->{TitleAndClientContractID}	= Common::FormObject::Scalar::String->new(value => $titleAndClientContractID);

    # !!! jpk - I don't agree with this at all - this stuff really should be in load subs.
    # There _is_ a use for a contract object without all this extra state.
    # But... I'll leave it alone for now.
    #

	# -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
	# 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} = Common::FormObject::Scalar->new(value => $hasCComp, readOnly => 1);


    # This is an editable section of the contract, so it
	# needs to be loaded here.
    #
    $self->{ReserveLiquidationList} = RPS::License::ReserveLiquidationList->new
    (
        id => $props->{artist_contract_id},
        type => RPS::DB::Item::ReserveLiquidation::kTypeArtistContract,
    );
}


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

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

        $self->{ControlledComposition} = $self->{_ccomp};
        $self->{TermList} = RPS::ArtistContract::TermHash->new(artistContractID => $contractID);
        $self->{DefaultTerm} = RPS::ArtistContract::DefaultTerm->new(artistContractID => $contractID);
	}
}


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

        my $defaultPayor = RPS::DB::Item::Payor->GetDefault();
        if ($defaultPayor)
        {
            $hrProperties->{payor_id} = $defaultPayor->payor_id;
        }
        # JPK - Don't have any canned defaults (yet)
        #
    }


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

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

        my $sum = 0;
        if ($self->ReserveRate())
        {
            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) = @_;

        my $dbObj;
        if($self->ArtistContractID())
        {
            $dbObj = RPS::DB::Item::NewArtistContract->Lookup(artist_contract_id => $self->ArtistContractID());
        }
        else
        {
            $dbObj = RPS::DB::Item::NewArtistContract->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->reserve_rate($self->ReserveRate());
        $dbObj->payor_id($self->PayorID());
        $dbObj->term_start($self->TermStart());
        $dbObj->term_end($self->TermEnd());    
        $dbObj->comments($self->Comments());    

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

        # save the term list
        #
        foreach my $termKey (keys %{$self->{TermList}->getHash()})
        {
            my $term = $self->{TermList}->getHash()->{$termKey};
            
            if(defined $term)
            {
                $term->ArtistContractID($dbObj->artist_contract_id);
            }
		}

    $self->{TermList}->save();

    # Now save the liquidation list.
    #
    foreach my $liq (@{$self->{ReserveLiquidationList}->getList()})
    {
        if(defined $liq && $liq->Percent())
        {
            # assign from the newly saved dbObj
            $liq->ID($dbObj->artist_contract_id);
        }
    }
    $self->{ReserveLiquidationList}->save();

	# save the default term
	#
    $self->{DefaultTerm}->ArtistContractTermID(undef) if( !$self->ArtistContractID() ); # default term for new contract

    $self->{DefaultTerm}->ArtistContractID($dbObj->artist_contract_id);
    $self->{DefaultTerm}->save();

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

sub delete
{
	my $self = shift;

	# TODO: we'll have to delete all the terms, reserve, escalation, attached albums, tracks, etc...
	#
	# my $myDBObj = RPS::DB::Item::NewArtistContract->Lookup(artist_contract_id => $self->ArtistContractID());
	# $myDBObj->delete();

	return 1;
}


###
1;#
###

