public Deck(string name, string className, IEnumerable<Card> cards, IEnumerable<string> tags, string note, string url,
		            DateTime lastEdited, bool archived, List<Card> missingCards, SerializableVersion version, IEnumerable<Deck> versions,
		            bool? syncWithHearthStats, string hearthStatsId, Guid deckId, string hearthStatsDeckVersionId,
		            string hearthStatsIdClone = null, SerializableVersion selectedVersion = null, bool? isArenaDeck = null)

		{
			Name = name;
			Class = className;
			Cards = new ObservableCollection<Card>();
			MissingCards = missingCards;
			foreach(var card in cards)
				Cards.Add((Card)card.Clone());
			Tags = new List<string>(tags);
			Note = note;
			Url = url;
			LastEdited = lastEdited;
			Archived = archived;
			Version = version;
			SyncWithHearthStats = syncWithHearthStats;
			HearthStatsId = hearthStatsId;
			SelectedVersion = selectedVersion ?? version;
			Versions = new List<Deck>();
			DeckId = deckId;
			if(hearthStatsIdClone != null)
				HearthStatsIdForUploading = hearthStatsIdClone;
			if(isArenaDeck.HasValue)
				IsArenaDeck = isArenaDeck.Value;
			HearthStatsDeckVersionId = hearthStatsDeckVersionId;
			if(versions != null)
			{
				foreach(var d in versions)
					Versions.Add(d.CloneWithNewId(true) as Deck);
			}
		}
        public NewVersioInfo CheckNewAppVersionAvailable()
        {
            var requestErrorPolicy = Policy <NewVersioInfo>
                                     .Handle <System.Net.WebException>()
                                     .Fallback(new NewVersioInfo()
            {
                IsAvailable = false
            });

            string       url         = "https://raw.githubusercontent.com/MarioZG/elder-scrolls-legends-tracker/master/Build/versions.json";
            IHTTPService httpService = (IHTTPService)trackerFactory.GetService <IHTTPService>();

            return(requestErrorPolicy.Execute(() =>
            {
                string versionJSON = httpService.SendGetRequest(url);
                JObject versions = JObject.Parse(versionJSON);
                SerializableVersion latest = new SerializableVersion(new Version(versions["Application"].ToString()));
                IApplicationService appService = (IApplicationService)trackerFactory.GetService <IApplicationService>();

                return new NewVersioInfo()
                {
                    IsAvailable = latest > appService.GetAssemblyVersion(),
                    Number = latest.ToString(),
                    DownloadUrl = GetLatestDownladUrl()
                };
            }));
        }
示例#3
0
        public ExistingDeck(Deck deck, HearthMirror.Objects.Deck newDeck)
        {
            Deck = deck;
            var tmp = new Deck {
                Cards = new ObservableCollection <Card>(newDeck.Cards.Select(x => new Card {
                    Id = x.Id, Count = x.Count
                }))
            };

            MatchingCards = 0;
            if (deck.HasVersions)
            {
                var counts = deck.VersionsIncludingSelf.Select(v => GetMatchingCards(tmp, deck.GetVersion(v)));
                if (counts.Any(c => c == 30))
                {
                    MatchingCards = 30;
                }
            }
            if (MatchingCards != 30)
            {
                MatchingCards = GetMatchingCards(tmp, deck);
            }
            NewVersion = MatchingCards == 30 ? new SerializableVersion(0, 0)
                                : (MatchingCards < 26 ? SerializableVersion.IncreaseMajor(deck.Version)
                                        : SerializableVersion.IncreaseMinor(deck.Version));
            ShouldBeNewDeck = MatchingCards < 15;
        }
