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

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

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


use lib '/app/tools/rps/lib';
use RPS::DB::Item::Album;
use RPS::Product::BonusTrackHash;
use Common::FormObject;
use RPS::Product::Product;
use RPS::Catalog::DistributionCache;


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{productID} && $args{trackID})
	{
		$self->_propertiesFromDB(\%properties, $args{productID}, $args{trackID});
	}
	else
	{
		$self->_propertiesFromDefaults(\%properties);
	}

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

    return $self;
}


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

	my $dbItem = RPS::DB::Item::ProductTrack->Lookup(product_id => $productID, track_id => $trackID);
	$self->_propertiesFromDBItem($hrProperties, $dbItem);
}

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

	$hrProperties->{product_id}     = $dbItem->product_id;
	$hrProperties->{track_id}       = $dbItem->track_id;
	$hrProperties->{disc_number}    = $dbItem->disc_number;
	$hrProperties->{disc_track}     = $dbItem->disc_track;
	$hrProperties->{is_bonus_track} = $dbItem->is_bonus_track;
	$hrProperties->{album_only}     = $dbItem->album_only;

    $hrProperties->{included} = 1;

	$self->{_inDB} = 1; # !!! Using an extra flag to denote that this was actually loaded from the db.
}


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

	$self->{ProductID}      = Common::FormObject::Scalar->new(value => $props->{product_id});
	$self->{TrackID}        = Common::FormObject::Scalar->new(value => $props->{track_id});
	$self->{DiscNumber}     = Common::FormObject::Scalar->new(value => $props->{disc_number});
	$self->{DiscTrack}      = Common::FormObject::Scalar->new(value => $props->{disc_track});
	$self->{IsBonusTrack}   = Common::FormObject::Scalar::Boolean->new(value => $props->{is_bonus_track});
	$self->{AlbumOnly}      = Common::FormObject::Scalar::Boolean->new(value => $props->{album_only});
	$self->{Included}       = Common::FormObject::Scalar::Boolean->new(value => $props->{included});

	# thse are readOnly to the form, but they get set by TrackList
	#
	$self->{Title}			= Common::FormObject::Scalar::String->new();
	$self->{Duration}		= Common::FormObject::Scalar->new();
	$self->{TrackOrder}	= Common::FormObject::Scalar->new();
	$self->{MediaType}	    = Common::FormObject::Scalar->new();
	$self->{ParentalAdvisory}			= Common::FormObject::Scalar::String->new();
}

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

	if($self->loadSubs())
	{
		$self->{BonusTrackList}
         = RPS::Product::BonusTrackHash->new(productID => $props->{product_id}, trackID => $props->{track_id});
	}
}


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

    $hrProperties->{included} = 1;

	$self->{_inDB} = 0;
}


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

	if (! $self->Included() && ! $self->IsBonusTrack())
	{
		# let's delete it
		#

		# First we need to clean out the album validation status first.
		my $product = new RPS::Product::Product( productID => $self->ProductID );
		my $cache = new RPS::Catalog::DistributionCache;

		$cache->clearAlbumStatus( albumID => $product->AssetID )
		    if( $product && $product->AssetID );


		# Now we can delete the record.
		$self->delete();
		return;
	}


	my $dbItem;
	if (! $self->{_inDB})
	{
		# This is a new entry
		#
		$dbItem = RPS::DB::Item::ProductTrack->Create(product_id => $self->ProductID(), track_id => $self->TrackID());
	}
	else
	{
		# This row already exists, but some of the data may have changed.
		#
		$dbItem = RPS::DB::Item::ProductTrack->Lookup(product_id => $self->ProductID(), track_id => $self->TrackID());
	}

	$dbItem->disc_number($self->DiscNumber());
	$dbItem->disc_track($self->DiscTrack());
	$dbItem->is_bonus_track($self->IsBonusTrack());
	$dbItem->album_only($self->AlbumOnly());

	$dbItem->save();
	$self->{_inDB} = 1;

	if($dbItem->is_bonus_track)
	{
		if(!$self->{BonusTrackList})
		{
			$self->{BonusTrackList} = RPS::Product::BonusTrackHash->new(productID => $dbItem->product_id, trackID => $dbItem->track_id);
		}

		foreach my $bonusTrackKey (keys %{$self->{BonusTrackList}->getHash()})
		{
		    my $bonusTrack = $self->{BonusTrackList}->getHash()->{$bonusTrackKey};
			if(defined $bonusTrack)
			{
				$bonusTrack->ProductID($dbItem->product_id);
				$bonusTrack->TrackID($dbItem->track_id);
			}
		}

		#$self->{BonusTrackList}->save(productID => $dbItem->product_id, trackID => $dbItem->track_id);
		$self->{BonusTrackList}->save(productID => $dbItem->product_id);
	}		

}


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

	return $self->{BonusTrackList};
}


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

	if($self->{_inDB})
	{
		my $trkProd = RPS::DB::Item::ProductTrack->Lookup(product_id => $self->ProductID(), track_id => $self->TrackID());
		$trkProd->delete();
		$self->{_inDB} = 0;
	}

	return 1;
}

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

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

    # disc_number and disc_track need to be validated, but only if this
    # track is 'included'
    #
    if ($self->Included())
    {
        if (! defined $self->DiscNumber())
        {
            $self->{DiscNumber}->setError(Common::FormObject::kErrFieldBlank);
            $valid = 0;
        }
        elsif ($self->DiscNumber() < 1)
        {
            $self->{DiscNumber}->setError(Common::FormObject::kErrFieldOutOfRange);
            $valid = 0;
        }

        if (! defined $self->DiscTrack())
        {
            $self->{DiscTrack}->setError(Common::FormObject::kErrFieldBlank);
            $valid = 0;
        }
        elsif ($self->DiscTrack() < 1)
        {
            $self->{DiscTrack}->setError(Common::FormObject::kErrFieldOutOfRange);
            $valid = 0;
        }
    }


    my $metadata_valid = $self->_validateMetadata( %args );
    return $valid && $metadata_valid;
}


sub _validateMetadata {
    my $self = shift;
	my $d = @_;

	my %args = @_;

    my $validator = $args{metadataValidator};
    my %validation_args;

	my $currentData = RPS::DB::Item::ProductTrack->Lookup(product_id => $self->ProductID, track_id => $self->TrackID )
        if( $self->ProductID && $self->TrackID );

    my %scalar_rule_map = (
		'DiscTrack' => { legacy => "disc_number",
						 validate => "disc-no" },
		'DiscNumber' => { legacy => "disc_track",
						  validate => "track-number" },
    );

    Common::Log::Debug( "Validate Product Track" );
	my $valid =  $self->SUPER::_validateMetadata( fieldMap => \%scalar_rule_map,
                                                  currentData => $currentData,
                                                  metadataValidator => $validator )
        if( $self->Included );

    return ! $self->Included || $valid;
}



###
1;#
###
