#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
#------------------------------------------------------------
package Distribution::Catalog::Track;
use strict;
use warnings;

use Data::Dumper;

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

use lib '/app/tools/distribution/lib';
use Distribution::Catalog::Genre;
use Distribution::Catalog::AdditionalArtist;

use base 'Common::XMLObject';

# This hash defines what tags/keys we expect.
#
use constant kAttribute             => 'a';
use constant kTag                   => 't';
use constant kGenreObject           => 'g';
use constant kAdditionalArtistsList => 'z';

# !!! Going to need to extend this to include the paths
# to the image and audio files.
#
my %gConfig = (
    'is-explicit'        => kTag,
    'sell-unbundled'     => kTag,
    'title'              => kTag,
    'isrc'               => kTag,
    'sequence'           => kTag,
    'wholesale-price'    => kTag,
    'length'             => kTag,
    'genre'              => kTag,
    'label'              => kTag,
    'cline'              => kTag,
    'pline'              => kTag,
    'display-artist'     => kTag,
    'apple-track-id'     => kTag,
    'album-only'         => kTag,
    'composer'           => kTag,
    'audio-path-linux'   => kTag,
    'audio-path-windows' => kTag,
    'genre-object'       => kGenreObject,
    'additional-artists' => kAdditionalArtistsList,
);

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

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

    $self->{_serviceID} = $args{serviceID};

    # So, we'll keep this _very_ simple for now.
    # I don't think we'll even need an XML based constructor here.
    # We'll just take in a hash table reference, and that'll be it.
    #
    my $hashRef = $args{hash};
    assert( $hashRef, "ERROR - Missing 'hash' argument" );

    # It would be quicker, I suppose, to just hang onto the hash reference
    # and output that directly...  But, I'd like to give us the chance to
    # do some sort of validation.  And some of these keys need to become 'attributes'.
    # Plus, hanging onto references that get passed around is a good way to leak memory.
    #
    foreach my $expectedKey ( keys %gConfig ) {
        if ( $expectedKey eq "composer" && !( exists $hashRef->{$expectedKey} ) ) {
            ## TODO: create a stub?
            next;
        }

        #assert(exists $hashRef->{$expectedKey}, "ERROR - hash missing key $expectedKey");
        if ( kAttribute eq $gConfig{$expectedKey} ) {
            $self->setXMLParam( $expectedKey, Common::UTF8::Encode( $hashRef->{$expectedKey} ) );
        } elsif ( kTag eq $gConfig{$expectedKey} ) {
            $self->{$expectedKey} = Common::UTF8::Encode( $hashRef->{$expectedKey} );
        } elsif ( kAdditionalArtistsList eq $gConfig{$expectedKey} && $hashRef->{$expectedKey} ) {
            $self->{'additional-artists'} = [];

            my $artistList;
            if ( ref( $hashRef->{$expectedKey} ) eq 'ARRAY' ) {
                $artistList = $hashRef->{$expectedKey} || [];
            } else {
                $artistList = [ $hashRef->{$expectedKey} ];
            }

            foreach my $artistHash (@$artistList) {

                # Instantiate a Volume, save it here.
                #
                my $artist = Distribution::Catalog::AdditionalArtist->new( hash => $artistHash );
                push @{ $self->{'additional-artists'} }, $artist;
            }
        } elsif ( kGenreObject eq $gConfig{$expectedKey} ) {
        }
    }

    my $genre     = new Distribution::Catalog::Genre( genreName => $self->{genre},             serviceID => $self->{_serviceID} );
    my $sec_genre = new Distribution::Catalog::Genre( genreName => $self->{'genre-secondary'}, serviceID => $self->{_serviceID} );

    $self->{'genre-object'}           = $genre;
    $self->{'genre-secondary-object'} = $sec_genre;

    $self->{composer} = undef if ( ref( $self->{composer} ) );

    return $self;
}

sub asHashRef {
    my $self = shift;
    my $result;
    my %data;
    my $dest_key;

    foreach my $key ( keys( %{$self} ) ) {
        next if ( $key =~ /^_/ );

        $dest_key = $key;
        $dest_key =~ s/-/_/g;

        if ( ref( $self->{$key} ) && ref( $self->{$key} ) eq 'HASH' ) {
            %data = %{ $self->{$key} };
            $result->{$dest_key} = \%data;
        } elsif ( ref( $self->{$key} ) && ref( $self->{$key} ) ne 'ARRAY' ) {
            $result->{$dest_key} = $self->{$key}->asHashRef();
        } else {
            $result->{$dest_key} = $self->{$key};
        }
    }

    if ( $self->{'additional-artists'} ) {
        $result->{'additional_artists'} = [];
        foreach my $artist ( @{ $self->{'additional-artists'} } ) {
            push( @{ $result->{'additional_artists'} }, $artist->asHashRef() );
        }
    }

    return $result;
}

# Set sequence numbers for vendors that don't have volume numbers
sub setSequence {
    my $self          = shift;
    my $maxTrack      = shift;
    my $volume        = shift || 1;
    my $startingTrack = 0;

    foreach my $vol ( keys(%$maxTrack) ) {
        next unless ( $vol < $volume );
        $startingTrack += $maxTrack->{$vol};
    }

    Common::Log::Debug("Non-Volume Sequence: $startingTrack + $self->{sequence}");
    $self->{sequence_no_volume} = $startingTrack + $self->{sequence};
}

1;
