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

use lib '/app/tools/rps/lib';
use RPS::DB::Item::Artist;
use RPS::DB::Item::Genre;
use RPS::Track::TrackListSimple;
use RPS::Catalog::AlbumAdditionalArtistHash;

use lib '/app/tools/mediaserve/lib';
use MediaServe::Image::ImageFile;
use MediaServe::DB::Item::AlbumFile;

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

use constant kAlbumArtImage       => "/production/images/no_album_art.png";
use constant kAlbumThumbnailImage => "/production/images/no_album_thumbnail.png";

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

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

    my %properties;

	if ($args{_dbItem})
	{
		$self->_propertiesFromDBItem(\%properties, $args{_dbItem});
	}
	elsif ($args{albumID})
	{
		$self->_propertiesFromDB(\%properties, $args{albumID});
	}
	else
	{
		$self->_propertiesFromDefaults(\%properties);
	}

    $self->_initProperties(\%properties);
    $self->_initSubs(\%properties);

    return $self;
}


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

	my $dbItem = RPS::DB::Item::Album->Lookup(album_id => $albumID);
	$self->_propertiesFromDBItem($hrProperties, $dbItem)
        if( $dbItem );
}

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

    assert($dbItem);

    $hrProperties->{album_id}           = $dbItem->album_id;
    $hrProperties->{catalog_number}     = $dbItem->catalog_number;
    $hrProperties->{client_album_id}    = $dbItem->client_album_id;
    $hrProperties->{title}              = $dbItem->title;
    $hrProperties->{title_clean}        = $dbItem->title_clean;
    $hrProperties->{genre_primary_id}   = $dbItem->genre_primary_id;
    $hrProperties->{genre_secondary_id} = $dbItem->genre_secondary_id;
    $hrProperties->{c_line}             = $dbItem->c_line;
    $hrProperties->{p_line}             = $dbItem->p_line;
    $hrProperties->{title_version}      = $dbItem->title_version;
    $hrProperties->{label_id}           = $dbItem->label_id;
    $hrProperties->{status}             = $dbItem->status;
    $hrProperties->{inactive}           = $dbItem->inactive;
    $hrProperties->{artist_contract_id} = $dbItem->artist_contract_id;
    $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->{company_id}         = $dbItem->company_id;
    $hrProperties->{vendor_id}          = $dbItem->vendor_id;
    $hrProperties->{location_id}        = $dbItem->location_id;
    $hrProperties->{custom_1}           = $dbItem->custom_1;
    $hrProperties->{custom_2}           = $dbItem->custom_2;
    $hrProperties->{custom_3}           = $dbItem->custom_3;
    $hrProperties->{date_queued}        = $dbItem->{date_queued};
    $hrProperties->{date_delivered}     = $dbItem->{date_delivered};
}

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

    if (my $defaultLabel = RPS::DB::Item::Label->GetDefault())
    {
        $hrProperties->{label_id} = $defaultLabel->label_id;
    }
}


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

	$self->{AlbumID}            = Common::FormObject::Scalar->new(value => $props->{album_id}, readOnly => 1);
	$self->{CatalogNumber}      = Common::FormObject::Scalar::String->new(value => $props->{catalog_number}, required => 1);
	$self->{ClientAlbumID}      = Common::FormObject::Scalar::String->new(value => $props->{client_album_id});
	$self->{Title}              = Common::FormObject::Scalar::String->new(value => $props->{title}, required => 1, maxlength => 0);
	$self->{TitleClean}         = Common::FormObject::Scalar::String->new(value => $props->{title_clean}, readOnly => 1);
	$self->{GenrePrimaryID}     = Common::FormObject::Scalar->new(value => $props->{genre_primary_id});
	$self->{GenreSecondaryID}     = Common::FormObject::Scalar->new(value => $props->{genre_secondary_id});
	$self->{CLine}     = Common::FormObject::Scalar::String->new(value => $props->{c_line});
	$self->{PLine}     = Common::FormObject::Scalar::String->new(value => $props->{p_line});
	$self->{TitleVersion}       = Common::FormObject::Scalar::String->new(value => $props->{title_version});
	$self->{LabelID}            = Common::FormObject::Scalar->new(value => $props->{label_id}, required => 1);
	$self->{Status}             = Common::FormObject::Scalar->new(value => $props->{status});
	$self->{Inactive}           = Common::FormObject::Scalar->new(value => $props->{inactive});
	$self->{ArtistContractID}   = Common::FormObject::Scalar->new(value => $props->{artist_contract_id});
	$self->{CompanyID}          = Common::FormObject::Scalar::String->new(value => $props->{company_id});
	$self->{VendorID}           = Common::FormObject::Scalar::String->new(value => $props->{vendor_id});
	$self->{LocationID}         = Common::FormObject::Scalar::String->new(value => $props->{location_id});
	$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);

	$self->{ArtistID}           = Common::FormObject::Scalar->new(value => $props->{artist_id});

	# Combining Title and CatalogNumber for autocomplete
	#
	my $titleAndCatalogNumber = "(" . $props->{catalog_number} . ") " . $props->{title};
	$self->{TitleAndCatalogNumber}  = Common::FormObject::Scalar::String->new(value => $titleAndCatalogNumber);

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

	# We need to fetch the genre names
	my $genrePrimaryName;
	if ($props->{genre_primary_id})
	{
		my $genreDBItem = RPS::DB::Item::Genre->Lookup(genre_id => $props->{genre_primary_id});
		$genrePrimaryName = $genreDBItem->genre_name
            if( $genreDBItem );
	}
	$self->{GenrePrimaryName} = Common::FormObject::Scalar::String->new(value => $genrePrimaryName);

	my $genreSecondaryName;
	if ($props->{genre_secondary_id})
	{
		my $genreDBItem = RPS::DB::Item::Genre->Lookup(genre_id => $props->{genre_secondary_id});
		$genreSecondaryName = $genreDBItem->genre_name
            if( $genreDBItem );
	}
	$self->{GenreSecondaryName} = Common::FormObject::Scalar::String->new(value => $genreSecondaryName);

    $self->{AlbumParentalAdvisory} = RPS::DB::Item::Album->GetAlbumParentalAdvisory($props->{album_id});

    my ($tn, $art) = $self->_getAlbumArtURL();
    $self->{AlbumArtThumbnail} = Common::FormObject::Scalar::String->new(value => $tn );
    $self->{AlbumArt}          = Common::FormObject::Scalar::String->new(value => $art );

    # If we have a cm queued or delivery date the store it in the XML.
    $self->{DateQueued} = Common::FormObject::Scalar::String->new( value => $props->{date_queued} )
        if( $props->{date_queued} );

    $self->{DateDelivered} = Common::FormObject::Scalar::String->new( value => $props->{date_delivered} )
        if( $props->{date_delivered} );


	$self->{AdditionalArtistList} = RPS::Catalog::AlbumAdditionalArtistHash->new( albumID => $props->{album_id} );
}


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

	# subclasses
	#
	if($self->loadSubs())
	{
		$self->{TrackList} = RPS::Track::TrackListSimple->new(albumID => $props->{album_id}, readOnly => 1);
	}
}




