#------------------------------------------------------------
# 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};

    my $page     = $args{page};
    my $pageSize = $args{pageSize};
    my $filterTrackList = $args{filterTrackList};

    #	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, page => $page, pageSize => $pageSize, filterTrackList => $filterTrackList );
        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;

        $self->{Pagination} = $albumTrackList->getPagination();
    }

    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;    #
###