示例#4
0
        public Deck ToDeck(CardObject[] cards, string[] rawTags, DeckVersion[] versions, string version)
        {
            if (!klass_id.HasValue)
            {
                return(null);
            }
            try
            {
                var url      = "";
                var archived = false;
                if (!string.IsNullOrEmpty(notes))
                {
                    var match = Regex.Match(notes, noteUrlRegex);
                    if (match.Success)
                    {
                        url   = match.Groups["url"].Value;
                        notes = Regex.Replace(notes, noteUrlRegex, "");
                    }

                    if (notes.Contains(noteArchived))
                    {
                        archived = true;
                        notes    = notes.Replace(noteArchived, "");
                    }
                    notes = notes.Trim();
                }


                //tags are returned all lowercase, find matching tag
                var tags =
                    rawTags.Select(
                        tag =>
                        DeckList.Instance.AllTags.FirstOrDefault(t => string.Equals(t, tag, StringComparison.InvariantCultureIgnoreCase))
                        ?? tag);
                var deck = new Deck(name ?? "", Dictionaries.HeroDict[klass_id.Value],
                                    cards?.Where(x => x?.count != null && x.id != null)
                                    .Select(x => x.ToCard())
                                    .Where(x => x != null)
                                    .ToList() ?? new List <Card>(), tags, notes ?? "", url, DateTime.Now, archived, new List <Card>(),
                                    SerializableVersion.ParseOrDefault(version), new List <Deck>(), true, id.ToString(), Guid.NewGuid(),
                                    deck_version_id.ToString());
                deck.LastEdited = updated_at.ToLocalTime();
                if (versions.Length > 0)
                {
                    deck.Versions = versions.Where(v => v.version != version).Select(v => v.ToDeck(deck)).ToList();
                }
                var current = versions.FirstOrDefault(v => v.version == version);
                if (current != null)
                {
                    deck.HearthStatsDeckVersionId = current.deck_version_id.ToString();
                }
                deck.HearthStatsIdsAlreadyReset = true;
                return(deck);
            }
            catch (Exception e)
            {
                Logger.WriteLine("error converting DeckObject: " + e, "HearthStatsAPI");
                return(null);
            }
        }
示例#5
0
        public NewVersioInfo CheckNewAppVersionAvailable()
        {
            string url = settings.VersionCheck_VersionsUrl;

            var requestErrorPolicy = Policy <NewVersioInfo>
                                     .Handle <System.Net.WebException>()
                                     .Fallback(
                new NewVersioInfo()
            {
                IsAvailable = false
            }
                );

            IHTTPService httpService = (IHTTPService)trackerFactory.GetService <IHTTPService>();

            return(requestErrorPolicy.Execute(() =>
            {
                string versionJSON = httpService.SendGetRequest(url);
                JObject versions = JObject.Parse(versionJSON);
                SerializableVersion latest = new SerializableVersion(new Version(versions["Application"].ToString()));
                IApplicationService appService = (IApplicationService)trackerFactory.GetService <IApplicationService>();

                return new NewVersioInfo()
                {
                    IsAvailable = latest > appService.GetAssemblyVersion(),
                    Number = latest.ToString(),
                    DownloadUrl = GetLatestDownladUrl()
                };
            }));
        }
示例#6
0
        /// <summary>
        /// A static initializer which populates the FileVersion and the ObjectModelVersion with the parsed contents of V_CURRENT.
        /// </summary>
        static VimConstants()
        {
            var parsedCurrent = SerializableHeader.Parse(V_CURRENT);

            FileVersion        = parsedCurrent.FileVersion;
            ObjectModelVersion = parsedCurrent.ObjectModelVersion;
        }
