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

use Data::Dumper;

use lib '/app/tools/appuser/lib';
use AppUser::User::User;

use lib '/app/tools/common/lib';
use Common::RSApp;
use Common::Assert;
use Common::Permission;
use Common::Log;

use lib '/app/tools/rps/lib';
use RPS::DB::Item::Track;
use RPS::DB::Item::MediaType;
use RPS::DB::Item::Artist;

use lib '/app/tools/mediaserve/lib';
use MediaServe::DB::Item::ProductTrackFile;

use RPS::Master::Master;
use RPS::Catalog::Album;

use Common::FormObject;
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{trackID} ) {
        $self->_propertiesFromDB( \%properties, $args{trackID} );
    } elsif ( $args{albumID} ) {
        $self->_propertiesFromDefaults( \%properties, $args{albumID} );
    }

    $self->_initProperties( \%properties, %args );

    return $self;
}

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

    my $dbItem = RPS::DB::Item::Track->Lookup( track_id => $trackID );

    $self->_propertiesFromDBItem( $hrProperties, $dbItem );
}

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

    $hrProperties->{track_id}             = $dbItem->track_id;
    $hrProperties->{album_id}             = $dbItem->album_id;
    $hrProperties->{track_order}          = $dbItem->track_order;
    $hrProperties->{title}                = $dbItem->title;
    $hrProperties->{title_clean}          = $dbItem->title_clean;
    $hrProperties->{client_track_id}      = $dbItem->client_track_id;
    $hrProperties->{track_order}          = $dbItem->track_order;
    $hrProperties->{master_id}            = $dbItem->master_id;
    $hrProperties->{mechanical_exempt}    = $dbItem->mechanical_exempt;
    $hrProperties->{ca_mechanical_exempt} = $dbItem->ca_mechanical_exempt;
    $hrProperties->{parental_advisory}    = $dbItem->parental_advisory;

    $hrProperties->{date_created}  = $dbItem->date_created;
    $hrProperties->{date_modified} = $dbItem->date_modified;
    $hrProperties->{created_by}    = $dbItem->created_by;
    $hrProperties->{modified_by}   = $dbItem->modified_by;
    $hrProperties->{artist_id}     = $dbItem->artist_id;
    $hrProperties->{media_type}    = $dbItem->media_type;

    $hrProperties->{genre_name} = $dbItem->genre_name;
    $hrProperties->{custom_1}   = $dbItem->custom_1;
    $hrProperties->{custom_2}   = $dbItem->custom_2;
    $hrProperties->{custom_3}   = $dbItem->custom_3;

}

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

    $self->{TrackID} = Common::FormObject::Scalar->new( value => $props->{track_id}, readOnly => 1 );
    $self->{AlbumID} = Common::FormObject::Scalar->new( value => $props->{album_id} );    # !!! had been required
    $self->{Title}         = Common::FormObject::Scalar::String->new( value => $props->{title}, required => 1 );
    $self->{TitleClean}    = Common::FormObject::Scalar::String->new( value => $props->{title_clean} );
    $self->{ClientTrackID} = Common::FormObject::Scalar::String->new( value => $props->{client_track_id} );
    $self->{TrackOrder} = Common::FormObject::Scalar->new( value => $props->{track_order} );
    $self->{MasterID}   = Common::FormObject::Scalar->new( value => $props->{master_id} );
    $self->{MechanicalExempt}   = Common::FormObject::Scalar::Boolean->new( value => $props->{mechanical_exempt} );
    $self->{CAMechanicalExempt} = Common::FormObject::Scalar::Boolean->new( value => $props->{ca_mechanical_exempt} );
    $self->{ParentalAdvisory} = Common::FormObject::Scalar::String->new( value => $props->{parental_advisory} );
    $self->{GenreName}        = Common::FormObject::Scalar::String->new( value => $props->{genre_name} );
    $self->{MediaType} = Common::FormObject::Scalar->new( value => $props->{media_type} );
    $self->{Custom1} = Common::FormObject::Scalar::String->new( value => $props->{custom_1} );
    $self->{Custom2} = Common::FormObject::Scalar::String->new( value => $props->{custom_2} );
    $self->{Custom3} = Common::FormObject::Scalar::String->new( value => $props->{custom_3} );

    $self->{CreatedDate}  = Common::FormObject::Scalar::DateTime->new( value => $props->{date_created},  readOnly => 1 );
    $self->{ModifiedDate} = Common::FormObject::Scalar::DateTime->new( value => $props->{date_modified}, readOnly => 1 );
    $self->{CreatedBy}    = Common::FormObject::Scalar::UserName->new( value => $props->{created_by},    readOnly => 1 );
    $self->{ModifiedBy}   = Common::FormObject::Scalar::UserName->new( value => $props->{modified_by},   readOnly => 1 );

    # We need to fetch the artist name, given the artist id.
    #
    my $artistName;
    if ( $props->{artist_id} ) {
        my $artistDBItem = RPS::DB::Item::Artist->Lookup( artist_id => $props->{artist_id} );
        $artistName = $artistDBItem->name if ($artistDBItem);
    }
    $self->{ArtistName} = Common::FormObject::Scalar::String->new( value => $artistName, required => 1 );
    $self->{ArtistID} = Common::FormObject::Scalar->new( value => $props->{artist_id} );

    # this is something we only do for TrackSimple and not
    # for any of its derived classes.
    # !!! Huh? What?  Why is this here?
    #
    if ( ref($self) eq 'RPS::Track::TrackSimple' ) {
        my $seconds = 0;
        if ( $props->{master_id} ) {
            my $master = RPS::DB::Item::Master->Lookup( master_id => $props->{master_id} );
            $seconds = $master->duration if ($master);
        }
        $self->{Duration} = Common::FormObject::Scalar->new( value => Common::FormObject::_secondsToMMSS($seconds) );
    }

    $self->{AudioPreviewURL} = $self->_getTrackAudioURL();
}

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

    my $album = RPS::Catalog::Album->new( albumID => $albumID, loadSubs => 0 );
    assert($album);

    # let's figure out the max track number
    #
    my $nextTrackNum = RPS::DB::Item::Track->GetTrackCountByAlbumID($albumID);
    $nextTrackNum++;

    $hrProperties->{album_id}    = $albumID;
    $hrProperties->{track_order} = $nextTrackNum;

    # We'll get the artist id from the album as well.
    #
    $hrProperties->{artist_id} = $album->ArtistID();

    $hrProperties->{media_type}        = RPS::DB::Item::MediaType::kMediaTypeAudio;
    $hrProperties->{parental_advisory} = 'N';
}

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

    my $dbObj = $self->_saveTrack();
    $self->_init( _dbItem => $dbObj );
}

