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

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

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

use lib '/app/tools/rps/lib';
use RPS::DB::Item::ArtistContract;
use RPS::DB::Item::ArtistContractTerm;
use RPS::Contract::DeductionList;
use RPS::Contract::ProductFormat;
use RPS::License::ReserveLiquidationList;
use RPS::Contract::ChannelList;
use RPS::Region::RegionList;

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


# jpk - providing some factory methods to perform 'abstract' instantiation.
# (This is going to require some circular includes...)
#
sub NewTerm
{
    my ($class, %args) = @_;

    my $self;

    my $contractID = $args{contractID};
    my $contractMode = $args{contractMode};
    my $format = $args{formatID};

    if (RPS::DB::Item::ArtistContract::kModeNetRevenue == $contractMode)
    {
        eval "require RPS::Contract::DigitalTerm";
        $self = RPS::Contract::DigitalTerm->new(contractID => $contractID, productFormatID => $format);
    }
    elsif (RPS::DB::Item::ArtistContract::kModeUnit == $contractMode)
    {
        eval "require RPS::Contract::PhysicalTerm";
        $self = RPS::Contract::PhysicalTerm->new(contractID => $contractID, productFormatID => $format);
    }

    return $self;
}

sub LoadTerm
{
    my ($class, $termID) = @_;

    # Fetch the dbitem for this term.
    #
    my $self;

    my $dbItem = RPS::DB::Item::ArtistContractTerm->Lookup(artist_contract_term_id => $termID);
    if (RPS::DB::Item::ArtistContract::kModeNetRevenue == $dbItem->contract_mode)
    {
        $self = RPS::Contract::DigitalTerm->new(_dbItem => $dbItem);
    }
    elsif (RPS::DB::Item::ArtistContract::kModeUnit == $dbItem->contract_mode)
    {
        $self = RPS::Contract::PhysicalTerm->new(_dbItem => $dbItem);
    }

    return $self;
}


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

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

    my %properties;

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

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

    return $self;
}


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

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


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

	$self->{_inDB} = 1;

    $hrProperties->{artist_contract_term_id} = $dbItem->artist_contract_term_id;
    $hrProperties->{artist_contract_id} = $dbItem->artist_contract_id;
    $hrProperties->{contract_mode} = $dbItem->contract_mode;
    $hrProperties->{product_format_id} = $dbItem->product_format_id;
    $hrProperties->{percent} = $dbItem->percent;
}


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

    $self->{ArtistContractTermID}	= RPS::XMLObject::Scalar::Integer->new(value => $props->{artist_contract_term_id}, readOnly => 1);
    $self->{ArtistContractID}		= RPS::XMLObject::Scalar::Integer->new(value => $props->{artist_contract_id}, required => 1);
    $self->{ContractMode}	    	= RPS::XMLObject::Scalar::Integer->new(value => $props->{contract_mode}, required => 1);
    $self->{ProductFormatID}		= RPS::XMLObject::Scalar::Integer->new(value => $props->{product_format_id}, required => 1);
    $self->{Percent}				= RPS::XMLObject::Scalar::Percent->new(value => $props->{percent}, required => 1);

	# this is how the template tells the backend to delete one of these.
	# the default is 'OFF' (ie. don't delete)
	#
	$self->{Delete} = RPS::XMLObject::Scalar->new();
}


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

	if($self->loadSubs())
	{
        $self->{ProductFormat} = RPS::Contract::ProductFormat->new(productFormatID => $props->{product_format_id}, readOnly => 1);
	}
}


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

    # JPK - It appears that contractID is a required parameter.
    # So it's best to use assert to test for that.
    #
    assert($contractID);
    $hrProperties->{artist_contract_id} = $contractID;
    $hrProperties->{product_format_id} = $formatID;
}

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

    # If this guy is being deleted, we don't really care what values it has...
    #
    if ($self->Delete())
    {
        return 1;
    }

    return $self->SUPER::validate();

}


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

	if($self->Delete())
	{
		$self->delete();
		return;
	}

	my $dbObj;
	if($self->ArtistContractTermID())
	{
		$dbObj = RPS::DB::Item::ArtistContractTerm->Lookup(artist_contract_term_id => $self->ArtistContractTermID());
	}
	else
	{
		$dbObj = RPS::DB::Item::ArtistContractTerm->Create();
	}

    $self->_saveSetDBObj($dbObj);

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

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


sub _saveSetDBObj
{
    my ($self, $dbObj) = @_;

	# set fields here
	#
	$dbObj->artist_contract_id($self->ArtistContractID());
	$dbObj->contract_mode($self->ContractMode());
#	$dbObj->channel_id($self->ChannelID());
	$dbObj->product_format_id($self->ProductFormatID());
#	$dbObj->price_level_id($self->PriceLevelID());
	$dbObj->percent($self->Percent());
}


sub delete
{
	my $self = shift;

	if($self->{_inDB})
	{
		my $myDBObj = RPS::DB::Item::ArtistContractTerm->Lookup(artist_contract_term_id => $self->ArtistContractTermID());
		$myDBObj->delete();
	}
    return 1;
}


###
1;#
###