示例#7
0
        public Deck(string name, string className, IEnumerable <Card> cards, IEnumerable <string> tags, string note, string url,
                    DateTime lastEdited, List <Card> missingCards, SerializableVersion version, IEnumerable <Deck> versions,
                    SerializableVersion selectedVersion = null)

        {
            Name         = name;
            Class        = className;
            Cards        = new ObservableCollection <Card>();
            MissingCards = missingCards;
            foreach (var card in cards)
            {
                Cards.Add((Card)card.Clone());
            }
            Tags            = new List <string>(tags);
            Note            = note;
            Url             = url;
            LastEdited      = lastEdited;
            Version         = version;
            SelectedVersion = selectedVersion ?? version;
            Versions        = new List <Deck>();
            if (versions != null)
            {
                foreach (var d in versions)
                {
                    Versions.Add(d.Clone() as Deck);
                }
            }
        }
        public void SaveDeck(ITracker tracker, SerializableVersion versionIncrease, IEnumerable <CardInstance> cardsCollection)
        {
            ErrorMessage = String.Empty;
            if (Deck.Class == null)
            {
                ErrorMessage = "Please select deck class";
                return;
            }
            if (versionIncrease == new SerializableVersion(0, 0))
            {
                //overwrite
                //we were working on current version - do nothing
            }
            else
            {
                //save current cards
                List <CardInstance> cards = new List <CardInstance>(Deck.SelectedVersion.Cards);
                //undo changes in curr version
                //Deck.SelectedVersion points to curret latest
                Deck.SelectedVersion.Cards = savedState.History.Where(dv => dv.VersionId == Deck.SelectedVersionId).First().Cards;
                //create new verson wih new cards

                int major, minor;
                if (versionIncrease.Major == 1)
                {
                    major = versionIncrease.Major + GetMaxMajor();
                    minor = 0;
                }
                else if (versionIncrease.Minor == 1)
                {
                    major = Deck.SelectedVersion.Version.Major;
                    minor = versionIncrease.Minor + GetMaxMinor(major);
                }
                else
                {
                    throw new ArgumentOutOfRangeException(nameof(versionIncrease), "Method accepts only version increase by 0 or 1");
                }

                Deck.CreateVersion(
                    major,
                    minor,
                    trackerFactory.GetDateTimeNow());

                //now Deck.SelectedVersion points to new version
                foreach (CardInstance ci in cards)
                {
                    Deck.SelectedVersion.Cards.Add((CardInstance)ci.Clone());
                }
            }
            if (!tracker.Decks.Contains(this.Deck))
            {
                tracker.Decks.Add(this.Deck);
            }
            trackerFactory.GetFileManager().SaveDatabase();
            this.EndEdit();
            messanger.Send(new Utils.Messages.EditDeck()
            {
                Deck = this.Deck
            }, Utils.Messages.EditDeck.Context.EditFinished);
        }
		internal static void MoveGamesToOtherDeckWithoutConfirmation(Deck targetDeck, SerializableVersion targetVersion,
																	 params GameStats[] games)
		{
			if(games == null)
				return;
			foreach(var game in games)
			{
				var defaultDeck = DefaultDeckStats.Instance.DeckStats.FirstOrDefault(ds => ds.Games.Contains(game));
				if(defaultDeck != null)
				{
					defaultDeck.Games.Remove(game);
					DefaultDeckStats.Save();
				}
				else
				{
					var deck = DeckList.Instance.Decks.FirstOrDefault(d => game.DeckId == d.DeckId);
					deck?.DeckStats.Games.Remove(game);
				}
				game.PlayerDeckVersion = targetVersion;
				game.HearthStatsDeckVersionId = targetDeck.GetVersion(targetVersion).HearthStatsDeckVersionId;
				game.DeckId = targetDeck.DeckId;
				game.DeckName = targetDeck.Name;
				targetDeck.DeckStats.Games.Add(game);
				if(HearthStatsAPI.IsLoggedIn && Config.Instance.HearthStatsAutoUploadNewGames)
					HearthStatsManager.MoveMatchAsync(game, targetDeck, background: true).Forget();
			}
			DeckStatsList.Save();
			DeckList.Save();
			Core.MainWindow.DeckPickerList.UpdateDecks();
		}
示例#10
0
        public void ParseCurrentFileVersionTest004_NullPassed()
        {
            SerializableVersion expected = null;

            SerializableVersion result = FileManager.ParseCurrentFileVersion(null);

            Assert.AreEqual(expected, result);
        }
示例#11
0
 public Deck GetVersion(SerializableVersion version)
 {
     if (version == null)
     {
         return(null);
     }
     return(GetVersion(version.Major, version.Minor));
 }
示例#12
0
        public Deck GetVersion(int major, int minor)
        {
            var target = new SerializableVersion(major, minor);

            if (Version == target)
            {
                return(this);
            }
            return(Versions.FirstOrDefault(x => x.Version == target));
        }
