#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
#------------------------------------------------------------
package RPS::DB::Item::Track;
use strict;
use warnings;
use lib '/app/tools/common/lib';
use Common::DB::Item;
use Common::DB::ItemCollection;
use Common::Assert;

use lib '/app/tools/rps/lib';
use RPS::DB::Item::TrackLicense;
#use RPS::DB::Item::Product;
use base 'Common::DB::Item';

use constant kTable => 'track';
use constant kDB => Common::DB::Item::kClientDB();


sub Search
{
	my ($class, $searchTerm) = @_;

	my $where;

	if($searchTerm)
	{
		$where = "WHERE ". $class->SearchSyntax(field => "track.title", value => $searchTerm)
			. " OR ". $class->SearchSyntax(field => "isrc", value => $searchTerm)
			. " OR ". $class->SearchSyntax(field => "artist.name", value => $searchTerm);
	}
	else
	{
		die "no valid param passed to track search";
	}

	my $sql = "SELECT track.* FROM track LEFT JOIN artist ON artist.artist_id=track.artist_id LEFT JOIN master ON ( track.master_id = master.master_id ) $where GROUP BY track_id ORDER BY track.title";

    return $class->GetAll($sql);
}


sub SearchByTitle
{
    my ($class, %args) = @_;

	 	my $dbo = Common::RSApp::GetClientDB();

    my $searchTerm = $args{searchTerm};
    my $limit = $args{limit};
    my $albumID = $args{albumID};



    my $where;

    if ($searchTerm)
    {
        $where = "(".$class->SUPER::SearchSyntax(field => 'title', value => $searchTerm).")";

		    if ($albumID)
		    {
		        $where .= " AND album_id = " . $dbo->DBQuote($albumID);
		    }

    }

    my $sql = 'SELECT * FROM ' . kTable;
    if ($where)
    {
        $sql .= " WHERE $where";
    }

    $sql .= ' ORDER BY title';

    if ($limit)
    {
        $sql .= " LIMIT $limit";
    }

	  print STDERR "---------- $sql ------------\n";

    return $class->SUPER::GetAll($sql);
}


sub hasDuplicateISRC
{
	my %args = @_;
	my $album_id = $args{album_id};
	my $track_id = $args{track_id};
	my $master_id = $args{master_id};
	my $isrc = $args{isrc};
	my $media_type = $args{media_type};

	my $dbo = Common::RSApp::GetClientDB();

	assert($album_id, "album id required");
	assert($isrc, "ISRC required");

	my $sql = "SELECT count(*) FROM track INNER JOIN master USING (master_id) ";
	my $where = " WHERE album_id = " . $dbo->DBQuote($album_id) .
		          " AND media_type = " . $dbo->DBQuote($media_type);

    if( $track_id ) {
		$where .= " AND track_id <> " . $dbo->DBQuote($track_id);
	} elsif( $master_id ) {
		$where .= " AND master_id <> " . $dbo->DBQuote($master_id);
	}

	$where .= " AND isrc = " . $dbo->DBQuote($isrc);
	$sql .= $where;

	Common::Log::Debug( "QUERY: $sql ");
	my $sth = $dbo->DoCmd($sql);
	my ($count) = $sth->fetchrow_array();

	return $count && $count > 0;
}



# This currently knows nothing about 'bonus tracks'...
#
sub GetTracksByAlbumID
{
	my ($class, $albumID) = @_;

	my $sql = "SELECT * FROM track WHERE album_id=$albumID ORDER BY track_order, track_id DESC";
    return $class->GetAll($sql);
}