# album fields
#

sub TrackList
{
	my ($self) = @_;
	return $self->{TrackList};
}


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

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

	if (! $self->ArtistName())
	{
		$self->{ArtistName}->setError(Common::FormObject::kErrFieldBlank);
		$valid = 0;
	}
	else
	{
		# check for duplicate artist name:
		#   we're not actually going to flag an error here,
		#   just use the existing artist_id if it exists.
		#
		if(! $self->ArtistID)
		{
			my $tmpArtist = RPS::DB::Item::Artist->Lookup(name => $self->ArtistName());
			if(defined $tmpArtist && lc($tmpArtist->name) eq lc($self->ArtistName()))
			{
				$self->ArtistID($tmpArtist->artist_id);
			}
		}
	}


    $valid = $self->_validateMetadata( %args )
        if( $valid && %args );

	$valid = 0
	    unless($self->{AdditionalArtistList}->validate( %args ));

    return $valid;
}

sub _validateMetadata {
    my ($self, %args) = @_;
    my $validator = $args{metadataValidator};

    my $currentData = RPS::DB::Item::Album->Lookup(album_id => $self->AlbumID)
        if( $self->AlbumID );

    my %scalar_rule_map = (
        CatalogNumber     => { legacy   => 'catalog_number',
                               validate => 'catalog-no' },
        ClientAlbumID     => { legacy   => 'client_album_id',
                               validate => 'client-album-id' },
        Title             => { legacy   => 'title',
                               validate => 'album-title' },
        ArtistName        => undef,
        GenrePrimaryID    => undef,
        GenreSecondaryID  => undef,
        CLine             => { legacy   => 'c_line',
                               validate => 'c-line' },
        PLine             => { legacy   => 'p_line',
                               validate => 'p-line' },
        TitleVersion      => undef,
        LabelID           => undef,
        Status            => undef,
        Inactive          => undef,
        ArtistContractID  => undef,
        Custom1           => { legacy   => 'custom_1',
                               validate => 'album-custom-1' },
        Custom2           => { legacy   => 'custom_2',
                               validate => 'album-custom-2' },
        Custom3           => { legacy   => 'custom_3',
                               validate => 'album-custom-3' },
    );

	my $valid =  $self->SUPER::_validateMetadata( fieldMap          => \%scalar_rule_map,
                                                  currentData       => $currentData,
                                                  metadataValidator => $validator );
	unless( $validator ) {
		Common::Log::Debug( "No validator passed to " . ref($self) . "::_validateMetadata, skipping validation!!!!!" );
		return $valid;
	}

    # If the genre object don't exist then create them.
    $self->{GenrePrimaryName}   = Common::FormObject::Scalar::String->new()
        unless( $self->{GenrePrimaryName} );
    $self->{GenreSecondaryName} = Common::FormObject::Scalar::String->new()
        unless( $self->{GenreSecondaryName} );

    my $primaryResult   = $validator->validate_item( "primary-genre", $self->{GenrePrimaryName}->access(), undef, %$currentData );
    my $secondaryResult = $validator->validate_item( "secondary-genre", $self->{GenreSecondaryName}->access(), undef, %$currentData );

    if( $primaryResult ) {
        $self->{GenrePrimaryName}->setError( $primaryResult->{code} );
        $self->{GenrePrimaryName}->setErrorString( $primaryResult->{message} );
        $valid = 0;
    }

    if( $secondaryResult ) {
        $self->{GenreSecondaryName}->setError( $secondaryResult->{code} );
        $self->{GenreSecondaryName}->setErrorString( $secondaryResult->{message} );
        $valid = 0;
    }

    return $valid;
}


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

	# -------------------------------
	# Save or create the artist
	# -------------------------------
	#
	my $artistObj;
	if($self->ArtistID())
	{
		$artistObj = RPS::DB::Item::Artist->Lookup(artist_id => $self->ArtistID());

		# changing the artist? see if it's a different artist
		if($self->ArtistName())
		{
			if(lc($artistObj->name) ne lc($self->ArtistName()))
			{
				$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();

            # If the name is the same, but different case
            } elsif( $artistObj->name ne $self->ArtistName() ) {
                $artistObj->name( $self->ArtistName );
                $artistObj->save();
            }
		}
	}
	elsif($self->ArtistName())
	{
		# Create a new artist.
		$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();
	}


	# -------------------------------
	# Save myself
	# -------------------------------
	#
	my $albumDBObj;
	if ($self->AlbumID())
	{
		$albumDBObj = RPS::DB::Item::Album->Lookup(album_id => $self->AlbumID());
	}
	else
	{
		$albumDBObj = RPS::DB::Item::Album->Create();
	}

	$albumDBObj->catalog_number($self->CatalogNumber());
	$albumDBObj->client_album_id($self->ClientAlbumID());
	$albumDBObj->title($self->Title());
	$albumDBObj->genre_primary_id($self->GenrePrimaryID());
	$albumDBObj->genre_secondary_id($self->GenreSecondaryID());
	$albumDBObj->c_line($self->CLine());
	$albumDBObj->p_line($self->PLine());
	$albumDBObj->title_version($self->TitleVersion());
	$albumDBObj->label_id($self->LabelID());
	$albumDBObj->status($self->Status());
	$albumDBObj->inactive($self->Inactive());
	$albumDBObj->artist_contract_id($self->ArtistContractID());
	$albumDBObj->company_id($self->CompanyID);
	$albumDBObj->vendor_id($self->VendorID);
	$albumDBObj->location_id($self->LocationID);
	$albumDBObj->custom_1($self->Custom1);
	$albumDBObj->custom_2($self->Custom2);
	$albumDBObj->custom_3($self->Custom3);

	$albumDBObj->artist_id($artistObj->artist_id);

    # Derrive the clean title from title
    #
    $albumDBObj->title_clean(Common::Util::clean_name_catalog($self->Title()));

	$albumDBObj->save();

	$self->{AdditionalArtistList}->save( albumID => $albumDBObj->album_id() );

	# reload object
	#
    $self->_init(_dbItem => $albumDBObj);
}

sub _getAlbumArtURL
{
	my ($self, %args) = @_;
    my ( $thumbnail, $full ) = ( kAlbumThumbnailImage, kAlbumArtImage );

    # Lookup the thumbnail image url
    $thumbnail = MediaServe::DB::Item::AlbumFile->LookupByType(
                            album_id => $self->AlbumID,
                            type     => 'thumbnail' );
    my $thumbnail_image = MediaServe::Image::ImageFile->new(
                        clientID => Common::RSApp::GetClientID(),
                        id       => $thumbnail->media_file_id )
        if( $thumbnail );
    $thumbnail = $thumbnail_image->url() if( $thumbnail_image );


    # Lookup the full image url
    $full = MediaServe::DB::Item::AlbumFile->LookupByType(
                            album_id => $self->AlbumID,
                            type     => 'large' );
    my $full_image = MediaServe::Image::ImageFile->new(
                        clientID => Common::RSApp::GetClientID(),
                        id       => $full->media_file_id )
        if( $full );
    $full = $full_image->url() if( $full_image );


    return ( $thumbnail, $full );
}

1;