示例#13
0
 public Deck()
 {
     Cards        = new ObservableCollection <Card>();
     MissingCards = new List <Card>();
     Tags         = new List <string>();
     Note         = string.Empty;
     Url          = string.Empty;
     Name         = string.Empty;
     Version      = SerializableVersion.Default;
     Versions     = new List <Deck>();
 }
        private void CommandSaveExecute(object parameter)
        {
            string versionInc       = parameter as string;
            SerializableVersion ver = new SerializableVersion(0, 0);

            if (parameter != null)
            {
                ver = new SerializableVersion(new Version(versionInc));
            }
            ClearModifiedBorder();
            SaveDeck(this.trackerFactory.GetTracker(), ver, Deck.SelectedVersion.Cards);
        }
        public Deck ToDeck(CardObject[] cards, DeckVersion[] versions, string version)
        {
            try
            {
                var  url      = "";
                bool archived = false;
                if (!string.IsNullOrEmpty(notes))
                {
                    var match = Regex.Match(notes, noteUrlRegex);
                    if (match.Success)
                    {
                        url   = match.Groups["url"].Value;
                        notes = Regex.Replace(notes, noteUrlRegex, "");
                    }

                    if (notes.Contains(noteArchived))
                    {
                        archived = true;
                        notes    = notes.Replace(noteArchived, "");
                    }
                }

                notes = notes.Trim();

                var deck = new Deck(name ?? "", Dictionaries.HeroDict[klass_id],
                                    cards == null
                                                            ? new List <Card>()
                                                            : cards.Where(x => x != null && x.count != null && x.id != null)
                                    .Select(x => x.ToCard())
                                    .Where(x => x != null)
                                    .ToList(), tags ?? new string[0], notes ?? "", url, DateTime.Now, archived, new List <Card>(),
                                    SerializableVersion.ParseOrDefault(version), new List <Deck>(), true, id.ToString(), Guid.NewGuid(),
                                    deck_version_id.ToString());
                deck.LastEdited = updated_at.ToLocalTime();
                if (versions.Length > 0)
                {
                    deck.Versions = versions.Where(v => v.version != version).Select(v => v.ToDeck(deck)).ToList();
                }
                var current = versions.FirstOrDefault(v => v.version == version);
                if (current != null)
                {
                    deck.HearthStatsDeckVersionId = current.deck_version_id.ToString();
                }
                deck.HearthStatsIdsAlreadyReset = true;
                return(deck);
            }
            catch (Exception e)
            {
                Logger.WriteLine("error converting DeckObject: " + e, "HearthStatsAPI");
                return(null);
            }
        }
        private static bool DeckVersionsAreEqual(Version v, SerializableVersion sv)
        {
            if (v == null && sv == null)
            {
                return(true);
            }
            else if (v == null || sv == null)
            {
                return(false);
            }

            return(v.Major == sv.Major && v.Minor == sv.Minor);
        }
示例#17
0
 public Deck()
 {
     Cards        = new ObservableCollection <Card>();
     MissingCards = new List <Card>();
     Tags         = new List <string>();
     Note         = string.Empty;
     Url          = string.Empty;
     Name         = string.Empty;
     Archived     = false;
     Version      = SerializableVersion.Default;
     Versions     = new List <Deck>();
     DeckId       = Guid.NewGuid();
 }
示例#18
0
        public void Invalidate(string editorInstallationPath)
        {
            var riderBuildNumber = RiderPathLocator.GetBuildNumber(editorInstallationPath);

            editorBuildNumber = riderBuildNumber.ToSerializableVersion();
            productInfo       = RiderPathLocator.GetBuildVersion(editorInstallationPath);
            if (riderBuildNumber == null)
            {
                shouldLoadEditorPlugin = false;
            }

            shouldLoadEditorPlugin = riderBuildNumber >= new Version("191.7141.156");
        }