# jpk - broke this out into an 'inner' method to make it easier to subclass
#
sub _saveTrack {
    my ($self) = @_;

    # !!! This assumes AlbumID gets set before we get here.
    #
    # Get the album data, so we can set the artist name if necessary.
    #
    my $artistID;
    my $albumData = RPS::DB::Item::Album->Lookup( album_id => $self->AlbumID() );
    if ($albumData) {
        $artistID = $albumData->artist_id;
    }

    # -------------------------------
    # Handle the Track artist here
    # -------------------------------

    # Translate artist name to artist id, creating the artist if necessary.
    # Use the $artistObj to set artist_id in the dbItem.
    #
    if ( $self->ArtistName() ) {
        my $artistObj;
        $artistObj = RPS::DB::Item::Artist->Lookup( name => $self->ArtistName() );
        if ( !defined $artistObj ) {
            $artistObj = RPS::DB::Item::Artist->Create( name => $self->ArtistName() );
            ## only good place to set the clean name for artists atm
            $artistObj->name_clean( Common::Util::clean_name_catalog( $self->ArtistName() ) );
            $artistObj->save();
        }

        $artistID = $artistObj->artist_id;
    }

    my $masterID = $self->MasterID();

    # -------------------------------
    # Save myself (Track)
    # -------------------------------
    #
    my $trackDBObj;
    if ( $self->TrackID() ) {
        $trackDBObj = RPS::DB::Item::Track->Lookup( track_id => $self->TrackID() );
    } else {
        $trackDBObj = RPS::DB::Item::Track->Create();
    }

    # !!! This needs to change.
    # Track order is provided 'externally'.
    # We are using a scalar reference so that we can increment it for the next guy.
    #
    #	$trackDBObj->track_order($$trackOrderRef++);
    $trackDBObj->track_order( $self->TrackOrder() );

    $trackDBObj->album_id( $self->AlbumID() );
    $trackDBObj->title( $self->Title() );
    $trackDBObj->mechanical_exempt( $self->MechanicalExempt() );
    $trackDBObj->ca_mechanical_exempt( $self->CAMechanicalExempt() );

    # !!! These fields have not been added to the form, yet.
    #
    $trackDBObj->client_track_id( $self->ClientTrackID() );
    $trackDBObj->genre_name( $self->GenreName() );
    $trackDBObj->media_type( $self->MediaType() );
    $trackDBObj->parental_advisory( $self->ParentalAdvisory() );
    $trackDBObj->custom_1( $self->Custom1() );
    $trackDBObj->custom_2( $self->Custom2() );
    $trackDBObj->custom_3( $self->Custom3() );

    # foreign keys
    #
    $trackDBObj->master_id($masterID);
    $trackDBObj->artist_id($artistID);

    # Derrive clean names
    #
    $trackDBObj->title_clean( Common::Util::clean_name_catalog( $self->Title() ) );

    $trackDBObj->save();

    return $trackDBObj;

}

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

    my $audio = MediaServe::DB::Item::ProductTrackFile->LookupByTrackID( track_id => $self->TrackID );

    #Common::Log::Debug("-------- the 'audio' obj: " . Dumper($audio));
    my $audio_file = MediaServe::Audio::AudioFile->new(
        clientID => Common::RSApp::GetClientID(),
        id       => $audio->media_file_id
    ) if ($audio);

    #Common::Log::Debug("-------- the 'audio_file' obj: " . Dumper($audio_file));
    return $audio_file ? $audio_file->url() : undef;
}
###
1;    # Play nicely.
###
