using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
namespace D2Multi
{
/// Grid row binding for mission flags across difficulties.
public sealed class CharacterMissionGridRow : INotifyPropertyChanged
{
readonly D2Character _character;
public CharacterMissionGridRow(D2Character character)
{
_character = character ?? throw new ArgumentNullException(nameof(character));
D2CharacterMissionHelper.EnsureAllMissions(_character);
}
public D2Character Character => _character;
public string Name
{
get => _character.Name ?? string.Empty;
set
{
var v = value ?? string.Empty;
if (string.Equals(_character.Name, v, StringComparison.Ordinal))
return;
_character.Name = v;
OnPropertyChanged(nameof(Name));
}
}
public string Class
{
get => _character.Class ?? string.Empty;
set
{
var v = value ?? string.Empty;
if (string.Equals(_character.Class, v, StringComparison.Ordinal))
return;
_character.Class = v;
OnPropertyChanged(nameof(Class));
}
}
public bool NormalA1
{
get => Mission(D2Level.Normal).A1_Enpowered;
set => SetA1(D2Level.Normal, value);
}
public bool NormalA5
{
get => Mission(D2Level.Normal).A5_Socket;
set => SetA5(D2Level.Normal, value);
}
public bool NightmareA1
{
get => Mission(D2Level.Nightmare).A1_Enpowered;
set => SetA1(D2Level.Nightmare, value);
}
public bool NightmareA5
{
get => Mission(D2Level.Nightmare).A5_Socket;
set => SetA5(D2Level.Nightmare, value);
}
public bool HellA1
{
get => Mission(D2Level.Hell).A1_Enpowered;
set => SetA1(D2Level.Hell, value);
}
public bool HellA5
{
get => Mission(D2Level.Hell).A5_Socket;
set => SetA5(D2Level.Hell, value);
}
/// Count of quest rewards not yet claimed (false = still available).
public int MissionsAvailable
{
get
{
var n = 0;
foreach (var lvl in AllLevels)
{
var m = Mission(lvl);
if (!m.A1_Enpowered) n++;
if (!m.A5_Socket) n++;
}
return n;
}
}
static readonly D2Level[] AllLevels = { D2Level.Normal, D2Level.Nightmare, D2Level.Hell };
D2Mission Mission(D2Level level) => D2CharacterMissionHelper.GetMission(_character, level);
void SetA1(D2Level level, bool value)
{
var m = Mission(level);
if (m.A1_Enpowered == value) return;
m.A1_Enpowered = value;
OnPropertyChanged(PropForA1(level));
OnPropertyChanged(nameof(MissionsAvailable));
}
void SetA5(D2Level level, bool value)
{
var m = Mission(level);
if (m.A5_Socket == value) return;
m.A5_Socket = value;
OnPropertyChanged(PropForA5(level));
OnPropertyChanged(nameof(MissionsAvailable));
}
static string PropForA1(D2Level level)
{
switch (level)
{
case D2Level.Normal: return nameof(NormalA1);
case D2Level.Nightmare: return nameof(NightmareA1);
default: return nameof(HellA1);
}
}
static string PropForA5(D2Level level)
{
switch (level)
{
case D2Level.Normal: return nameof(NormalA5);
case D2Level.Nightmare: return nameof(NightmareA5);
default: return nameof(HellA5);
}
}
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string name) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
public static List FromAccount(D2Account account)
{
if (account?.Characters == null || account.Characters.Count == 0)
return new List();
return account.Characters.Select(c => new CharacterMissionGridRow(c)).ToList();
}
}
static class D2CharacterMissionHelper
{
public static void EnsureAllMissions(D2Character character)
{
if (character.Missions == null)
character.Missions = new List();
foreach (D2Level lvl in Enum.GetValues(typeof(D2Level)))
{
if (character.Missions.All(m => m.Level != lvl))
character.Missions.Add(new D2Mission { Level = lvl });
}
}
public static D2Mission GetMission(D2Character character, D2Level level)
{
EnsureAllMissions(character);
return character.Missions.First(m => m.Level == level);
}
public static D2Character CreateNewCharacter()
{
var c = new D2Character { Name = "New character", Class = string.Empty, Missions = new List() };
EnsureAllMissions(c);
return c;
}
}
}