示例#19
0
        public ExistingDeck(Deck deck, HearthMirror.Objects.Deck newDeck)
        {
            Deck = deck;
            var tmp = new Deck {
                Cards = new ObservableCollection <Card>(newDeck.Cards.Select(x => new Card {
                    Id = x.Id, Count = x.Count
                }))
            };

            MatchingCards = 30 - (deck - tmp).Count(x => x.Count > 0);
            NewVersion    = MatchingCards == 30 ? new SerializableVersion(0, 0)
                                : (MatchingCards < 26 ? SerializableVersion.IncreaseMajor(deck.Version)
                                        : SerializableVersion.IncreaseMinor(deck.Version));
        }
示例#20
0
        public Deck ToDeck(Deck latest)
        {
            var clone = (Deck)latest.CloneWithNewId(true);

            clone.Cards =
                new ObservableCollection <Card>(cards?.Where(x => x?.count != null && x.id != null)
                                                .Select(x => x.ToCard())
                                                .Where(x => x != null)
                                                .ToList() ?? new List <Card>());
            clone.HearthStatsDeckVersionId = deck_version_id.ToString();
            clone.Version = SerializableVersion.ParseOrDefault(version);
            clone.Versions.Clear();
            return(clone);
        }
示例#21
0
 public Deck()
 {
     Cards               = new ObservableCollection <Card>();
     MissingCards        = new List <Card>();
     Tags                = new List <string>();
     Note                = string.Empty;
     Url                 = string.Empty;
     Name                = string.Empty;
     SyncWithHearthStats = null;
     HearthStatsId       = string.Empty;
     Version             = SerializableVersion.Default;
     Versions            = new List <Deck>();
     DeckId              = Guid.NewGuid();
 }
		public Deck()
		{
			Cards = new ObservableCollection<Card>();
			MissingCards = new List<Card>();
			Tags = new List<string>();
			Note = string.Empty;
			Url = string.Empty;
			Name = string.Empty;
			Archived = false;
			SyncWithHearthStats = null;
			HearthStatsId = string.Empty;
			Version = SerializableVersion.Default;
			Versions = new List<Deck>();
			DeckId = Guid.NewGuid();
		}
示例#23
0
        internal void SaveDeckWithOverwriteCheck(SerializableVersion newVersion, bool saveAsNew = false)
        {
            if (saveAsNew)
            {
                EditingDeck = false;
                _newDeck.ResetVersions();
                _newDeck.DeckId   = Guid.NewGuid();
                _newDeck.Archived = false;
            }

            SaveDeck(EditingDeck, newVersion);
            DeckPickerList.UpdateArchivedClassVisibility();

            _editedDeckName = string.Empty;
        }
示例#24
0
        public Deck(string name, string className, IEnumerable <Card> cards, IEnumerable <string> tags, string note, string url,
                    DateTime lastEdited, bool archived, List <Card> missingCards, SerializableVersion version, IEnumerable <Deck> versions,
                    bool?syncWithHearthStats, string hearthStatsId, Guid deckId, string hearthStatsDeckVersionId, long hsId = 0,
                    string hearthStatsIdClone = null, SerializableVersion selectedVersion = null, bool?isArenaDeck = null,
                    ArenaReward reward        = null)

        {
            Name         = name;
            Class        = className;
            Cards        = new ObservableCollection <Card>();
            MissingCards = missingCards;
            foreach (var card in cards.ToSortedCardList())
            {
                Cards.Add((Card)card.Clone());
            }
            Tags                = new List <string>(tags);
            Note                = note;
            Url                 = url;
            LastEdited          = lastEdited;
            Archived            = archived;
            Version             = version;
            SyncWithHearthStats = syncWithHearthStats;
            HearthStatsId       = hearthStatsId;
            SelectedVersion     = selectedVersion ?? version;
            Versions            = new List <Deck>();
            DeckId              = deckId;
            if (hearthStatsIdClone != null)
            {
                HearthStatsIdForUploading = hearthStatsIdClone;
            }
            if (isArenaDeck.HasValue)
            {
                IsArenaDeck = isArenaDeck.Value;
            }
            HearthStatsDeckVersionId = hearthStatsDeckVersionId;
            if (versions != null)
            {
                foreach (var d in versions)
                {
                    Versions.Add(d.CloneWithNewId(true) as Deck);
                }
            }
            if (reward != null)
            {
                _arenaReward = reward;
            }
            HsId = hsId;
        }
        protected string CreateNewVersionXML(SerializableVersion TargetVersion)
        {
            StringBuilder serialisedVersion = new StringBuilder();

            using (TextWriter writer = new StringWriter(serialisedVersion))
            {
                var xml = new XmlSerializer(typeof(SerializableVersion), String.Empty);
                xml.Serialize(writer, TargetVersion);
            }

            XmlDocument newVersionDoc = new XmlDocument();

            newVersionDoc.LoadXml(serialisedVersion.ToString());

            return(newVersionDoc.DocumentElement.InnerXml);
        }
