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

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

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

use lib '/app/tools/rps/lib';
use RPS::DB::Item::Album;
use RPS::DB::Item::ProductTrack;
use RPS::Product::Track;
use RPS::Track::TrackSimple;

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


sub _listProperties
{
    return
    {
        Track => 1
    };
}



# It really does seem that the easiest way to make this all work will be
# to also grab the album track list, and fill in all the missing tracks.
# Otherwise, really, it gets amazingly complex.

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

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

	my $productID = $args{productID};
	$self->{_productID} = $productID;
	my $albumID = $args{albumID};
#	assert($albumID);
	$self->{_albumID} = $albumID;

    $self->{Track} = [];

    my ($nextDiscNum, $nextDiscTrack) = (1,1);
	my %productTracks = ();
	if ($productID)
	{
		my $collection = RPS::DB::Item::ProductTrack->GetTracksByProductID($productID);

		while ($collection->hasNext())
		{
			my $obj = $collection->next();
			$productTracks{$obj->track_id} = $obj;
		}


        # Going to give the template a hint regarding what disc_number and disc_track to use
        #
        ($nextDiscNum, $nextDiscTrack) = RPS::DB::Item::ProductTrack->GetNextDiscNumAndDiscTrack($productID);
        $self->{NextDiscNumber} = $nextDiscNum;
        $self->{NextDiscTrack} = $nextDiscTrack;
	}

	# Now loop through the album tracks.  If an album track is in this product,
	# then it will be in our %trackHash, and we can use that db item.
	# If not, then we need to create a 'placeholder' Product::Track.
	#
    $self->{Track} = [];
    if ($albumID)
    {
	    my $albumTrackList = RPS::Track::TrackListSimple->new(albumID => $albumID);
	    foreach my $albumTrack (@{$albumTrackList->getTracks()})
	    {
		    my $track;
		    if ($productTracks{$albumTrack->TrackID()})
		    {
			    $track = RPS::Product::Track->new(_dbItem => $productTracks{$albumTrack->TrackID()});
		    }
		    else
		    {
			    $track = RPS::Product::Track->new();
			    $track->Included(0);
			    $track->ProductID($productID);
			    $track->TrackID($albumTrack->TrackID());
                $track->{NextDiscNumber} = $nextDiscNum;
                $track->{NextDiscTrack} = $nextDiscTrack++;
		    }
		    $track->Title($albumTrack->Title());
		    $track->Duration($albumTrack->Duration());
		    # $track->TrackNumber($albumTrack->TrackNumber());
		    $track->TrackOrder($albumTrack->TrackOrder());
            $track->MediaType($albumTrack->MediaType());
            $track->ParentalAdvisory($albumTrack->ParentalAdvisory());

		    push @{$self->{Track}}, $track;
	    }

	    # sort them
		no warnings;
	    @{$self->{Track}} = sort {$a->DiscNumber() <=> $b->DiscNumber() || $a->DiscTrack() <=> $b->DiscTrack() }  @{$self->{Track}};
		use warnings;
    }

	return $self;
}

sub validate
{
	my $self = shift;
	my %args = @_;

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

	foreach my $track (@{$self->{Track}})
	{
		if(! $track->validate( %args ))
		{
			$valid = 0;
		}
	}
	return $valid;
}


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


	# !!! How can I tell easily whether I even need to bother to save anything here?
	# !!! For now, I will just take the brute-force approach and assume I need to recreate
	# !!! this table here...  Which is pretty ugly.
	#

	# I think I _can_ rely on each track to remember it's fate. It's one of these 3:
	# - Its a new track, so insert it.
	# - Its an old track, but was referred to in the cgi - keep it.
	# - Its an old track, and was left out of the cgi - delete it.

	# Nope - won't work.  The problem is, this list just contains the tracks that currently
	# appear in this product - There is not necessarily a relationship between the 1st track in
	# this list and the 1st track on the album, for example.

	# If there _was_ a 1-1 relationship, this would be easier.
	#
	# There is also the issue of the disc no and disc track settings, and what happens to them
	# if you de-select a track.  In the current scheme, they just go away.
	#
	# Which reminds me that we need to validate disc no and track, to at least insure that the
	# values are somewhat reasonable.

	foreach my $track (@{$self->{Track}})
	{
		$track->save();
	}
}


# This is the special sort of list accessor.
#
sub Track
{
    my ($self, $index, $methodAddressList, $newValue) = @_;

    if (0 == scalar @$methodAddressList)
    {
        if (defined $newValue)
        {
            $self->{Track}[$index] = $newValue;
        }
		return 1;
    }

	# May need to dynamically add objects to the list...
	#
	if (! defined $self->{Track}[$index])
	{
		$self->{Track}[$index] = RPS::Product::Track->new();
	}


    return $self->{Track}[$index]->_accessProperty($methodAddressList, $newValue);
}


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

	return $self->{Track};
}


###
1;#
###
