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

use strict;
use warnings;
use Carp;

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

use lib '/app/tools/rps/lib';
use Common::FormObject;
use RPS::Product::Product;
use RPS::DB::Item::Product;
use RPS::DB::Item::Track;

use Data::Dumper;

use base 'Common::FormObject';

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

    my $albumID           = $args{albumID};
    my $digitalTracksOnly = $args{digitalTracksOnly};

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

    $self->{Product} = [];
    return $self if !defined $albumID;

    if ($digitalTracksOnly) {
        my $tracks = RPS::DB::Item::Track->GetTracksByAlbumID($albumID);

        while ( $tracks->hasNext() ) {
            my $track = $tracks->next();

            my $products = RPS::DB::Item::Product->GetAllDigitalTrackProducts( $track->track_id );

            while ( $products->hasNext() ) {
                my $productData = $products->next();

                push @{ $self->{TrackProduct} }, $self->_getProductXML($productData);
            }
        }
    } else {
        my $products = RPS::DB::Item::Product->GetProductsByAlbumID($albumID);

        while ( $products->hasNext() ) {
            my $productData = $products->next();

            # we don't want the track products in the xml.
            # Note: we can always add a flag parameter to this function to control this behavior.
            #
            if ( RPS::DB::Item::Product::kProductTypeDigitalTrack == $productData->product_type_id ) {
                next;
            }

            push @{ $self->{Product} }, $self->_getProductXML($productData);
        }
    }

    return $self;
}

sub _getProductXML {
    my ( $self, $productData ) = @_;
    return RPS::Product::Product->new( _dbItem => $productData, loadSubs => $self->loadSubs() );
}

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

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

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

    # Give my contained XMLObjects a chance to validate as well.
    #
    foreach my $product ( @{ $self->{Product} } ) {

        # JPK - It _is_ possible for there to be undef entries in the list.
        #  This is due to the way we allow dynamic addition of Products in the list
        #  based on CGI parameters.
        #
        $valid = $product->validate(@_) if defined $product;
    }

    return $valid;
}

sub validateDigitalProduct {
    my $self = shift;
    my $valid;

    foreach my $product ( @{ $self->{Product} } ) {
        if ( $product->ProductTypeID == RPS::DB::Item::Product::kProductTypeDigital ) {
            $valid = $product->validate(@_) if ( defined $product );
        }
    }

    return $valid;
}

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

    # We'll dynamically extend the list during an assignment.
    #
    if (  !defined $self->{Product}[$index]
        && defined $newValue ) {
        $self->{Product}[$index] = RPS::Product::Product->new();
    }

    if ( !$methodAddress ) {
        if ( defined $newValue ) {
            $self->{Product}[$index] = $newValue;
            return 1;
        }
        return $self->{Product}[$index];
    }

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

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

    foreach my $product ( @{ $self->{Product} } ) {
        $product->save();
    }
}

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

    return $self->{Product};
}

1;