示例#26
0
        /// <summary>
        /// Creates new deck version in history, adds to colletion and returns reference
        /// </summary>
        /// <param name="major"></param>
        /// <param name="minor"></param>
        /// <param name="createdDate"></param>
        /// <returns></returns>
        public DeckVersion CreateVersion(int major, int minor, DateTime createdDate)
        {
            SerializableVersion version = new SerializableVersion(major, minor);

            if (DoNotUse.Any(v => v.Version == version))
            {
                throw new ArgumentException(string.Format("Version {0} alread has been added to deck '{1}'", version, Name));
            }
            DeckVersion dv = new DeckVersion();

            dv.CreatedDate = createdDate;
            dv.Version     = version;
            this.DoNotUse.Add(dv); //add to history
            this.SelectedVersionId = dv.VersionId;
            return(dv);
        }
示例#27
0
    public void Invalidate(string editorInstallationPath, bool shouldInvalidatePrevEditorBuildNumber = false)
    {
      var riderBuildNumber = RiderPathLocator.GetBuildNumber(editorInstallationPath);
      editorBuildNumber = riderBuildNumber.ToSerializableVersion();
      if (shouldInvalidatePrevEditorBuildNumber)
        prevEditorBuildNumber = editorBuildNumber;
      productInfo = RiderPathLocator.GetBuildVersion(editorInstallationPath);
      if (riderBuildNumber == null) // if we fail to parse for some reason
        shouldLoadEditorPlugin = true;

      shouldLoadEditorPlugin = riderBuildNumber >= new Version("191.7141.156");

      if (RiderPathUtil.IsRiderDevEditor(editorInstallationPath))
      {
        shouldLoadEditorPlugin = true;
        editorBuildNumber = new SerializableVersion(new Version("999.999.999.999"));
      }
    }
        public void ToStringTest002()
        {
            SerializableVersion sv = new SerializableVersion(1, 2, 3, 4);

            Dictionary <string, string> testCases = new Dictionary <string, string>()
            {
                { "G", "1.2.3.4" },
                { "{M}.{m}.{b}.{r}", "1.2.3.4" },
                { "{M}.{m}", "1.2" },
                { "hello {M}.{m}", "hello 1.2" },
                { "mm", "1.2" },
                { "hello mm", "hello mm" }
            };

            foreach (KeyValuePair <string, string> textCase in testCases)
            {
                Assert.AreEqual(textCase.Value, sv.ToString(textCase.Key), "Failed for case {0}", textCase.Key);
            }
        }
