public List <FightData> GenerateFightData(bool _SaveTrash = false)//Dictionary<string, string> _InterestingFights)
        {
            //float addonVersion = 1.0f;
            //if (AddonVersion.TryParseFloat(out addonVersion) == false)
            //    addonVersion = 1.0f;

            //if (addonVersion < 1.5f)
            //    throw new Exception("Too old AddonVersion: \"" + AddonVersion + "\"");

            List <FightData> fights = new List <FightData>();

            FightData  currTrash             = null;
            FightData  currFight             = null;
            int        lastFightTime         = 0;
            TimeSlice  lastFightTimeSlice    = null;
            List <int> currentGroupMemberIDs = null;

            for (int i = 0; i < TimeSlices.Count; ++i)
            {
                var currTimeSlice = TimeSlices[i];
                if (currTimeSlice.GroupMemberIDs != null && currTimeSlice.GroupMemberIDs.Count != 0)
                {
                    currentGroupMemberIDs = currTimeSlice.GroupMemberIDs;
                }
                if (currentGroupMemberIDs != null)
                {
                    if (currTrash != null)
                    {
                        if (currTrash.TimeSlices.Count >= 1 &&
                            currTrash.TimeSlices[0].GroupMemberIDs == null)
                        {
                            currTrash.TimeSlices[0].GroupMemberIDs = new List <int>(currentGroupMemberIDs);
                        }
                    }
                    if (currFight != null)
                    {
                        if (currFight.TimeSlices.Count >= 1 &&
                            currFight.TimeSlices[0].GroupMemberIDs == null)
                        {
                            currFight.TimeSlices[0].GroupMemberIDs = new List <int>(currentGroupMemberIDs);
                        }
                    }
                }
                if (_SaveTrash == true)
                {
                    if (currTrash == null && currFight == null)
                    {
                        currTrash = new FightData
                        {
                            FightName        = "Trash",
                            StartDateTime    = StartDateTime.AddSeconds(currTimeSlice.Time - StartTime),
                            Realm            = this.Realm,
                            RecordedByPlayer = this.Player,
                            AddonVersion     = this.AddonVersion,
                            StartServerTime  = StartServerTime + (currTimeSlice.Time - StartTime),
                        };
                    }
                    if (currTrash != null)
                    {
                        currTrash.TimeSlices.Add(currTimeSlice);
                    }
                }
                if (currTimeSlice.Event != "")
                {
                    if (currTimeSlice.IsStartEvent())
                    {
                        string bossName = "";
                        if (currTimeSlice.GetEventBoss(out bossName) == true)
                        {
                            if (currFight == null)
                            {
                                string   instanceName      = BossInformation.BossFights[bossName];
                                int      raidID            = -1;
                                DateTime raidResetDateTime = DateTime.MinValue;
                                if (FetchRelevantRaidID(currTimeSlice, instanceName, ref raidID, ref raidResetDateTime) == false)
                                {
                                    raidID = -1;
                                }
                                if (_SaveTrash == true)
                                {
                                    currTrash.FightDuration     = (int)(StartDateTime.AddSeconds(currTimeSlice.Time - StartTime) - currTrash.StartDateTime).TotalSeconds;
                                    currTrash.RaidID            = raidID;
                                    currTrash.RaidResetDateTime = raidResetDateTime;

                                    if (currTrash.FightDuration > 120 && currTrash.TimeSlices.Count((_Value) => _Value.ChangedUnitDatas.Count > 10) > 10)
                                    {
                                        var trashUnitDatas = currTrash.TimeSlices.Last().GetDeltaUnitDatas(currTrash.TimeSlices.First());
                                        if (trashUnitDatas.Sum((_Value) => _Value.Value.I.Dmg) > 100000)
                                        {
                                            //Save only if enough data in it
                                            fights.Add(currTrash);
                                        }
                                    }
                                    currTrash = null;
                                }
                                try
                                {
                                    currFight = new FightData {
                                        FightName         = bossName,
                                        m_FightUnitIDs    = GenerateFightUnitIDs(bossName),
                                        StartDateTime     = StartDateTime.AddSeconds(currTimeSlice.Time - StartTime),
                                        RaidID            = raidID,
                                        RaidResetDateTime = raidResetDateTime,
                                        Realm             = this.Realm,
                                        RecordedByPlayer  = this.Player,
                                        AddonVersion      = this.AddonVersion,
                                        StartServerTime   = StartServerTime + (currTimeSlice.Time - StartTime),
                                    };
                                    lastFightTimeSlice = null;
                                    //if (i > 0)
                                    //{
                                    //    currFight.TimeSlices.Add(TimeSlices[i - 1]);
                                    //}
                                }
                                catch (Exception)
                                {
                                    currFight = null;
                                }
                            }
                            else
                            {
                                if (currTimeSlice.IsEventBoss(currFight.FightName))
                                {
                                    //Nothing needs to be done, fight is allready started!
                                }
                                else
                                {
                                    var bossUnitIDs = GenerateFightUnitIDs(bossName);
                                    //If a fight is allready ongoing we need to figure out which one has priority, figure out which one contains the most data change over the next 20 timeslices

                                    TimeSlice lastFightData1TimeSlice = null;
                                    TimeSlice lastFightData2TimeSlice = null;
                                    int       lastFightData1Score     = 0;
                                    int       lastFightData2Score     = 0;
                                    for (int u = i; u < TimeSlices.Count && u < i + 20; ++u)
                                    {
                                        if (currFight.ContainsThisFight(TimeSlices[u]) == true)
                                        {
                                            if (lastFightData1TimeSlice != null)
                                            {
                                                if (currFight.DetectActivity(lastFightData1TimeSlice, TimeSlices[u]) == true)
                                                {
                                                    ++lastFightData1Score;
                                                }
                                            }
                                            lastFightData1TimeSlice = TimeSlices[u];
                                        }
                                        if (FightData._ContainsThisFight(bossUnitIDs, TimeSlices[u]) == true)
                                        {
                                            if (lastFightData2TimeSlice != null)
                                            {
                                                if (FightData._DetectActivity(bossUnitIDs, lastFightData2TimeSlice, TimeSlices[u]) == true)
                                                {
                                                    ++lastFightData2Score;
                                                }
                                            }
                                            lastFightData2TimeSlice = TimeSlices[u];
                                        }
                                    }

                                    if (bossName == "Ragnaros" && currFight.FightName == "Majordomo Executus")
                                    {
                                        lastFightData2Score += 10;
                                    }

                                    if (lastFightData1Score >= lastFightData2Score)
                                    {
                                        //There is no reason to change since the next 20 timeslices contains more or same amount of info about the current boss
                                    }
                                    else
                                    {
                                        //The current boss has less data in the next 20 timeslices. End current boss and change so the new boss is focused!
                                        //currFight.FightDuration = -1;
                                        //currFight.PerfectSync = false;
                                        //fights.Add(currFight);
                                        currFight = null;

                                        string   instanceName      = BossInformation.BossFights[bossName];
                                        int      raidID            = -1;
                                        DateTime raidResetDateTime = DateTime.MinValue;
                                        if (FetchRelevantRaidID(currTimeSlice, instanceName, ref raidID, ref raidResetDateTime) == false)
                                        {
                                            raidID = -1;
                                        }
                                        try
                                        {
                                            currFight = new FightData
                                            {
                                                FightName         = bossName,
                                                m_FightUnitIDs    = GenerateFightUnitIDs(bossName),
                                                StartDateTime     = StartDateTime.AddSeconds(currTimeSlice.Time - StartTime),
                                                RaidID            = raidID,
                                                RaidResetDateTime = raidResetDateTime,
                                                Realm             = this.Realm,
                                                RecordedByPlayer  = this.Player,
                                                AddonVersion      = this.AddonVersion,
                                                StartServerTime   = StartServerTime + (currTimeSlice.Time - StartTime),
                                            };
                                            lastFightTimeSlice = null;
                                            if (i > 0)
                                            {
                                                currFight.TimeSlices.Add(TimeSlices[i - 1]);
                                            }
                                        }
                                        catch (Exception)
                                        {
                                            currFight = null;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else if (currFight != null && (currTimeSlice.IsDeadEvent() || currTimeSlice.IsWipeEvent()))
                    {
                        if (currTimeSlice.IsEventBoss(currFight.FightName))
                        {
                            bool realDeadEvent = true;
                            if (currFight.FightName == "The Prophet Skeram")
                            {
                                int health;
                                int maxHealth;
                                if (currTimeSlice.IsDeadYellEvent() ||
                                    (currTimeSlice.GetEventBossHealth("The Prophet Skeram", out health, out maxHealth) && health <= 0 && maxHealth > 500000))
                                {
                                    realDeadEvent = true;
                                }
                                else
                                {
                                    string newEventStr = "";
                                    var    eventSplits = currTimeSlice.Event.Split(';');
                                    foreach (var eventSplit in eventSplits)
                                    {
                                        if (eventSplit.StartsWith("Dead") == false)
                                        {
                                            newEventStr += eventSplit + ";";
                                        }
                                        else
                                        {
                                            newEventStr += eventSplit.Replace("Dead", "AddDead") + ";";
                                        }
                                    }
                                    while (newEventStr.EndsWith(";"))
                                    {
                                        newEventStr = newEventStr.Substring(0, newEventStr.Length - 1);
                                    }

                                    currTimeSlice.Event = newEventStr;
                                    realDeadEvent       = false;
                                }
                            }
                            if (currTimeSlice.IsWipeEvent() && BossInformation.FightsWithDisappearingBoss.Contains(currFight.FightName) == true)
                            {
                                //Detection of premature Wipe event.
                                //This was added after problems on Nefarian raid not being able to capture Razorgore fight
                                //Possibly it is just a problem with the faulty "WIPE" guesses.
                                //This should hopefully solve the issue as this is pretty much an internal wipe functionality that is standalone from client
                                var        bossAdds = BossInformation.BossAdds[currFight.FightName];
                                List <int> bossIDs  = new List <int>();
                                bossIDs.AddRange(currFight.FightUnitIDs);
                                foreach (var bossAdd in bossAdds)
                                {
                                    int bossAddID = 0;
                                    if (TryGetIDFromName(bossAdd, out bossAddID) == true)
                                    {
                                        bossIDs.Add(bossAddID);
                                    }
                                }
                                int timeSinceLastBossInTimeSlice = 0;
                                for (int u = i + 1; u < TimeSlices.Count - 1; ++u)
                                {
                                    bool bossInTimeSlice = false;
                                    foreach (var bossID in bossIDs)
                                    {
                                        if (TimeSlices[u].ChangedUnitDatas.Contains(bossID))
                                        {
                                            bossInTimeSlice = true;
                                            break;
                                        }
                                    }
                                    //It is important that we continue adding time to this variable and not check if boss was in timeslice yet
                                    //This will help cover some rare corner cases such as Wipe->no timeslices for 200 seconds due to whatever reason->Start
                                    timeSinceLastBossInTimeSlice += (TimeSlices[u].Time - TimeSlices[u - 1].Time);

                                    if ((TimeSlices[u].IsStartEvent() && TimeSlices[u].IsEventBoss(currFight.FightName)) ||
                                        TimeSlices[u].Time - TimeSlices[i].Time > 180)
                                    {
                                        if (timeSinceLastBossInTimeSlice < 35)
                                        {
                                            realDeadEvent = false;
                                        }
                                        break;
                                    }
                                    else if (bossInTimeSlice == true)
                                    {
                                        timeSinceLastBossInTimeSlice = 0;
                                    }
                                    else if (bossInTimeSlice == false)
                                    {
                                        if (timeSinceLastBossInTimeSlice > 35)
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                            if (realDeadEvent == true) //Only end the fight if it truely was a Dead event (not fake one like The Prophet Skeram)
                            {
                                currFight.TimeSlices.Add(currTimeSlice);
                                for (int u = i + 1; u < TimeSlices.Count - 1; ++u)
                                {
                                    if (TimeSlices[u].IsStartEvent())
                                    {
                                        break;
                                    }
                                    currFight.TimeSlices.Add(TimeSlices[u]);
                                    if (TimeSlices[u].ChangedUnitDatas.Count < 3 && /*TimeSlices[u + 1].ChangedUnitDatas.Count < 3 &&*/ TimeSlices[u].Time - currTimeSlice.Time > 5)
                                    {
                                        currFight.PerfectSync = true;
                                        break;
                                    }
                                    else if (TimeSlices[u + 1].Time - TimeSlices[u].Time > 15 && TimeSlices[u].Time - currTimeSlice.Time < 30)
                                    {
                                        currFight.PerfectSync = true;
                                        break;
                                    }
                                    int deltaChangedUnitsCount = TimeSlices[u + 1].GetDeltaUnitDatas(TimeSlices[u], true).Count((_Value) => { return(_Value.Value.I.Dmg > 1000 || _Value.Value.I.EffHeal > 1000); });
                                    if (deltaChangedUnitsCount < 3 && TimeSlices[u].Time - currTimeSlice.Time > 5)
                                    {
                                        currFight.PerfectSync = true;
                                        break;
                                    }
                                    if (TimeSlices[u].Time - currTimeSlice.Time > 60)
                                    {
                                        currFight.PerfectSync = false;
                                        break;
                                    }
                                }
                                currFight.FightDuration = (int)(StartDateTime.AddSeconds(currTimeSlice.Time - StartTime) - currFight.StartDateTime).TotalSeconds;
                                if (currFight.TimeSlices.Count(
                                        (_Value) =>
                                {
                                    foreach (var unitID in currFight.FightUnitIDs)
                                    {
                                        if (_Value.ChangedUnitDatas.Contains(unitID) == true)
                                        {
                                            return(true);
                                        }
                                    }
                                    return(false);
                                }) >= 5)
                                {
                                    fights.Add(currFight);
                                }
                                else
                                {
                                    if (BossInformation.FightsWithDisappearingBoss.Contains(currFight.FightName) == true)
                                    {
                                        //Give these fights a second chance to since they do not have the Boss included in the entire fight, check all the adds
                                        var        bossAdds = BossInformation.BossAdds[currFight.FightName];
                                        List <int> bossIDs  = new List <int>();
                                        bossIDs.AddRange(currFight.FightUnitIDs);
                                        foreach (var bossAdd in bossAdds)
                                        {
                                            int bossAddID = 0;
                                            if (TryGetIDFromName(bossAdd, out bossAddID) == true)
                                            {
                                                bossIDs.Add(bossAddID);
                                            }
                                        }
                                        if (currFight.TimeSlices.Count(
                                                (_Value) =>
                                        {
                                            foreach (var unitID in bossIDs)
                                            {
                                                if (_Value.ChangedUnitDatas.Contains(unitID) == true)
                                                {
                                                    return(true);
                                                }
                                            }
                                            return(false);
                                        }) >= 10)
                                        {
                                            fights.Add(currFight);
                                        }
                                    }
                                }
                                currFight = null;
                            }
                        }
                    }
                    else if (currFight != null && lastFightTimeSlice != null && currTimeSlice.Time - lastFightTime > 60)
                    {
                        //If the fighting "boss" has not been seen on SWStats for longer than 60 seconds it most likely means there was a wipe

                        //Unless the bossfight is Gothik the Harvester!
                        //then we recalculate to see if any add has been changed the last 60 seconds
                        if (BossInformation.FightsWithDisappearingBoss.Contains(currFight.FightName) == true)
                        {
                            //Check if adds have been active the last 60 seconds, if so extend the lastFightTime!
                            var bossAdds = BossInformation.BossAdds[currFight.FightName];
                            List <Tuple <int, UnitData> > bossAddIDs = new List <Tuple <int, UnitData> >();
                            foreach (var bossAdd in bossAdds)
                            {
                                int bossAddID = 0;
                                if (TryGetIDFromName(bossAdd, out bossAddID) == true)
                                {
                                    UnitData bossAddUnitData = null;
                                    if (currTimeSlice.UnitDatas.TryGetValue(bossAddID, out bossAddUnitData) == true)
                                    {
                                        bossAddIDs.Add(Tuple.Create(bossAddID, bossAddUnitData));
                                    }
                                }
                            }
                            for (int u = i - 1; u >= 0; --u)
                            {
                                if (currTimeSlice.Time - TimeSlices[u].Time > 60)
                                {
                                    break;
                                }
                                bool foundAction = false;
                                foreach (var bossAdd in bossAddIDs)
                                {
                                    UnitData bossAddUnitData = null;
                                    if (TimeSlices[u].UnitDatas.TryGetValue(bossAdd.Item1, out bossAddUnitData) == true)
                                    {
                                        if (bossAdd.Item2.I.Dmg - bossAddUnitData.I.Dmg != 0 ||
                                            bossAdd.Item2.I.DmgTaken - bossAddUnitData.I.DmgTaken != 0 ||
                                            bossAdd.Item2.I.Death - bossAddUnitData.I.Death != 0)
                                        {
                                            lastFightTime = TimeSlices[u].Time;
                                            foundAction   = true;
                                            break;
                                        }
                                    }
                                }
                                if (foundAction == true)
                                {
                                    break;
                                }
                            }
                        }
                        if (currTimeSlice.Time - lastFightTime > 60)//Double check incase it changed above
                        {
                            currFight.FightDuration = (int)(StartDateTime.AddSeconds(lastFightTime - StartTime) - currFight.StartDateTime).TotalSeconds;
                            if (currFight.FightDuration > 30)
                            {//Only care about fights that lasts longer than 30 seconds
                                currFight.PerfectSync = false;
                                fights.Add(currFight);
                            }
                            currFight = null;
                        }
                    }
                }
                if (currFight != null)
                {
                    if (currFight.ContainsThisFight(currTimeSlice) == true)
                    {
                        if (lastFightTimeSlice == null || currFight.DetectActivity(lastFightTimeSlice, currTimeSlice) == true)
                        {
                            lastFightTime = currTimeSlice.Time;
                        }
                        lastFightTimeSlice = currTimeSlice;
                    }

                    currFight.TimeSlices.Add(currTimeSlice);
                }
            }
            foreach (var fight in fights)
            {
                fight.RemoveUnnecessaryUnits();
            }
            return(fights);
        }
 public FightCacheData(FightData _Fight, FightDataCollection _FightDataCollection)
 {
     m_Fight = _Fight;
     m_FightDataCollection = _FightDataCollection;
 }