using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Threading;
using MediaAssistant.DAL;
using MediaAssistant.Helper;
using MediaAssistant.MusicDJ;
namespace MediaAssistant.Management
{
[Export]
public class SmartDJProbabilityCalculationService:BackgroundScanner
{
public SmartShuffleDJ SmartShuffleDj { get; private set; }
public Music CurrentMusic { get; set; }
public SmartDJProbabilityCalculationService()
{
Name = "Smart DJ Service";
}
protected override void TryToScan()
{
CancelIfRequested();
if (PauseIfRequested())
{
return;
}
if (CurrentMusic == null)
return;
Calculate();
CancelIfRequested();
}
private void CancelIfRequested()
{
if(CancelPendingJobRequested)
{
CurrentMusic = null;
CancelPendingJobRequested = false;
}
}
public void StartCalculation(Music playingMusic, SmartShuffleDJ smartShuffleDj)
{
if(CurrentMusic!=null)
CancelPendingJob();
SmartShuffleDj = smartShuffleDj;
CurrentMusic = playingMusic;
}
private void Calculate()
{
var grandTotal = 0d;
var genreDictionary = new Dictionary<string, double>();
var albumDictionary = new Dictionary<string, double>();
var artistDictionary = new Dictionary<string, double>();
var composerDictionary = new Dictionary<string, double>();
foreach (var music in SmartShuffleDj.NextMusics)
{
music.TotalScore = DatabaseManager.Instance.GetScore(music, DataSource.Value.SelectedProfile);
if (IsInfluencedGenre(music.Genre, CurrentMusic) || IsInfluencedGenre(music.Genre, SmartShuffleDj.InitializedMusic))
{
string value = music.Genre;
var averageScore = genreDictionary.ContainsKey(value) ? genreDictionary[value] : GetAverageScore(SmartShuffleDj.AllMusics.Where(m => m.Genre == value), genreDictionary, value, DataSource.Value.SelectedProfile);
music.TotalScore += RegistryHelper.GenrePreferance * averageScore;
}
if (PauseIfRequested()) return;
if (IsInfluencedAlbum(music.Album, CurrentMusic) || IsInfluencedAlbum(music.Album, SmartShuffleDj.InitializedMusic))
{
var value = music.Album;
var averageScore = albumDictionary.ContainsKey(value) ? albumDictionary[value] : GetAverageScore(SmartShuffleDj.AllMusics.Where(m => m.Album == value), albumDictionary, value, DataSource.Value.SelectedProfile);
music.TotalScore += RegistryHelper.AlbumPreferance * averageScore;
}
if (PauseIfRequested()) return;
if (IsInfluencedArtist(music.Artist, CurrentMusic) || IsInfluencedArtist(music.Artist, SmartShuffleDj.InitializedMusic))
{
var value = music.Artist;
var averageScore = artistDictionary.ContainsKey(value) ? artistDictionary[value] : GetAverageScore(SmartShuffleDj.AllMusics.Where(m => m.Artist == value), artistDictionary, value, DataSource.Value.SelectedProfile);
music.TotalScore += RegistryHelper.ArtistPreferance * averageScore;
}
if (PauseIfRequested()) return;
if (IsInfluencedComposer(music.Composer, CurrentMusic) || IsInfluencedComposer(music.Composer, SmartShuffleDj.InitializedMusic))
{
var value = music.Composer;
var averageScore = composerDictionary.ContainsKey(value) ? composerDictionary[value] : GetAverageScore(SmartShuffleDj.AllMusics.Where(m => m.Composer == value), composerDictionary, value, DataSource.Value.SelectedProfile);
music.TotalScore += RegistryHelper.ComposerPreferance * averageScore;
}
grandTotal += music.TotalScore;
if (PauseIfRequested()) return;
}
foreach (var music in SmartShuffleDj.NextMusics)
{
music.Probability = music.TotalScore / grandTotal;
if (PauseIfRequested()) return;
}
CurrentMusic = null;
}
protected override bool PauseIfRequested()
{
return CancelPendingJobRequested || base.PauseIfRequested();
}
public static double GetAverageScore(IEnumerable<Music> influencedMusic, IDictionary<string, double> scoreDictionary, string value, Profile selectedProfile)
{
var averageScore = influencedMusic.Count() > 0 ? influencedMusic.Average(m => DatabaseManager.Instance.GetScore(m, selectedProfile)) : 0;
scoreDictionary.Add(value, averageScore);
return averageScore;
}
public static bool IsInfluencedGenre(string genre, Music influencingMusic)
{
return String.IsNullOrWhiteSpace(genre) == false && genre == influencingMusic.Genre;
}
public static bool IsInfluencedAlbum(string album, Music influencingMusic)
{
return String.IsNullOrWhiteSpace(album) == false && album == influencingMusic.Album;
}
public static bool IsInfluencedArtist(string artist, Music influencingMusic)
{
return String.IsNullOrWhiteSpace(artist) == false && artist == influencingMusic.Album;
}
public static bool IsInfluencedComposer(string composer, Music influencingMusic)
{
return String.IsNullOrWhiteSpace(composer) == false && composer == influencingMusic.Album;
}
}
}