示例#29
0
        public void ParseCurrentFileVersionTest002_IncorrectElementNameXML()
        {
            var doc = new XmlDocument();

            doc.LoadXml(
                @" <Version>
                    <Bld>2</Bld>
                    <Major>1</Major>
                    <Minor>3</Minor>
                    <Resion>4</Resion>
                  </Version>");
            var versionNode = doc.DocumentElement;

            SerializableVersion expected = null;

            SerializableVersion result = FileManager.ParseCurrentFileVersion(versionNode);;

            Assert.AreEqual(expected, result);
        }
示例#30
0
        public void ParseCurrentFileVersionTest001_AllOK()
        {
            var doc = new XmlDocument();

            doc.LoadXml(
                @" <Version>
                    <Build>2</Build>
                    <Major>1</Major>
                    <Minor>3</Minor>
                    <Revision>4</Revision>
                  </Version>");
            var versionNode = doc.DocumentElement;

            SerializableVersion expected = new SerializableVersion(new Version(1, 3, 2, 4));

            SerializableVersion result = FileManager.ParseCurrentFileVersion(versionNode);

            Assert.AreEqual(expected, result);
        }
示例#31
0
        public void ParseCurrentFileVersionTest003_NotIntInValue()
        {
            var doc = new XmlDocument();

            doc.LoadXml(
                @" <Version>
                    <Build>test non int!</Build>
                    <Major>1</Major>
                    <Minor>3</Minor>
                    <Revision>4</Revision>
                  </Version>");
            var versionNode = doc.DocumentElement;

            SerializableVersion expected = null;

            SerializableVersion result = FileManager.ParseCurrentFileVersion(versionNode);

            Assert.AreEqual(expected, result);
        }
示例#32
0
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            SerializableVersion selectedVersion = (values[0] as DataRowView)?.Row[1] as SerializableVersion;
            Deck selectedDeck = (values[0] as GameStatisticsViewModel.GameStatisticsDeckRow)?.Deck as Deck;

            Deck currentDeck = values[1] as Deck;
            SerializableVersion currentVersion = values[2] as SerializableVersion;

            SerializableVersion totalRowMarker = values[3] as SerializableVersion;

            if (selectedDeck != null)
            {
                return(currentDeck.DeckId == selectedDeck.DeckId || currentVersion == totalRowMarker);
            }
            else
            {
                //nothing yet selected - show only deck totoals
                return(currentVersion == totalRowMarker);
            }
        }
        public static SerializableHeader Parse(string input)
        {
            var comps = input.Split(':');

            if (comps.Length != 4)
            {
                throw new Exception("Expected header to have four parts: " + input);
            }
            if (comps[0] != "vim")
            {
                throw new Exception("Expected header to start with `vim`: " + input);
            }
            if (comps[2] != "objectmodel")
            {
                throw new Exception("Expected header to have object model: " + input);
            }
            return(new SerializableHeader
            {
                FileVersion = SerializableVersion.Parse(comps[1]),
                ObjectModelVersion = SerializableVersion.Parse(comps[3])
            });
        }
		public async void SaveDeck(bool overwrite, SerializableVersion newVersion, bool workInProgressDeck = false)
		{
			var deckName = TextBoxDeckName.Text;

			if(string.IsNullOrEmpty(deckName))
			{
				var settings = new MessageDialogs.Settings {AffirmativeButtonText = "Set", DefaultText = deckName};

				var name = await this.ShowInputAsync("No name set", "Please set a name for the deck", settings);

				if(string.IsNullOrEmpty(name))
					return;

				deckName = name;
				TextBoxDeckName.Text = name;
			}

			if(_newDeck.Cards.Sum(c => c.Count) != 30 && workInProgressDeck == false)
			{
				var settings = new MessageDialogs.Settings {AffirmativeButtonText = "Yes", NegativeButtonText = "No"};

				var result =
					await
					this.ShowMessageAsync("Not 30 cards",
										  $"Deck contains {_newDeck.Cards.Sum(c => c.Count)} cards. Is this what you want to save anyway?", MessageDialogStyle.AffirmativeAndNegative, settings);
				if(result != MessageDialogResult.Affirmative)
					return;
			}

			var previousVersion = _newDeck.Version;
			if(overwrite && (_newDeck.Version != newVersion))
			{
				AddDeckHistory();
				_newDeck.Version = newVersion;
				_newDeck.SelectedVersion = newVersion;
				_newDeck.HearthStatsDeckVersionId = "";
			}

			if(EditingDeck && overwrite)
				DeckList.Instance.Decks.Remove(_newDeck);

			var oldDeckName = _newDeck.Name;

			_newDeck.Name = deckName;

			var newDeckClone = (Deck)_newDeck.Clone();
			newDeckClone.Archived = false;

			DeckList.Instance.Decks.Add(newDeckClone);

			newDeckClone.LastEdited = DateTime.Now;

			DeckList.Save();

			Log.Info("Saved Decks");

			if(EditingDeck)
			{
				TagControlEdit.SetSelectedTags(new List<string>());
				if(deckName != oldDeckName)
				{
					var statsEntry = DeckStatsList.Instance.DeckStats.FirstOrDefault(ds => ds.BelongsToDeck(_newDeck));
					if(statsEntry != null)
					{
						if(overwrite)
						{
							statsEntry.Name = deckName;
							Log.Info("Deck has new name, updated deckstats");
							foreach(var game in statsEntry.Games)
								game.DeckName = deckName;
						}
						else
						{
							var newStatsEntry = DeckStatsList.Instance.DeckStats.FirstOrDefault(ds => ds.BelongsToDeck(_newDeck));
							if(newStatsEntry == null)
							{
								newStatsEntry = new DeckStats(_newDeck);
								DeckStatsList.Instance.DeckStats.Add(newStatsEntry);
							}
							foreach(var game in statsEntry.Games)
								newStatsEntry.AddGameResult(game.CloneWithNewId());
							Log.Info("cloned gamestats for \"Set as new\"");
						}
						DeckStatsList.Save();
					}
				}
			}


			if(Config.Instance.HearthStatsAutoUploadNewDecks && HearthStatsAPI.IsLoggedIn)
			{
				Log.Info("auto uploading new/edited deck");
				if(EditingDeck)
				{
					if(previousVersion != newVersion)
						HearthStatsManager.UploadVersionAsync(newDeckClone, _originalDeck.HearthStatsIdForUploading, background: true).Forget();
					else
						HearthStatsManager.UpdateDeckAsync(newDeckClone, background: true).Forget();
				}
				else
					HearthStatsManager.UploadDeckAsync(newDeckClone, background: true).Forget();
			}

			if(EditingDeck)
				DeckManagerEvents.OnDeckUpdated.Execute(newDeckClone);
			else
				DeckManagerEvents.OnDeckCreated.Execute(newDeckClone);


			EditingDeck = false;

			foreach(var tag in _newDeck.Tags)
				SortFilterDecksFlyout.AddSelectedTag(tag);

			DeckPickerList.SelectDeckAndAppropriateView(newDeckClone);
			DeckPickerList.UpdateDecks(forceUpdate: new[] {newDeckClone});
			SelectDeck(newDeckClone, true);
			CloseNewDeck();
			ClearNewDeckSection();
		}
		public Deck GetVersion(SerializableVersion version)
		{
			if(version == null)
				return null;
			return GetVersion(version.Major, version.Minor);
		}
		public Deck GetVersion(int major, int minor)
		{
			var target = new SerializableVersion(major, minor);
			if(Version == target)
				return this;
			return Versions.FirstOrDefault(x => x.Version == target);
		}
		public void SelectVersion(SerializableVersion version) => SelectedVersion = version;
		public void ResetVersions()
		{
			Versions = new List<Deck>();
			Version = SerializableVersion.Default;
			SelectedVersion = Version;
		}
		public bool HasVersion(SerializableVersion version) => Version == version || Versions.Any(v => v.Version == version);
		public Deck GetVersion(SerializableVersion version) => version == null ? null : (Version == version ? this : Versions.FirstOrDefault(x => x.Version == version));
		internal void SaveDeckWithOverwriteCheck(SerializableVersion newVersion, bool saveAsNew = false)
		{
			if(saveAsNew)
			{
				EditingDeck = false;
				_newDeck.ResetVersions();
				_newDeck.ResetHearthstatsIds();
				_newDeck.DeckId = Guid.NewGuid();
				_newDeck.Archived = false;
			}

			SaveDeck(EditingDeck, newVersion);
			DeckPickerList.UpdateArchivedClassVisibility();

			_editedDeckName = string.Empty;
		}