# This currently knows nothing about 'bonus tracks'...
#
sub GetTracksByAlbumIDFiltered
{
	my ($class, $albumID, $type, %args) = @_;
	my $dbo = Common::RSApp::GetClientDB();

	return $class->GetTracksByAlbumID( $albumID )
	    unless( %args );

	my $licenseFilter = "";
	my $productSelect = "";

    my $exemptField;
    my $licenseID;
    my $licenseTable;
    
    if ( defined($type) && $type eq 'CA')
    {
        $exemptField = 'ca_mechanical_exempt';
        $licenseID = 'ca_track_license_id';
        $licenseTable = 'ca_track_license';
    }
    else
    {
        $exemptField = 'mechanical_exempt';
        $licenseID = 'track_license_id';
        $licenseTable = 'track_license';
    }

    # For the purposes of this filter, we do not want to count ringtone licenses as licenses.  
    # So, here's some slightly ugly code to accomplish that.

	if( $args{filter} && $args{filter}->{licenseFilter} ) {
		$licenseFilter = " AND $exemptField <> 1 AND $licenseID IS NOT NULL AND $licenseTable.type != " . RPS::DB::Item::TrackLicense::kRingtone . " "
			if( $args{filter}->{licenseFilter} =~ /^licensed$/ );

		$licenseFilter = " AND $exemptField <>  1 AND ($licenseID IS NULL OR ($licenseID IS NOT NULL AND $licenseTable.type = " . RPS::DB::Item::TrackLicense::kRingtone . ")) "
			if( $args{filter}->{licenseFilter} =~ /^unlicensed$/ );
	}

	if( $args{filter} && $args{filter}->{productFilter} ) {
		$productSelect  = ", COUNT( ";
		
		$productSelect .= "IF( ";		
		
		# We only want to include licenses for All Products if we are not filtering by Ringtone.
		#
		if ($args{filter}->{productFilter} != 15)
		{
		    $productSelect .= "( $licenseID AND product_type_id IS NULL ) OR ";
		}

		$productSelect .= "product_type_id =  ";                   
                              
		$productSelect .= $dbo->DBQuote($args{filter}->{productFilter});
		
		$productSelect .= ', 1, \N ) ) as "has_product" ';
	}

	my $sql = "SELECT track.* $productSelect " .
	          "FROM track " .
			      "LEFT JOIN $licenseTable USING (track_id) " .
			  "WHERE " .
                  "album_id = " . $dbo->DBQuote($albumID) .
                  $licenseFilter .
			  " GROUP BY track.track_id " .
			  "ORDER BY track_order, track_id DESC";


	if( $args{filter} && $args{filter}->{productFilter} ) {
		$sql = "SELECT * FROM ( $sql ) as subq WHERE has_product ";
	}

	Common::Log::Debug( "QUERY: $sql ");
	return $class->GetAll($sql);
}

sub GetTracksByMasterID
{
	my ($class, $masterID) = @_;
    assert($masterID, "Missing master_id");

	my $sql = "SELECT * FROM track WHERE master_id=$masterID ORDER BY track_id";
    return $class->GetAll($sql);
}

sub GetTrackCountByAlbumID
{
	my ($class, $albumID) = @_;
    assert($albumID, "Missing album_id");

	my $dbo = Common::RSApp::GetClientDB();

	my $sql = "SELECT count(*) FROM track WHERE album_id=$albumID";

	my $sth = $dbo->DoCmd($sql);

	my $aref = $sth->fetchrow() if($sth);

	return (defined $aref) ? $aref : 0;
}



# pass the trackDBItem that just had its track_number changed
#
# It will grab all tracks for this album and renumber them
#
sub RenumberTracks
{
	my ($class, $trackDBObj) = @_;

	# get all tracks for this album
	#
	my $coll = RPS::DB::Item::Track->GetTracksByAlbumID($trackDBObj->album_id());
	my @trackList = ();
	while($coll->hasNext())
	{
		push @trackList, $coll->next();
	}

	my $nextTrackNumber = 1;
	foreach my $track (sort {$a->track_order() <=> $b->track_order()} @trackList)
	{
		# skip the track we just updated
		#
		if($track->track_id == $trackDBObj->track_id())
		{
			next;
		}

		# if(this track does not match the next track_number)
		# OR
		# if(the next track_number is the one we just updated)
		#
		# Basically, if something needs to be resolved...
		#
		if($track->track_order() != $nextTrackNumber || $nextTrackNumber == $trackDBObj->track_order())
		{
			# if this track happens to have the same track_number as the one
			# we just updated, then this one gets bumped, increment to the
			# next track_number and update
			#
			if($nextTrackNumber == $trackDBObj->track_order())
			{
				$nextTrackNumber++;
			}

			$track->track_order($nextTrackNumber);
			$track->save();
			$nextTrackNumber++;
		}
		else
		{
			# everything's cool, just move on to the next one
			#
			$nextTrackNumber++;
			next;
		}
	}
}


sub GetTableStatus
{
	my ($class) = @_;
  my $dbo = Common::RSApp::GetClientDB();

	my $sql = "SHOW TABLE STATUS LIKE '" . kTable . "'";

  my $sth = $dbo->DoCmd( $sql );

  my $result;
  my @results;
  while ($result = $sth->fetchrow_arrayref) {
  	push @results, @{$result};
  }
  return @results;
}


1;
