예제 #1
0
 public String getSessionInfo(String script, String method, SessionInfo session, Int32 rounding)
 {
     try
     {
         string result = scripts[script].SessionInfo(method, session, rounding);
         logger.Debug("Calling getSessionInfo('{0}') in {1} Result: {2}", method, script, result);
         return result;
     }
     catch (Exception ex)
     {
         logger.Error("Error in {0}.SessionInfo('{2}'): {1}", script, ex.ToString(), method);
     }
     return "[Error]";
 }
예제 #2
0
        private void parser(string yaml)
        {
            int start = 0;
            int end = 0;
            int length = 0;

            length = yaml.Length;
            start = yaml.IndexOf("WeekendInfo:\n", 0, length);
            end = yaml.IndexOf("\n\n", start, length - start);

            string WeekendInfo = yaml.Substring(start, end - start);
            SharedData.Track.Length = (Single)parseDoubleValue(WeekendInfo, "TrackLength", "km") * 1000;
            SharedData.Track.Id = parseIntValue(WeekendInfo, "TrackID");
            SharedData.Track.Turns = parseIntValue(WeekendInfo, "TrackNumTurns");
            SharedData.Track.City = parseStringValue(WeekendInfo, "TrackCity");
            SharedData.Track.Country = parseStringValue(WeekendInfo, "TrackCountry");

            SharedData.Track.Altitude = (Single)parseDoubleValue(WeekendInfo, "TrackAltitude", "m");
            SharedData.Track.Sky = parseStringValue(WeekendInfo, "TrackSkies");
            SharedData.Track.TrackTemperature = (Single)parseDoubleValue(WeekendInfo, "TrackSurfaceTemp", "C");
            SharedData.Track.AirTemperature = (Single)parseDoubleValue(WeekendInfo, "TrackAirTemp", "C");
            SharedData.Track.AirPressure = (Single)parseDoubleValue(WeekendInfo, "TrackAirPressure", "Hg");
            SharedData.Track.WindSpeed = (Single)parseDoubleValue(WeekendInfo, "TrackWindVel", "m/s");
            SharedData.Track.WindDirection = (Single)parseDoubleValue(WeekendInfo, "TrackWindDir", "rad");
            SharedData.Track.Humidity = parseIntValue(WeekendInfo, "TrackRelativeHumidity", "%");
            SharedData.Track.Fog = parseIntValue(WeekendInfo, "TrackFogLevel", "%");

            if (parseIntValue(WeekendInfo, "Official") == 0 &&
                parseIntValue(WeekendInfo, "SeasonID") == 0 &&
                parseIntValue(WeekendInfo, "SeriesID") == 0)
                SharedData.Sessions.Hosted = true;
            else
                SharedData.Sessions.Hosted = false;




            if ( SharedData.theme != null )
                SharedData.Track.Name = SharedData.theme.TrackNames.getValue("Tracks", SharedData.Track.Id.ToString(),false,"Unknown Track",false);

            SharedData.Sessions.SessionId = parseIntValue(WeekendInfo, "SessionID");
            SharedData.Sessions.SubSessionId = parseIntValue(WeekendInfo, "SubSessionID");

            length = yaml.Length;
            start = yaml.IndexOf("DriverInfo:\n", 0, length);
            end = yaml.IndexOf("\n\n", start, length - start);

            string DriverInfo = yaml.Substring(start, end - start);

            length = DriverInfo.Length;
            start = DriverInfo.IndexOf(" Drivers:\n", 0, length);
            end = length;

            string Drivers = DriverInfo.Substring(start, end - start - 1);
            string[] driverList = Drivers.Split(new string[] { "\n - " }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string driver in driverList)
            {
                // KJ: fix
                // let's see if car is already in list ...
                int carIdx = parseIntValue(driver, "CarIdx");
                var driverCarIdx = SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx));
                if (driverCarIdx != null)
                {
                    // car already in list, check if driver changed
                    var newUserId = parseIntValue(driver, "UserID");
                    if (driverCarIdx.UserId != newUserId)
                    {
logger.Info("driverChange detected - new driver ({0})", parseStringValue(driver,"UserName"));
                        // driver changed - update driver details
                        SharedData.updateControls = true;
                        SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Name = parseStringValue(driver, "UserName");
                        SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Initials = parseStringValue(driver, "Initials");
                        if (parseStringValue(driver, "AbbrevName") != null)
                        {
                            string[] splitName = parseStringValue(driver, "AbbrevName").Split(',');
                            if (splitName.Length > 1)
                                SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Shortname = splitName[1] + " " + splitName[0];
                            else
                                SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Shortname = parseStringValue(driver, "AbbrevName");
                        }
                        else
                            SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Shortname = "";
                        SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Club = parseStringValue(driver, "Club");
                        SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).SR = parseStringValue(driver, "SR");
                        SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).iRating = parseIntValue(driver, "iRating");
                        SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).UserId = newUserId;
logger.Info("driverChange - looking for external data", "");
                        string[] external_driver;
                        if ( SharedData.externalData.TryGetValue(newUserId, out external_driver) )
                        {
logger.Info("driverChange - external data found", "");
                            int ed_idx;
                            if ( ( ed_idx = Int32.Parse(SharedData.theme.getIniValue("General", "dataFullName") ) ) >= 0 && external_driver.Length > ed_idx )
                            {
                                SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Name = external_driver[ed_idx];
                            }
                            if ( ( ed_idx = Int32.Parse(SharedData.theme.getIniValue("General", "dataShortName") ) ) >= 0 && external_driver.Length > ed_idx )
                            {
                                SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Shortname = external_driver[ed_idx];
                            }
                            if ( ( ed_idx = Int32.Parse(SharedData.theme.getIniValue("General", "dataInitials") ) ) >= 0 && external_driver.Length > ed_idx )
                            {
                                SharedData.Drivers.Find(d => d.CarIdx.Equals(carIdx)).Initials = external_driver[ed_idx];
                            }
                        }
logger.Info("driverChange - data ready", "");
                    }
                }

                int userId = parseIntValue(driver, "UserID");
                if (userId < Int32.MaxValue && userId > 0)
                {
                    int index = SharedData.Drivers.FindIndex(d => d.UserId.Equals(userId));
                    if (index < 0 &&
                        parseStringValue(driver, "CarPath") != "safety pcfr500s" &&
                        parseStringValue(driver, "AbbrevName") != "Pace Car")
                    {
                        if (SharedData.settings.IncludeMe || (!SharedData.settings.IncludeMe && parseIntValue(driver, "CarIdx") != 63))
                        {
                            DriverInfo driverItem = new DriverInfo();
                            char[] charsToTrim = {'"'};

                            driverItem.Name = parseStringValue(driver, "UserName");

                            if (parseStringValue(driver, "AbbrevName") != null)
                            {
                                string[] splitName = parseStringValue(driver, "AbbrevName").Split(',');
                                if (splitName.Length > 1)
                                    driverItem.Shortname = splitName[1] + " " + splitName[0];
                                else
                                    driverItem.Shortname = parseStringValue(driver, "AbbrevName");
                            }
                            driverItem.Initials = parseStringValue(driver, "Initials");
                            driverItem.Club = parseStringValue(driver, "ClubName");
                            driverItem.NumberPlate = parseStringValue(driver, "CarNumber").Trim(charsToTrim);
                            driverItem.CarId = parseIntValue(driver, "CarID");
                            driverItem.CarClass = parseIntValue(driver, "CarClassID");
                            driverItem.UserId = parseIntValue(driver, "UserID");
                            driverItem.CarIdx = parseIntValue(driver, "CarIdx");
                            driverItem.CarClassName = ( SharedData.theme != null ? SharedData.theme.getCarClass(driverItem.CarId) : "unknown" );
                            driverItem.iRating = parseIntValue(driver, "IRating");
                            // KJ: teamID!
                            driverItem.TeamId = parseIntValue(driver, "TeamID");

                            int liclevel = parseIntValue(driver, "LicLevel");
                            int licsublevel = parseIntValue(driver, "LicSubLevel");

                            switch (liclevel)
                            {
                                case 0:
                                case 1:
                                case 2:
                                case 3:
                                case 4:
                                    driverItem.SR = "R" + ((double)licsublevel / 100).ToString("0.00");
                                    break;
                                case 5:
                                case 6:
                                case 7:
                                case 8:
                                    driverItem.SR = "D" + ((double)licsublevel / 100).ToString("0.00");
                                    break;
                                case 9:
                                case 10:
                                case 11:
                                case 12:
                                    driverItem.SR = "C" + ((double)licsublevel / 100).ToString("0.00");
                                    break;
                                case 14:
                                case 15:
                                case 16:
                                case 17:
                                    driverItem.SR = "B" + ((double)licsublevel / 100).ToString("0.00");
                                    break;
                                case 18:
                                case 19:
                                case 20:
                                case 21:
                                    driverItem.SR = "A" + ((double)licsublevel / 100).ToString("0.00");
                                    break;
                                case 22:
                                case 23:
                                case 24:
                                case 25:
                                    driverItem.SR = "P" + ((double)licsublevel / 100).ToString("0.00");
                                    break;
                                case 26:
                                case 27:
                                case 28:
                                case 29:
                                    driverItem.SR = "WC" + ((double)licsublevel / 100).ToString("0.00");
                                    break;
                                default:
                                    driverItem.SR = "Unknown";
                                    break;
                            }

                            driverItem.CarClass = -1;
                            int carclass = parseIntValue(driver, "CarClassID");
                            int freeslot = -1;

                            for (int i = 0; i < SharedData.Classes.Length; i++)
                            {
                                if (SharedData.Classes[i] == carclass)
                                {
                                    driverItem.CarClass = i;
                                }
                                else if (SharedData.Classes[i] == -1 && freeslot < 0)
                                {
                                    freeslot = i;
                                }
                            }

                            if (driverItem.CarClass < 0 && freeslot >= 0)
                            {
                                SharedData.Classes[freeslot] = carclass;
                                driverItem.CarClass = freeslot;
                            }

                            if (!SharedData.externalPoints.ContainsKey(userId) && driverItem.CarIdx < 60)
                                SharedData.externalPoints.Add(userId, 0);

                            // fix bugges
                            if (driverItem.NumberPlate == null)
                                driverItem.NumberPlate = "000";
                            if (driverItem.Initials == null)
                                driverItem.Initials = "";

                            // KJ: if we are team-racing: get the teamname or make one up ...
                            if (driverItem.TeamId > 0)
                            {
                                if (SharedData.externalTeamData.ContainsKey(driverItem.TeamId))
                                {
                                    // found teamname for teamid in teams.csv
                                    string[] td_result;
                                    SharedData.externalTeamData.TryGetValue(driverItem.TeamId, out td_result);
                                    driverItem.TeamName = td_result[0];
                                }
                                else if (SharedData.externalTeamData.ContainsKey(Int32.Parse(driverItem.NumberPlate)))
                                {
                                    // found teamname for carnum in teams.csv
                                    string[] td_result;
                                    SharedData.externalTeamData.TryGetValue(Int32.Parse(driverItem.NumberPlate), out td_result);
                                    driverItem.TeamName = td_result[0];
                                }
                                else
                                {
                                    // make up generic teamname (to be parametrized in future)
                                    driverItem.TeamName = "Team #" + driverItem.NumberPlate;
                                }
                            }

                            // KJ: if we have external data - perhaps we shall overload name data for the driver
                            string[] external_driver;
                            if (SharedData.externalData.TryGetValue(userId, out external_driver))
                            {
                                // found external data for userid
                                int ed_idx;
                                SharedData.theme.getIniValue("General", "dataFullName");
                                if ((ed_idx = Int32.Parse(SharedData.theme.getIniValue("General", "dataFullName"))) >= 0 && external_driver.Length > ed_idx )
                                {
                                    // fullname gets replaced with column of data.csv
                                    driverItem.Name = external_driver[ed_idx];
                                }
                                if ((ed_idx = Int32.Parse(SharedData.theme.getIniValue("General", "dataShortName"))) >= 0 && external_driver.Length > ed_idx )
                                {
                                    // shortname gets replaced with column of data.csv
                                    driverItem.Shortname = external_driver[ed_idx];
                                }
                                if ((ed_idx = Int32.Parse(SharedData.theme.getIniValue("General", "dataInitials"))) >= 0 && external_driver.Length > ed_idx )
                                {
                                    // initials get replaced with column of data.csv
                                    driverItem.Initials = external_driver[ed_idx];
                                }
                            }

                            SharedData.Drivers.Add(driverItem);
                        }
                    }
                }
            }

            length = yaml.Length;
            start = yaml.IndexOf("SessionInfo:\n", 0, length);
            end = yaml.IndexOf("\n\n", start, length - start);

            string SessionInfo = yaml.Substring(start, end - start);

            length = SessionInfo.Length;
            start = SessionInfo.IndexOf(" Sessions:\n", 0, length);
            end = length;

            string Sessions = SessionInfo.Substring(start, end - start);
            string[] sessionList = Sessions.Split(new string[] { "\n - " }, StringSplitOptions.RemoveEmptyEntries);

            // Get Current running Session
            int _CurrentSession = (int)sdk.GetData("SessionNum");

            foreach (string session in sessionList)
            {
                int sessionNum = parseIntValue(session, "SessionNum");
                if (sessionNum < Int32.MaxValue)
                {
                    int sessionIndex = SharedData.Sessions.SessionList.FindIndex(s => s.Id.Equals(sessionNum));
                    if (sessionIndex < 0) // add new session item
                    {
                        SessionInfo sessionItem = new SessionInfo();
                        sessionItem.Id = sessionNum;
                        sessionItem.LapsTotal = parseIntValue(session, "SessionLaps");
                        sessionItem.SessionLength = parseFloatValue(session, "SessionTime", "sec");
                        sessionItem.Type = sessionTypeMap[parseStringValue(session, "SessionType")];

                        if (sessionItem.Type == SessionTypes.race)
                        {
                            sessionItem.FinishLine = parseIntValue(session, "SessionLaps") + 1;
                        }
                        else
                        {
                            sessionItem.FinishLine = Int32.MaxValue;
                        }

                        if (sessionItem.FinishLine < 0)
                        {
                            sessionItem.FinishLine = Int32.MaxValue;
                        }

                        sessionItem.Cautions = parseIntValue(session, "ResultsNumCautionFlags");
                        sessionItem.CautionLaps = parseIntValue(session, "ResultsNumCautionLaps");
                        sessionItem.LeadChanges = parseIntValue(session, "ResultsNumLeadChanges");
                        sessionItem.LapsComplete = parseIntValue(session, "ResultsLapsComplete");

                        length = session.Length;
                        start = session.IndexOf("   ResultsFastestLap:\n", 0, length);
                        end = length;
                        string ResultsFastestLap = session.Substring(start, end - start);

                        sessionItem.FastestLap = parseFloatValue(ResultsFastestLap, "FastestTime");
                        int index = SharedData.Drivers.FindIndex(d => d.CarIdx.Equals(parseIntValue(ResultsFastestLap, "CarIdx")));
                        if (index >= 0)
                        {
                            sessionItem.FastestLapDriver = SharedData.Drivers[index];
                            sessionItem.FastestLapNum = parseIntValue(ResultsFastestLap, "FastestLap");
                        }
                        SharedData.Sessions.SessionList.Add(sessionItem);
                        sessionIndex = SharedData.Sessions.SessionList.FindIndex(s => s.Id.Equals(sessionNum));
                    }
                    else // update only non fixed fields
                    {
                        SharedData.Sessions.SessionList[sessionIndex].LeadChanges = parseIntValue(session, "ResultsNumLeadChanges");
                        SharedData.Sessions.SessionList[sessionIndex].LapsComplete = parseIntValue(session, "ResultsLapsComplete");

                        length = session.Length;
                        start = session.IndexOf("   ResultsFastestLap:\n", 0, length) + "   ResultsFastestLap:\n".Length;
                        end = length;
                        string ResultsFastestLap = session.Substring(start, end - start);

                        
                        SharedData.Sessions.SessionList[sessionIndex].FastestLap = parseFloatValue(ResultsFastestLap, "FastestTime");
                        int index = SharedData.Drivers.FindIndex(d => d.CarIdx.Equals(parseIntValue(ResultsFastestLap, "CarIdx")));
                        if (index >= 0)
                        {
                            SharedData.Sessions.SessionList[sessionIndex].FastestLapDriver = SharedData.Drivers[index];
                            SharedData.Sessions.SessionList[sessionIndex].FastestLapNum = parseIntValue(ResultsFastestLap, "FastestLap");
                        }
                    }
                    

                    length = session.Length;
                    start = session.IndexOf("   ResultsPositions:\n", 0, length);
                    end = session.IndexOf("   ResultsFastestLap:\n", start, length - start);

                    string Standings = session.Substring(start, end - start);
                    string[] standingList = Standings.Split(new string[] { "\n   - " }, StringSplitOptions.RemoveEmptyEntries);

                    Int32 position = 1;
                    List<DriverInfo> standingsDrivers = SharedData.Drivers.ToList();

                    foreach (string standing in standingList)
                    {
                        int carIdx = parseIntValue(standing, "CarIdx");
                        if (carIdx < Int32.MaxValue)
                        {
                            StandingsItem standingItem = new StandingsItem();
                            standingItem = SharedData.Sessions.SessionList[sessionIndex].FindDriver(carIdx);

                            standingsDrivers.Remove(standingsDrivers.Find(s => s.CarIdx.Equals(carIdx)));

                            if (parseFloatValue(standing, "LastTime") > 0)
                            {
                                if (parseFloatValue(standing, "LastTime") < SharedData.Sessions.SessionList[sessionIndex].FastestLap && SharedData.Sessions.SessionList[sessionIndex].FastestLap > 0)
                                {
                                    

                                    // Race Condition?
                                    //SharedData.Sessions.SessionList[sessionIndex].FastestLap = parseFloatValue(standing, "FastestTime");                                    
                                }
                            }

                            /*
                            if (parseFloatValue(standing, "FastestTime") < SharedData.Sessions.SessionList[sessionIndex].FastestLap ||
                                SharedData.Sessions.SessionList[sessionIndex].FastestLap <= 0)
                            {
                                SharedData.Sessions.SessionList[sessionIndex].FastestLap = parseFloatValue(standing, "FastestTime");
                            }
                            */
                            /*
                            if (standingItem.Finished == false)
                            {
                                standingItem.PreviousLap.LapTime = parseFloatValue(standing, "LastTime");

                                if (standingItem.PreviousLap.LapTime <= 1)
                                {
                                    standingItem.PreviousLap.LapTime = standingItem.CurrentLap.LapTime;
                                }
                            }
                            */

                            if (SharedData.Sessions.SessionList[sessionIndex].Type == SharedData.Sessions.CurrentSession.Type)
                            {
                                if ((standingItem.CurrentTrackPct % 1.0) > 0.1)
                                {
                                    standingItem.PreviousLap.Position = parseIntValue(standing, "Position");
                                    standingItem.PreviousLap.Gap = parseFloatValue(standing, "Time");
                                    standingItem.PreviousLap.GapLaps = parseIntValue(standing, "Lap");
                                    standingItem.CurrentLap.Position = parseIntValue(standing, "Position");
                                }
                            }

                            if (standingItem.Driver.CarIdx < 0)
                            {
                                // insert item
                                int driverIndex = SharedData.Drivers.FindIndex(d => d.CarIdx.Equals(carIdx));
                                standingItem.setDriver(carIdx);
                                standingItem.FastestLap = parseFloatValue(standing, "FastestTime");
                                standingItem.LapsLed = parseIntValue(standing, "LapsLed");
                                standingItem.CurrentTrackPct = parseFloatValue(standing, "LapsDriven");
                                standingItem.Laps = new List<LapInfo>();

                                LapInfo newLap = new LapInfo();
                                newLap.LapNum = parseIntValue(standing, "LapsComplete");
                                newLap.LapTime = parseFloatValue(standing, "LastTime");
                                newLap.Position = parseIntValue(standing, "Position");
                                newLap.Gap = parseFloatValue(standing, "Time");
                                newLap.GapLaps = parseIntValue(standing, "Lap");
                                newLap.SectorTimes = new List<Sector>(3);
                                standingItem.Laps.Add(newLap);

                                standingItem.CurrentLap = new LapInfo();
                                standingItem.CurrentLap.LapNum = parseIntValue(standing, "LapsComplete") + 1;
                                standingItem.CurrentLap.Position = parseIntValue(standing, "Position");
                                standingItem.CurrentLap.Gap = parseFloatValue(standing, "Time");
                                standingItem.CurrentLap.GapLaps = parseIntValue(standing, "Lap");

                                lock (SharedData.SharedDataLock)
                                {
                                    SharedData.Sessions.SessionList[sessionIndex].Standings.Add(standingItem);
                                    SharedData.Sessions.SessionList[sessionIndex].UpdatePosition();
                                }
                            }

                            int lapnum = parseIntValue(standing, "LapsComplete");
                            standingItem.FastestLap = parseFloatValue(standing, "FastestTime");
                            standingItem.LapsLed = parseIntValue(standing, "LapsLed");

                            if (SharedData.Sessions.SessionList[sessionIndex].Type == SharedData.Sessions.CurrentSession.Type)
                            {
                                standingItem.PreviousLap.LapTime = parseFloatValue(standing, "LastTime");
                            }

                            if (SharedData.Sessions.CurrentSession.State == SessionStates.cooldown)
                            {
                                standingItem.CurrentLap.Gap = parseFloatValue(standing, "Time");
                                standingItem.CurrentLap.GapLaps = parseIntValue(standing, "Lap");
                                standingItem.CurrentLap.Position = parseIntValue(standing, "Position");
                                standingItem.CurrentLap.LapNum = parseIntValue(standing, "LapsComplete");
                            }

                            standingItem.Position = parseIntValue(standing, "Position");
                            standingItem.NotifySelf();
                            standingItem.NotifyLaps();

                            position++;
                        }
                    }

                    // Trigger Overlay Event, but only in current active session
                    if ((SharedData.Sessions.SessionList[sessionIndex].FastestLap != SharedData.Sessions.SessionList[sessionIndex].PreviousFastestLap)
                        && (_CurrentSession == SharedData.Sessions.SessionList[sessionIndex].Id)
                        )
                    {
                        if (SharedData.Sessions.SessionList[sessionIndex].FastestLap > 0)
                        {
                            SessionEvent ev = new SessionEvent(
                                        SessionEventTypes.fastlap,
                                        (Int32)(((Double)sdk.GetData("SessionTime") * 60) + timeoffset),
                                         SharedData.Sessions.SessionList[sessionIndex].FastestLapDriver,
                                        "New session fastest lap (" + Utils.floatTime2String(SharedData.Sessions.SessionList[sessionIndex].FastestLap, 3, false) + ")",
                                        SharedData.Sessions.SessionList[sessionIndex].Type,
                                       SharedData.Sessions.SessionList[sessionIndex].FastestLapNum
                                    );

                            SharedData.Events.Add(ev);
                            // Push Event to Overlay
                            logger.Info("New fastest lap in Session {0} : {1}", _CurrentSession, SharedData.Sessions.SessionList[sessionIndex].FastestLap);
                            SharedData.triggers.Push(TriggerTypes.fastestlap);
                        }
                    }

                    // update/add position for drivers not in results
                    foreach (DriverInfo driver in standingsDrivers)
                    {
                        StandingsItem standingItem = SharedData.Sessions.SessionList[sessionIndex].FindDriver(driver.CarIdx);
                        if (standingItem.Driver.CarIdx < 0)
                        {
                            if (SharedData.settings.IncludeMe || (!SharedData.settings.IncludeMe && standingItem.Driver.CarIdx != 63))
                            {
                                standingItem.setDriver(driver.CarIdx);
                                standingItem.Position = position;
                                standingItem.Laps = new List<LapInfo>();
                                lock (SharedData.SharedDataLock)
                                {
                                    SharedData.Sessions.SessionList[sessionIndex].Standings.Add(standingItem);
                                }
                                position++;
                            }
                        }
                        else if (!SharedData.settings.IncludeMe && driver.CarIdx < 63)
                        {
                            standingItem.Position = position;
                            position++;
                        }
                    }
                }
            }

            // add qualify session if it doesn't exist when race starts and fill it with YAML QualifyResultsInfo
            SessionInfo qualifySession = SharedData.Sessions.findSessionByType(SessionTypes.qualify);
            if (qualifySession.Type == SessionTypes.none)
            {
                qualifySession.Type = SessionTypes.qualify;

                length = yaml.Length;
                start = yaml.IndexOf("QualifyResultsInfo:\n", 0, length);

                // if found
                if (start >= 0)
                {
                    end = yaml.IndexOf("\n\n", start, length - start);

                    string QualifyResults = yaml.Substring(start, end - start);

                    length = QualifyResults.Length;
                    start = QualifyResults.IndexOf(" Results:\n", 0, length);
                    end = length;

                    string Results = QualifyResults.Substring(start, end - start - 1);
                    string[] resultList = Results.Split(new string[] { "\n - " }, StringSplitOptions.RemoveEmptyEntries);

                    qualifySession.FastestLap = float.MaxValue;

                    foreach (string result in resultList)
                    {
                        if (result != " Results:")
                        {
                            StandingsItem qualStandingsItem = qualifySession.FindDriver(parseIntValue(result, "CarIdx"));

                            if (qualStandingsItem.Driver.CarIdx > 0) // check if driver is in quali session
                            {
                                qualStandingsItem.Position = parseIntValue(result, "Position") + 1;
                            }
                            else // add driver to quali session
                            {
                                qualStandingsItem.setDriver(parseIntValue(result, "CarIdx"));
                                qualStandingsItem.Position = parseIntValue(result, "Position") + 1;
                                qualStandingsItem.FastestLap = parseFloatValue(result, "FastestTime");
                                lock (SharedData.SharedDataLock)
                                {
                                    qualifySession.Standings.Add(qualStandingsItem);
                                }
                                // update session fastest lap
                                if (qualStandingsItem.FastestLap < qualifySession.FastestLap && qualStandingsItem.FastestLap > 0)
                                    qualifySession.FastestLap = qualStandingsItem.FastestLap;
                            }
                        }
                    }
                    SharedData.Sessions.SessionList.Add(qualifySession); // add quali session
                }
            }

            // get qualify results if race session standings is empty
            foreach (SessionInfo session in SharedData.Sessions.SessionList)
            {
                if (session.Type == SessionTypes.race && session.Standings.Count < 1)
                {
                    length = yaml.Length;
                    start = yaml.IndexOf("QualifyResultsInfo:\n", 0, length);

                    // if found
                    if (start >= 0)
                    {
                        end = yaml.IndexOf("\n\n", start, length - start);

                        string QualifyResults = yaml.Substring(start, end - start);

                        length = QualifyResults.Length;
                        start = QualifyResults.IndexOf(" Results:\n", 0, length);
                        end = length;

                        string Results = QualifyResults.Substring(start, end - start - 1);
                        string[] resultList = Results.Split(new string[] { "\n - " }, StringSplitOptions.RemoveEmptyEntries);

                        foreach (string result in resultList)
                        {
                            if (result != " Results:")
                            {
                                StandingsItem standingItem = new StandingsItem();
                                standingItem.setDriver(parseIntValue(result, "CarIdx"));
                                standingItem.Position = parseIntValue(result, "Position") + 1;
                                lock (SharedData.SharedDataLock)
                                {
                                    session.Standings.Add(standingItem);
                                }
                            }
                        }
                    }
                }
            }

            length = yaml.Length;
            start = yaml.IndexOf("CameraInfo:\n", 0, length);
            end = yaml.IndexOf("\n\n", start, length - start);

            string CameraInfo = yaml.Substring(start, end - start);

            length = CameraInfo.Length;
            start = CameraInfo.IndexOf(" Groups:\n", 0, length);
            end = length;

            string Cameras = CameraInfo.Substring(start, end - start - 1);
            string[] cameraList = Cameras.Split(new string[] { "\n - " }, StringSplitOptions.RemoveEmptyEntries);
            bool haveNewCam = false;
            foreach (string camera in cameraList)
            {
                int cameraNum = parseIntValue(camera, "GroupNum");
                if (cameraNum < Int32.MaxValue)
                {
                    CameraGroup camgrp = SharedData.Camera.FindId(cameraNum);
                    if (camgrp.Id < 0)
                    {
                        CameraGroup cameraGroupItem = new CameraGroup();
                        cameraGroupItem.Id = cameraNum;
                        cameraGroupItem.Name = parseStringValue(camera, "GroupName");
                        lock (SharedData.SharedDataLock)
                        {
                            SharedData.Camera.Groups.Add(cameraGroupItem);
                            haveNewCam = true;
                        }
                    }
                }
            }
            if (SharedData.settings.CamerasButtonColumn && haveNewCam) // If we have a new cam and want Camera Buttons, then forece a refresh of the main window buttons
                SharedData.refreshButtons = true;

            length = yaml.Length;
            start = yaml.IndexOf("SplitTimeInfo:\n", 0, length);
            end = yaml.IndexOf("\n\n", start, length - start);

            string SplitTimeInfo = yaml.Substring(start, end - start);

            length = SplitTimeInfo.Length;
            start = SplitTimeInfo.IndexOf(" Sectors:\n", 0, length);
            end = length;

            string Sectors = SplitTimeInfo.Substring(start, end - start - 1);
            string[] sectorList = Sectors.Split(new string[] { "\n - " }, StringSplitOptions.RemoveEmptyEntries);

            if (sectorList.Length != SharedData.Sectors.Count)
            {
                SharedData.Sectors.Clear();
                foreach (string sector in sectorList)
                {
                    int sectornum = parseIntValue(sector, "SectorNum");
                    if (sectornum < 100)
                    {
                        float sectorborder = parseFloatValue(sector, "SectorStartPct");
                        SharedData.Sectors.Add(sectorborder);
                    }
                }

                // automagic sector selection
                if (SharedData.SelectedSectors.Count == 0)
                {
                    SharedData.SelectedSectors.Clear();

                    // load sectors
                    CfgFile sectorsIni = new CfgFile(Directory.GetCurrentDirectory() + "\\sectors.ini");
                    string sectorValue = sectorsIni.getValue("Sectors", SharedData.Track.Id.ToString(),false,String.Empty,false);
                    string[] selectedSectors = sectorValue.Split(';');
                    Array.Sort(selectedSectors);

                    SharedData.SelectedSectors.Clear();
                    if (sectorValue.Length > 0)
                    {
                        foreach (string sector in selectedSectors)
                        {
                            float number;
                            if (Single.TryParse(sector, out number))
                            {
                                SharedData.SelectedSectors.Add(number);
                            }
                        }
                    }
                    else
                    {
                        if (SharedData.Sectors.Count == 2)
                        {
                            foreach (float sector in SharedData.Sectors)
                                SharedData.SelectedSectors.Add(sector);
                        }
                        else
                        {
                            float prevsector = 0;
                            foreach (float sector in SharedData.Sectors)
                            {

                                if (sector == 0 && SharedData.SelectedSectors.Count == 0)
                                {
                                    SharedData.SelectedSectors.Add(sector);
                                }
                                else if (sector >= 0.333 && SharedData.SelectedSectors.Count == 1)
                                {
                                    if (sector - 0.333 < Math.Abs(prevsector - 0.333))
                                    {
                                        SharedData.SelectedSectors.Add(sector);
                                    }
                                    else
                                    {
                                        SharedData.SelectedSectors.Add(prevsector);
                                    }
                                }
                                else if (sector >= 0.666 && SharedData.SelectedSectors.Count == 2)
                                {
                                    if (sector - 0.666 < Math.Abs(prevsector - 0.666))
                                    {
                                        SharedData.SelectedSectors.Add(sector);
                                    }
                                    else
                                    {
                                        SharedData.SelectedSectors.Add(prevsector);
                                    }
                                }

                                prevsector = sector;
                            }
                        }
                    }
                }
            }
        }
예제 #3
0
        private void parseFlag(SessionInfo session, Int64 flag)
        {
            /*
            Dictionary<Int32, sessionFlag> flagMap = new Dictionary<Int32, sessionFlag>()
            {
                // global flags
                0x00000001 = sessionFlag.checkered,
                0x00000002 = sessionFlag.white,
                green = sessionFlag.green,
                yellow = 0x00000008,
             * 
                red = 0x00000010,
                blue = 0x00000020,
                debris = 0x00000040,
                crossed = 0x00000080,
             * 
                yellowWaving = 0x00000100,
                oneLapToGreen = 0x00000200,
                greenHeld = 0x00000400,
                tenToGo = 0x00000800,
             * 
                fiveToGo = 0x00001000,
                randomWaving = 0x00002000,
                caution = 0x00004000,
                cautionWaving = 0x00008000,

                // drivers black flags
                black = 0x00010000,
                disqualify = 0x00020000,
                servicible = 0x00040000, // car is allowed service (not a flag)
                furled = 0x00080000,
             * 
                repair = 0x00100000,

                // start lights
                startHidden = 0x10000000,
                startReady = 0x20000000,
                startSet = 0x40000000,
                startGo = 0x80000000,

            };*/

            Int64 regularFlag = flag & 0x0000000f;
            Int64 specialFlag = (flag & 0x0000f000) >> (4 * 3);
            Int64 startlight = (flag & 0xf0000000) >> (4 * 7);

            if (regularFlag == 0x8 || specialFlag >= 0x4)
                session.Flag = SessionFlags.yellow;
            else if (regularFlag == 0x2)
                session.Flag = SessionFlags.white;
            else if (regularFlag == 0x1)
                session.Flag = SessionFlags.checkered;
            else
                session.Flag = SessionFlags.green;

            session.StartLight = (SessionStartLights)startlight;
        }
예제 #4
0
파일: theme.cs 프로젝트: CloseUpDK/iRTVO
        // *-name *-info
        public string[] getFollowedFormats(StandingsItem standing, SessionInfo session, Int32 rounding)
        {
            Double laptime = SharedData.currentSessionTime - standing.Begin;

            string[] output = new string[71] {
                standing.Driver.Name,
                standing.Driver.Shortname,
                standing.Driver.Initials,
                standing.Driver.SR,
                standing.Driver.Club,
                getCar(standing.Driver.CarId),
                getCarClass(standing.Driver.CarId), //driver.carclass.ToString(),
                (standing.Driver.NumberPlate).ToString(),
               Utils.floatTime2String(standing.FastestLap, rounding, false),
               Utils.floatTime2String(standing.PreviousLap.LapTime, rounding, false),
                "", // currentlap (live) // 10
                standing.CurrentLap.LapNum.ToString(),
                "", // fastlap speed mph
                "", // prev lap speed mph
                "", // fastlap speed kph
                "", // prev lap speed kph
                standing.Position.ToString(),
                ordinate(standing.Position), // ordinal
                "",
                standing.LapsLed.ToString(),
                standing.Driver.UserId.ToString(), //20
                "",
                "",
                "",
                "",
                (standing.Speed * 3.6).ToString("0"),
                (standing.Speed * 2.237).ToString("0"),
                "",
                "",
                "",
                standing.PitStops.ToString(), //30
               Utils.floatTime2String(standing.PitStopTime, rounding, false),
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                "", // 40
                "",
                "",
                "",
                "",
                "",
                standing.ClassLapsLed.ToString(),
                "",
                "",
                "",
                "", // 50
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                "", // 60
                "",
                standing.PositionLive.ToString(),
                ordinate(standing.PositionLive),
                "",
                "",
                standing.Driver.iRating.ToString(),
                "",
                standing.TrackSurface == SurfaceTypes.InPitStall ? "1" : "0",
                standing.Driver.TeamId.ToString(),        // KJ: new text property teamid
                standing.Driver.TeamName,   // 70         // KJ: new text property teamname
            };

            if (standing.FastestLap < 5)
                output[8] = translation["invalid"];

            if (standing.PreviousLap.LapTime < 5)
                output[9] = translation["invalid"];

            if (laptime/60 > 60)
                output[10] = translation["invalid"];
            else if (((SharedData.currentSessionTime - standing.Begin) < 5))
            {
                if (standing.PreviousLap.LapTime < 5)
                    output[10] = translation["invalid"];
                else
                    output[10] =Utils.floatTime2String(standing.PreviousLap.LapTime, rounding, false);
            }
            //else if (standing.OnTrack == false)
            else if (standing.TrackSurface == SurfaceTypes.NotInWorld)
            {
                output[10] =Utils.floatTime2String(standing.FastestLap, rounding, false);
            }
            else {
                output[10] =Utils.floatTime2String((float)(SharedData.currentSessionTime - standing.Begin), rounding, false);
            }

            if (standing.FastestLap > 0)
            {
                output[12] = ((3600 * SharedData.Track.Length / (1609.344 * standing.FastestLap))).ToString("0.00");
                output[14] = (3.6 * SharedData.Track.Length / standing.FastestLap).ToString("0.00");
            }
            else
            {
                output[12] = "-";
                output[14] = "-";
            }

            if (standing.PreviousLap.LapTime > 0)
            {
                output[13] = ((3600 * SharedData.Track.Length / (1609.344 * standing.PreviousLap.LapTime))).ToString("0.00");
                output[15] = (3.6 * SharedData.Track.Length / standing.PreviousLap.LapTime).ToString("0.00");
            }
            else
            {
                output[13] = "-";
                output[15] = "-";
            }

            /*if ((DateTime.Now - standing.OffTrackSince).TotalMilliseconds > 1000 && standing.OnTrack == false && SharedData.allowRetire)*/
            if (standing.TrackSurface == SurfaceTypes.NotInWorld && 
                SharedData.allowRetire &&
                (SharedData.Sessions.CurrentSession.Time - standing.OffTrackSince) > 1)
            {
                output[18] = translation["out"];
            }
            else
            {
                if (standing.Position == 1)
                {
                    if (session.Type == SessionTypes.race)
                        output[18] = "";//iRTVO.Overlay.floatTime2String((float)standing.CurrentLap.SessionTime, rounding, true); //translation["leader"];
                    else
                        output[18] =Utils.floatTime2String(standing.FastestLap, rounding, false);
                }
                else if (standing.PreviousLap.GapLaps > 0 && session.Type == SessionTypes.race)
                {
                    /*
                    if (session.State == SessionStates.cooldown ||
                        (session.State == SessionStates.checkered && standing.CurrentTrackPct > session.LapsComplete))
                    {
                        output[18] = translation["behind"] + standing.FindLap(session.LapsComplete).GapLaps + " ";
                        if (standing.FindLap(session.LapsComplete).GapLaps > 1)
                            output[18] += translation["laps"];
                        else
                            output[18] += translation["lap"];
                    }
                    else
                    {
                    */
                        output[18] = translation["behind"] + standing.PreviousLap.GapLaps + " ";
                        if (standing.PreviousLap.GapLaps > 1)
                            output[18] += translation["laps"];
                        else
                            output[18] += translation["lap"];
                    //}
                }
                else/* if (SharedData.standing[SharedData.overlaySession].Length > 0 && SharedData.standing[SharedData.overlaySession][0].fastLap > 0)*/
                {
                    if (session.Type == SessionTypes.race)
                    {
                        /*
                        if (session.State == SessionStates.cooldown ||
                        (session.State == SessionStates.checkered && standing.CurrentTrackPct > session.LapsComplete))
                        {
                            output[18] = translation["behind"] +Utils.floatTime2String((standing.FindLap(session.LapsComplete).Gap), rounding, false);
                        }
                        else
                        {
                            output[18] = translation["behind"] +Utils.floatTime2String((standing.PreviousLap.Gap), rounding, false);
                        }
                         * */
                        output[18] = translation["behind"] +Utils.floatTime2String((standing.PreviousLap.Gap), rounding, false);
                    }
                    else if (standing.FastestLap <= 1)
                        output[18] = translation["invalid"];
                    else
                        output[18] = translation["behind"] +Utils.floatTime2String((standing.FastestLap - session.FastestLap), rounding, false);    
                }
            }

            // interval
            if (standing.Position > 1) // not leader
            {
                StandingsItem infront = new StandingsItem();
                infront = session.FindPosition(standing.Position - 1, DataOrders.position);

                if (session.Type == SessionTypes.race)
                {
                    if ((infront.CurrentTrackPct - standing.CurrentTrackPct) > 1)
                    {
                        output[21] = translation["behind"] + standing.PreviousLap.GapLaps + " ";
                        if (standing.PreviousLap.GapLaps > 1)
                            output[21] += translation["laps"];
                        else
                            output[21] += translation["lap"];
                    }
                    else
                    {
                        output[21] = translation["behind"] +Utils.floatTime2String((standing.PreviousLap.Gap - infront.PreviousLap.Gap), rounding, false);
                    }
                }
                else // qualify and practice
                {
                    if (standing.FastestLap <= 1)
                    {
                        output[21] = translation["invalid"];
                    }
                    else 
                    {
                        output[21] = translation["behind"] +Utils.floatTime2String((standing.FastestLap - infront.FastestLap), rounding, false);
                    }
                }

                output[22] = translation["behind"] +Utils.floatTime2String((standing.PreviousLap.Gap - infront.PreviousLap.Gap), rounding, false);
            }
            else // leader
            {

                if (session.Type == SessionTypes.race)
                {
                    output[21] = ""; //iRTVO.Overlay.floatTime2String((float)standing.CurrentLap.SessionTime, rounding, true); //translation["leader"];
                    output[22] = output[21];
                }
                else // qualify and practice
                {
                    output[21] =Utils.floatTime2String(standing.FastestLap, rounding, false);
                    output[22] = output[21];
                }
            }

            if (session.Type == SessionTypes.race)
            {
                output[23] = translation["behind"] + standing.GapLive_HR(rounding);
                output[24] = translation["behind"] + standing.IntervalLive_HR(rounding);
            }
            else {
                output[23] = output[18];
                output[24] = output[22];
            }

            // sectors
            if (SharedData.SelectedSectors.Count > 0)
            {
                for(int i = 0; i <= 2; i++) {
                    if (standing.Sector <= 0) // first sector, show previous lap times
                    {
                        if (i < standing.PreviousLap.SectorTimes.Count) 
                        {
                            Sector sector = standing.PreviousLap.SectorTimes.Find(s => s.Num.Equals(i));
                            if(sector != null)
                            {

                                output[27 + i] =Utils.floatTime2String(sector.Time, rounding, false);
                                output[32 + i] = (sector.Speed * 3.6).ToString("0.0");
                                output[35 + i] = (sector.Speed * 2.237).ToString("0.0");
                            }
                            else
                            {
                                output[27 + i] = "";
                                output[32 + i] = "";
                                output[35 + i] = "";
                            }
                        }
                        else
                        {
                            output[27 + i] = "";
                            output[32 + i] = "";
                            output[35 + i] = "";
                        }
                    }
                    else
                    {
                        if (i < standing.CurrentLap.SectorTimes.Count)
                        {
                            Sector sector = standing.CurrentLap.SectorTimes.Find(s => s.Num.Equals(i));
                            if(sector != null) 
                            {
                                output[27 + i] =Utils.floatTime2String(sector.Time, rounding, false);
                                output[32 + i] = (sector.Speed * 3.6).ToString("0.0");
                                output[35 + i] = (sector.Speed * 2.237).ToString("0.0");
                            }
                            else
                            {
                                output[27 + i] = "";
                                output[32 + i] = "";
                                output[35 + i] = "";
                            }
                        }
                        else
                        {
                            output[27 + i] = "";
                            output[32 + i] = "";
                            output[35 + i] = "";
                        }
                    }
                }
            }

            // position gain
            SessionInfo qualifySession = SharedData.Sessions.findSessionByType(SessionTypes.qualify);
            if (qualifySession.Type != SessionTypes.none)
            {
                int qualifyPos = qualifySession.FindDriver(standing.Driver.CarIdx).Position;
                if((qualifyPos - standing.Position) > 0)
                    output[38] = "+" + (qualifyPos - standing.Position).ToString();
                else
                    output[38] = (qualifyPos - standing.Position).ToString();

                output[47] = qualifyPos.ToString();
                output[50] = ordinate(qualifyPos);

                Int32 classqpos = qualifySession.getClassPosition(standing.Driver);
                output[48] = classqpos.ToString();
                output[49] = ordinate(classqpos);
            }

            // highest/lowest position
            output[51] = standing.HighestPosition.ToString();
            output[52] = ordinate(standing.HighestPosition);
            output[53] = standing.LowestPosition.ToString();
            output[54] = ordinate(standing.LowestPosition);

            output[55] = standing.HighestClassPosition.ToString();
            output[56] = ordinate(standing.HighestClassPosition);
            output[57] = standing.LowestClassPosition.ToString();
            output[58] = ordinate(standing.LowestClassPosition);

            /*
            // pititemr
            if ((DateTime.Now - standing.PitStopBegin).TotalSeconds > 1)
                output[31] =Utils.floatTime2String(standing.PitStopTime, rounding, false);
            else
            {
                output[31] =Utils.floatTime2String((float)(DateTime.Now - standing.PitStopBegin).TotalSeconds, rounding, false);
            }
            */

            // multiclass
            /*
                {"classposition", 39},
                {"classposition_ord", 40},
                {"classpositiongain", 41},
                {"classgap", 42},
                {"classlivegap", 43},
                {"classinterval", 44},
                {"classliveinterval", 45},
             */
            int classpos = session.getClassPosition(standing.Driver);
            StandingsItem classLeader = session.getClassLeader(standing.Driver.CarClassName);
            output[39] = classpos.ToString();
            output[40] = ordinate(classpos);
            output[43] = standing.ClassGapLive_HR;
            output[45] = standing.ClassIntervalLive_HR;

            if (qualifySession.Type != SessionTypes.none)
            {
                IEnumerable<StandingsItem> query = qualifySession.Standings.Where(s => s.Driver.CarClassName == standing.Driver.CarClassName).OrderBy(s => s.Position);
                Int32 position = 1;
                Int32 qualifyPos = 0;
                foreach (StandingsItem si in query)
                {
                    if (si.Driver.CarIdx == standing.Driver.CarIdx)
                    {
                        qualifyPos = position;
                        break;
                    }
                    else
                        position++;
                }

                if ((qualifyPos - classpos) > 0)
                    output[41] = "+" + (qualifyPos - classpos).ToString();
                else
                    output[41] = (qualifyPos - classpos).ToString();
            }

            if (standing.TrackSurface == SurfaceTypes.NotInWorld &&
                SharedData.allowRetire &&
                (SharedData.Sessions.CurrentSession.Time - standing.OffTrackSince) > 1)
            {
                output[42] = translation["out"];
            }
            else
            {
                float gap = classLeader.PreviousLap.Gap - standing.PreviousLap.Gap;
                int gaplaps = classLeader.PreviousLap.LapNum - standing.PreviousLap.LapNum;
                if (classpos == 1)
                {
                    if (session.Type == SessionTypes.race)
                        output[42] = ""; //iRTVO.Overlay.floatTime2String((float)standing.CurrentLap.SessionTime, rounding, true); //translation["leader"];
                    else
                        output[42] =Utils.floatTime2String(standing.FastestLap, rounding, false);
                }
                else if (gaplaps > 0 && session.Type == SessionTypes.race)
                {
                    output[42] = translation["behind"] + gaplaps + " ";
                    if (gaplaps > 1)
                        output[42] += translation["laps"];
                    else
                        output[42] += translation["lap"];
                    //}
                }
                else/* if (SharedData.standing[SharedData.overlaySession].Length > 0 && SharedData.standing[SharedData.overlaySession][0].fastLap > 0)*/
                {
                    if (session.Type == SessionTypes.race)
                    {
                        if (session.State == SessionStates.cooldown ||
                        (session.State == SessionStates.checkered && standing.CurrentTrackPct > session.LapsComplete))
                        {
                            output[42] = translation["behind"] +Utils.floatTime2String((standing.FindLap(session.LapsComplete).Gap), rounding, false);
                        }
                        else
                        {
                            output[42] = translation["behind"] +Utils.floatTime2String(gap, rounding, false);
                        }
                    }
                    else if (standing.FastestLap <= 1)
                        output[42] = translation["invalid"];
                    else
                        output[42] = translation["behind"] +Utils.floatTime2String((standing.FastestLap - classLeader.FastestLap), rounding, false);

                }
            }

            // interval
            if (standing.PreviousLap.Position > 1)
            {
                StandingsItem infront = new StandingsItem();
                infront = session.FindPosition(standing.Position - 1, DataOrders.position, standing.Driver.CarClassName);

                if (session.Type == SessionTypes.race)
                {
                    if ((infront.CurrentTrackPct - standing.CurrentTrackPct) > 1)
                    {
                        output[44] = translation["behind"] + standing.PreviousLap.GapLaps + " ";
                        if (standing.PreviousLap.GapLaps > 1)
                            output[44] += translation["laps"];
                        else
                            output[44] += translation["lap"];
                    }
                    else
                    {
                        output[44] = translation["behind"] +Utils.floatTime2String((standing.PreviousLap.Gap - infront.PreviousLap.Gap), rounding, false);
                    }
                }
                else
                {
                    if (standing.FastestLap <= 1)
                    {
                        output[44] = translation["invalid"];
                    }
                    else
                    {
                        output[44] = translation["behind"] +Utils.floatTime2String((standing.FastestLap - infront.FastestLap), rounding, false);
                    }
                }

                output[44] = translation["behind"] +Utils.floatTime2String((standing.PreviousLap.Gap - infront.PreviousLap.Gap), rounding, false);
            }
            else
            {

                if (session.Type == SessionTypes.race)
                {
                    output[44] = ""; //Utils.floatTime2String((float)standing.CurrentLap.SessionTime, rounding, true); //translation["leader"];
                }
                else
                {
                    output[44] =Utils.floatTime2String(standing.FastestLap, rounding, false);
                }
            }

            if (session.Type == SessionTypes.race)
            {
                output[23] = translation["behind"] + standing.GapLive_HR(rounding);
                output[24] = translation["behind"] + standing.IntervalLive_HR(rounding);
            }
            else
            {
                output[23] = output[18];
                output[24] = output[22];
            }

            // points
            if (SharedData.externalCurrentPoints.ContainsKey(standing.Driver.UserId))
            {
                output[59] = SharedData.externalCurrentPoints[standing.Driver.UserId].ToString();
                int pos = 0;
                foreach (KeyValuePair<int, int> item in SharedData.externalCurrentPoints.OrderByDescending(key => key.Value))
                {
                    pos++;
                    if (item.Key == standing.Driver.UserId)
                    {
                        output[60] = pos.ToString();
                        output[61] = ordinate(pos);
                        break;
                    }
                }
            }
            else
            {
                output[59] = "0";
                output[60] = SharedData.externalCurrentPoints.Count().ToString();
                output[61] = ordinate(SharedData.externalCurrentPoints.Count());
            }

            int classlivepos = session.getClassLivePosition(standing.Driver);
            output[64] = classlivepos.ToString();
            output[65] = ordinate(classlivepos);

            // interval followed
            if(standing.DistanceToFollowed < 0)
                output[67] = translation["behind"] + Theme.round(standing.IntervalToFollowedLive, rounding);
            else
                output[67] = translation["ahead"] + Theme.round(standing.IntervalToFollowedLive, rounding);

            string[] extrenal;
            if (SharedData.externalData.ContainsKey(standing.Driver.UserId))
            {
                extrenal = SharedData.externalData[standing.Driver.UserId];
            }
            else
                extrenal = new string[0];


            

            string[] merged = new string[output.Length + extrenal.Length];
            Array.Copy(output, 0, merged, 0, output.Length);
            Array.Copy(extrenal, 0, merged, output.Length, extrenal.Length);

            return merged;
        }
예제 #5
0
파일: theme.cs 프로젝트: CloseUpDK/iRTVO
        public string[] getSessionstateFormats(SessionInfo session, Int32 rounding)
        {
            string[] output = new string[33] {
                session.LapsTotal.ToString(),
                session.LapsRemaining.ToString(),
               Utils.floatTime2String((float)session.SessionLength, rounding, true),
               Utils.floatTime2String((float)session.TimeRemaining, rounding, true),
                "",
               Utils.floatTime2String((float)session.Time, rounding, true),
                "",
                SharedData.Track.Name,
                round(SharedData.Track.Length * 0.6214 / 1000, rounding),
                round(SharedData.Track.Length / 1000, rounding),
                session.Cautions.ToString(),
                session.CautionLaps.ToString(),
                session.LeadChanges.ToString(),
                "",
                (session.LapsComplete + 1).ToString(),
                SharedData.Track.Turns.ToString(),
                SharedData.Track.City,
                SharedData.Track.Country,
                Math.Round(SharedData.Track.Altitude).ToString(),
                translation[SharedData.Track.Sky],
                Math.Round(SharedData.Track.TrackTemperature, rounding).ToString(),
                Math.Round(SharedData.Track.AirTemperature, rounding).ToString(),
                SharedData.Track.Humidity.ToString(),
                SharedData.Track.Fog.ToString(),
                Math.Round(SharedData.Track.AirPressure, rounding).ToString(),
                Math.Round(SharedData.Track.WindSpeed, rounding).ToString(),
                Math.Round(360 * SharedData.Track.WindDirection / (2*Math.PI), rounding).ToString(),
                Math.Round(SharedData.Track.Altitude * 3.281, rounding).ToString(),
                Math.Round(SharedData.Track.TrackTemperature * 9/5 + 32, rounding).ToString(),
                Math.Round(SharedData.Track.AirTemperature * 9/5 + 32, rounding).ToString(),
                Math.Round(SharedData.Track.AirPressure * 1.333224, rounding).ToString(),
                Math.Round(SharedData.Track.WindSpeed * 1.943844, rounding).ToString(),
                Math.Round(SharedData.Track.WindSpeed * 3.6, rounding).ToString(),
            };

            if (session.SessionLength == float.MaxValue)
                output[2] = "-.--";

            if(session.TimeRemaining > 600000)
                output[3] = "-.--";

            if ((session.LapsComplete) < 0)
                output[4] = "0";
            else
                output[4] = session.LapsComplete.ToString();

            // lap counter
            if (session.LapsTotal == Int32.MaxValue || session.LapsTotal < 1)
            {
                if (session.State == SessionStates.checkered) // session ending
                    output[6] = translation["finishing"];
                else // normal
                    output[6] =Utils.floatTime2String((float)SharedData.Sessions.CurrentSession.TimeRemaining, rounding, true);
            }
            else if (session.State == SessionStates.gridding)
            {
                output[6] = translation["gridding"];
            }
            else if (session.State == SessionStates.pacing)
            {
                output[6] = translation["pacelap"];
            }
            else
            {
                int currentlap = session.LapsComplete;

                if (session.LapsRemaining < 1 && session.LapsComplete > 0)
                {
                    output[6] = translation["finishing"];
                }
                else if (session.LapsRemaining == 1)
                {
                    output[6] = translation["finallap"];
                }
                else if (session.LapsRemaining <= SharedData.settings.LapCountdownFrom)
                { // x laps remaining
                    output[6] = String.Format("{0} {1} {2}",
                        session.LapsRemaining,
                        translation["laps"],
                        translation["remaining"]
                    );
                }
                else // normal behavior
                {
                    if (currentlap < 0)
                        currentlap = 0;

                    output[6] = String.Format("{0} {1} {2} {3}",
                        translation["lap"],
                        (currentlap + 1),
                        translation["of"],
                        session.LapsTotal
                    );

                }
            }

            switch (session.Type)
            {
                case SessionTypes.race:
                    output[13] = translation["race"];
                    break;
                case SessionTypes.qualify:
                    output[13] = translation["qualify"];
                    break;
                case SessionTypes.practice:
                    output[13] = translation["practice"];
                    break;
                default:
                    output[13] = "";
                    break;
            }

            return output;
        }
예제 #6
0
파일: theme.cs 프로젝트: CloseUpDK/iRTVO
        public string formatFollowedText(LabelProperties label, StandingsItem standing, SessionInfo session)
        {
            string output = "";

            Dictionary<string, int> formatMap = new Dictionary<string, int>()
            {
                {"fullname", 0},
                {"shortname", 1},
                {"initials", 2},
                {"license", 3},
                {"club", 4},
                {"car", 5},
                {"class", 6},
                {"carnum", 7},
                {"fastlap", 8},
                {"prevlap", 9},
                {"curlap", 10},
                {"lapnum", 11},
                {"speedfast_mph", 12},
                {"speedprev_mph", 13},
                {"speedfast_kph", 14},
                {"speedprev_kph", 15},
                {"position", 16},
                {"position_ord", 17},
                {"gap", 18},
                {"lapsled", 19},
                {"driverid", 20},
                {"interval", 21},
                {"interval_time", 22},
                {"livegap", 23},
                {"liveinterval", 24},
                {"livespeed_kph", 25},
                {"livespeed_mph", 26},
                {"sector1", 27},
                {"sector2", 28},
                {"sector3", 29},
                {"pitstops", 30},
                {"pitstoptime", 31},
                {"sector1_speed_kph", 32},
                {"sector2_speed_kph", 33},
                {"sector3_speed_kph", 34},
                {"sector1_speed_mph", 35},
                {"sector2_speed_mph", 36},
                {"sector3_speed_mph", 37},
                {"positiongain", 38},
                {"classposition", 39},
                {"classposition_ord", 40},
                {"classpositiongain", 41},
                {"classgap", 42},
                {"classlivegap", 43},
                {"classinterval", 44},
                {"classliveinterval", 45},
                {"classlapsled", 46},
                {"startposition", 47},
                {"classstartposition", 48},
                {"classstartposition_ord", 49},
                {"startposition_ord", 50},
                {"highestposition", 51},
                {"highestposition_ord", 52},
                {"lowestposition", 53},
                {"lowestposition_ord", 54},
                {"classhighestposition", 55},
                {"classhighestposition_ord", 56},
                {"classlowestposition", 57},
                {"classlowestposition_ord", 58},
                {"points", 59},
                {"points_pos", 60},
                {"points_pos_ord", 61},
                {"liveposition", 62},
                {"liveposition_ord", 63},
                {"classliveposition", 64},
                {"classliveposition_ord", 65},
                {"irating", 66},
                {"liveintervalfollowed", 67},
                {"inpit",68},
                {"teamid",69},              // KJ: new text property
                {"teamname",70},            // KJ: new text property
            };

            int start, end, end2;
            StringBuilder t = new StringBuilder(label.text);

            // replace strings with numbers
            foreach (KeyValuePair<string, int> pair in formatMap)
            {
                t.Replace("{" + pair.Key + "}", "{" + pair.Value + "}");
                // KJ: there could be a dependent text property usage
                t.Replace("|" + pair.Key + "}", "|" + pair.Value + "}");
            }

            // replace external strings with numbers
            int maxExternelData = 0;
            if (SharedData.externalData.ContainsKey(standing.Driver.UserId))
            {
                for (int i = 0; i < SharedData.externalData[standing.Driver.UserId].Length; i++)
                {
                    t.Replace("{external:" + i + "}", "{" + (formatMap.Keys.Count + i) + "}");
                    // KJ: there could be a dependent text property usage
                    foreach ( KeyValuePair<string, int> pair in formatMap )
                    {
                        t.Replace("{external:" + i + "|" + pair.Value + "}", "{" + (formatMap.Keys.Count + i) + "}");
                    }
                }
                maxExternelData = Math.Max(maxExternelData, SharedData.externalData[standing.Driver.UserId].Length);
            }

            // remove leftovers
            string format = t.ToString();
            do
            {
                start = format.IndexOf("{external", 0);
                if (start >= 0)
                {
                    end = format.IndexOf('}', start) + 1;
                    end2 = format.IndexOf('|', start) + 1;

                    if (end2 < end && end2 > start)
                    {
                        start++;
                        end = end2;
                    }

                    format = format.Remove(start, end - start);
                }
            } while (start >= 0);

            t = new StringBuilder(format);

            // run scripts
            if (label.text.Contains("{script:"))
            {
                String[] scripts = SharedData.scripting.Scripts;
                foreach(String script in scripts) {
                    String text = t.ToString();
                    do
                    {
                        start = text.IndexOf("{script:" + script + ":", 0);
                        // if script name found
                        if (start >= 0)
                        {
                            end = text.IndexOf('}', start) + 1;
                            // if ending found
                            if (end > start)
                            {
                                String method = text.Substring(start + script.Length + 9, end - start - script.Length - 10);
                                String result = SharedData.scripting.getDriverInfo(script, method, standing, session, label.rounding);                                
                                t.Replace("{script:" + script + ":" + method + "}",result );
                            }
                        }
                        text = t.ToString();
                    } while (t.ToString().Contains("{script:" + script + ":"));
                }
            }

            // remove leftovers
            format = t.ToString();
            do
            {
                start = format.IndexOf("{script", 0);
                if (start >= 0)
                {
                    end = format.IndexOf('}', start) + 1;
                    logger.Warn("Script Call not found: {0} ", format.Substring(start,end-start));
                    format = format.Remove(start, end - start);
                    
                }
            } while (start >= 0);


            if (standing.Driver.CarIdx < 0)
            {
                output = String.Format(format, getFollowedFormats(standing, session, label.rounding));
            }
            else if (SharedData.themeDriverCache[standing.Driver.CarIdx][label.rounding] == null)
            {
                string[] cache = getFollowedFormats(standing, session, label.rounding);
                SharedData.themeDriverCache[standing.Driver.CarIdx][label.rounding] = cache;
                try
                {
                    output = String.Format(format, cache);
                }
                catch (FormatException)
                {
                    output = "[invalid]";
                }
                SharedData.cacheMiss++;

            }
            else
            {
                try
                {
                    output = String.Format(format, SharedData.themeDriverCache[standing.Driver.CarIdx][label.rounding]);
                }
                catch (FormatException)
                {
                    output = "[invalid]";
                }

                SharedData.cacheHit++;
            }

            output = output.Replace("\\n", System.Environment.NewLine);

            if (label.uppercase)
                return output.ToUpper();
            else
                return output;
        }
예제 #7
0
            public webtimingDriver(StandingsItem driver, SessionInfo session)
            {
                position = driver.PositionLive.ToString();
                name = driver.Driver.Name;

                // KJ: for multi-car/multi-class races and pitting status
                car = "";
                pitting = false;

                // KJ: set name for team events
                if ( driver.Driver.TeamId > 0 )
                {
                    name = driver.Driver.TeamName + " (" + driver.Driver.Shortname + ")";
                }
                number = driver.Driver.NumberPlate;
                car = SharedData.theme.getCar(driver.Driver.CarId);  // KJ: set car
                lap = driver.CurrentLap.LapNum.ToString();
                fastestlap =Utils.floatTime2String(driver.FastestLap, 3, false);
                previouslap =Utils.floatTime2String(driver.PreviousLap.LapTime, 3, false);
                pit = driver.PitStops.ToString();
                lapsled = driver.LapsLed.ToString();
                sectors = new string[0];

                classid = driver.Driver.CarClass.ToString();
                classname = driver.Driver.CarClassName;
                classposition = session.getClassPosition(driver.Driver).ToString();
                classgap = driver.ClassGapLive_HR;
                classinterval = driver.ClassIntervalLive_HR;

                StandingsItem leader = SharedData.Sessions.CurrentSession.FindPosition(1, DataOrders.liveposition);
                StandingsItem infront;

                if(driver.PositionLive <= 1) {
                    infront = new StandingsItem();
                }
                else {
                    infront = SharedData.Sessions.CurrentSession.FindPosition(driver.Position - 1, DataOrders.liveposition);
                }

                if (SharedData.Sessions.CurrentSession.Type == SessionTypes.race
                    /* && (driver.Finished == true || driver.Sector == 0) */)
                {
                    if (infront.PreviousLap.GapLaps > driver.PreviousLap.GapLaps)
                    {
                        interval = (infront.FindLap(driver.PreviousLap.LapNum).LapNum - driver.PreviousLap.LapNum) + " L";
                    }
                    else
                    {
                        interval =Utils.floatTime2String((driver.PreviousLap.Gap - infront.FindLap(driver.PreviousLap.LapNum).Gap), 3, false);
                    }

                    if (driver.PreviousLap.GapLaps > 0)
                    {
                        gap = driver.PreviousLap.GapLaps +" L";
                    }
                    else
                    {
                        gap =Utils.floatTime2String(driver.PreviousLap.Gap, 3, false);
                    }
                }
                else
                {
                    interval =Utils.floatTime2String((driver.FastestLap - infront.FastestLap), 3, false);
                    gap =Utils.floatTime2String((driver.FastestLap - leader.FastestLap), 3, false);
                }

                if (SharedData.SelectedSectors.Count > 0)
                {
                    sectors = new string[SharedData.SelectedSectors.Count];

                    for (int i = 0; i < SharedData.SelectedSectors.Count; i++)
                    {
                        if (driver.Sector <= 0) // first sector, show previous lap times
                        {
                            if (i < driver.PreviousLap.SectorTimes.Count)
                            {
                                Sector sector = driver.PreviousLap.SectorTimes.Find(s => s.Num.Equals(i));
                                if(sector != null)
                                {
                                    sectors[i] =Utils.floatTime2String(sector.Time, 1, false);
                                }
                                else
                                {
                                    sectors[i] = "-.--";
                                }
                            }
                            else
                            {
                                sectors[i] = "-.--";
                            }
                        }
                        else
                        {
                            if (i < driver.CurrentLap.SectorTimes.Count)
                            {
                                Sector sector = driver.CurrentLap.SectorTimes.Find(s => s.Num.Equals(i));
                                if(sector != null)
                                {
                                    sectors[i] =Utils.floatTime2String(sector.Time, 1, false);
                                }
                                else
                                {
                                    sectors[i] = "-.--";
                                }
                            }
                            else
                            {
                                sectors[i] = "-.--";
                            }
                        }
                    }
                }

                if (SharedData.Sessions.CurrentSession.Type == SessionTypes.race &&
                    driver.TrackSurface == SurfaceTypes.NotInWorld && 
                SharedData.allowRetire &&
                (SharedData.Sessions.CurrentSession.Time - driver.OffTrackSince) > 1)
                {
                    retired = true;

                    if (infront.CurrentLap.LapNum > driver.CurrentLap.LapNum)
                    {
                        interval = (infront.CurrentLap.LapNum - driver.CurrentLap.LapNum) + " L";
                    }
                    else
                    {
                        interval =Utils.floatTime2String((driver.PreviousLap.Gap - infront.PreviousLap.Gap), 3, false);
                    }
                    if ((leader.CurrentLap.LapNum - driver.CurrentLap.LapNum) > 0)
                    {
                        gap = leader.CurrentLap.LapNum - driver.CurrentLap.LapNum + " L";
                    }
                    else
                    {
                        gap =Utils.floatTime2String(driver.PreviousLap.Gap, 3, false);
                    }
                }
                else
                {
                    retired = false;
                }
                // KJ: set pitting status
                if (driver.TrackSurface == SurfaceTypes.InPitStall)
                {
                    pitting = true;
                }
                else
                {
                    pitting = false;
                }
            }
예제 #8
0
파일: overlay.cs 프로젝트: CloseUpDK/iRTVO
        private void overlayUpdate(object sender, EventArgs e)
        {
            if (!SharedData.runOverlay)
                return;
            if (SharedData.refreshTheme == true)
            {                

                loadTheme(SharedData.settings.Theme);
                SharedData.Sessions.CurrentSession.Flag = SessionFlags.invalid; // Force flags to be resend to overlay
                overlay.Left = SharedData.settings.OverlayX;
                overlay.Top = SharedData.settings.OverlayY;
                overlay.Width = SharedData.settings.OverlayW;
                overlay.Height = SharedData.settings.OverlayH;

                resizeOverlay(overlay.Width, overlay.Height);
                SharedData.refreshTheme = false;
            }

            // offline functionality hax
            if(SharedData.Sessions.SessionList.Count < 1) {
                SessionInfo dummysession = new SessionInfo();
                SharedData.Sessions.SessionList.Add(dummysession);
            }

            if (SharedData.themeCacheSessionTime != SharedData.currentSessionTime || true)
            {
                SharedData.themeDriverCache = new string[64][][];
                for (Int16 i = 0; i < 64; i++)
                    SharedData.themeDriverCache[i] = new string[4][];
                SharedData.themeSessionStateCache = new Dictionary<int, string[]>();
                SharedData.themeCacheSessionTime = SharedData.currentSessionTime;
                SharedData.cacheFrameCount++;
            }

            // do we allow retirement
            SharedData.allowRetire = true;

            if (SharedData.Sessions.SessionList.Count > 0 && (SharedData.OverlaySession < SharedData.Sessions.SessionList.Count) &&
                SharedData.Sessions.SessionList[SharedData.OverlaySession].State == SessionStates.racing &&
                (SharedData.Sessions.SessionList[SharedData.OverlaySession].LapsRemaining > 0 &&
                    SharedData.Sessions.SessionList[SharedData.OverlaySession].LapsComplete > 1)
                )
            {
                SharedData.allowRetire = true;
            }
            else
            {
                SharedData.allowRetire = false;
            }

            // wait
            SharedData.mutex.WaitOne();
            DateTime mutexLocked = DateTime.Now;

            // calculate points
            SharedData.externalCurrentPoints.Clear();
            SessionInfo racesession = SharedData.Sessions.findSessionByType(SessionTypes.race);
            Double leaderpos = racesession.FindPosition(1, DataOrders.position).CurrentTrackPct;

            foreach (StandingsItem si in racesession.Standings)
            {
                if (SharedData.externalPoints.ContainsKey(si.Driver.UserId))
                {
                    if (si.Position <= SharedData.theme.pointschema.Length /*&&
                        (si.CurrentTrackPct / leaderpos) > SharedData.theme.minscoringdistance */)
                        SharedData.externalCurrentPoints.Add(si.Driver.UserId, SharedData.externalPoints[si.Driver.UserId] + SharedData.theme.pointschema[si.Position - 1]);
                    else
                        SharedData.externalCurrentPoints.Add(si.Driver.UserId, SharedData.externalPoints[si.Driver.UserId]);
                }
            }

            foreach (KeyValuePair<int, int> driver in SharedData.externalPoints)
            {
                if (!SharedData.externalCurrentPoints.ContainsKey(driver.Key))
                {
                    SharedData.externalCurrentPoints.Add(driver.Key, SharedData.externalPoints[driver.Key]);
                }
            }

            // images
            for (int i = 0; i < images.Length; i++)
            {
                if(SharedData.theme.images[i].presistent) {
                    images[i].Visibility = System.Windows.Visibility.Visible;
                }
                else if (SharedData.theme.images[i].visible != visibility2boolean[images[i].Visibility])
                {
#if DEBUG
                    logger.Trace(SharedData.theme.images[i].name);
#endif
                    if (SharedData.theme.images[i].dynamic == true)
                        loadImage(images[i], SharedData.theme.images[i]);
                    
                    images[i].Visibility = boolean2visibility[SharedData.theme.images[i].visible];
                    if (SharedData.theme.images[i].doAnimate)
                    {
                        var controller = ImageBehavior.GetAnimationController(images[i]);
                        if (controller == null)
                            continue;
                        if (SharedData.theme.images[i].visible)
                        {
                            controller.GotoFrame(0);
                            controller.Play();
                        }
                        else
                        {
                            controller.Pause();
                        }
                    }
                }
            }

            // objects
            for (int i = 0; i < SharedData.theme.objects.Length; i++)
            {
                if (SharedData.theme.objects[i].presistent)
                    objects[i].Visibility = System.Windows.Visibility.Visible;
                else if (SharedData.theme.objects[i].visible != visibility2boolean[objects[i].Visibility])
                    objects[i].Visibility = boolean2visibility[SharedData.theme.objects[i].visible];

                int session;

                if (objects[i].Visibility == System.Windows.Visibility.Visible)
                {
                    logger.Debug("Object {0} DataSet {1} DataOrder {2} Labels {3}", SharedData.theme.objects[i].name, SharedData.theme.objects[i].dataset, SharedData.theme.objects[i].dataorder, SharedData.theme.objects[i].labels.Length);
                    switch (SharedData.theme.objects[i].dataset)
                    {
                        case DataSets.standing:
                        case DataSets.points:
                        case DataSets.pit:
                            for (int j = 0; j < SharedData.theme.objects[i].labels.Length; j++) // items
                            {
                                if (SharedData.theme.objects[i].labels[j].session != SessionTypes.none)
                                    session = SharedData.Sessions.findSessionIndexByType(SharedData.theme.objects[i].labels[j].session);
                                else
                                    session = SharedData.OverlaySession;
                                logger.Trace("Session = {0} ({1})", session, SharedData.Sessions.SessionList[session].Type);
                                for (int k = 0; k < SharedData.theme.objects[i].itemCount; k++) // drivers
                                {
                                    int driverPos = 1 + k + ((SharedData.theme.objects[i].itemCount + SharedData.theme.objects[i].skip) * SharedData.theme.objects[i].page) + SharedData.theme.objects[i].labels[j].offset + SharedData.theme.objects[i].offset;
                                    Int32 standingsCount = 0;

                                    if (SharedData.theme.objects[i].dataset == DataSets.standing)
                                    {
                                        if (SharedData.theme.objects[i].carclass == null)
                                            standingsCount = SharedData.Sessions.SessionList[session].Standings.Count;
                                        else
                                            standingsCount = SharedData.Sessions.SessionList[session].getClassCarCount(SharedData.theme.objects[i].carclass);
                                    }
                                    else if (SharedData.theme.objects[i].dataset == DataSets.points)
                                        standingsCount = SharedData.externalCurrentPoints.Count;

                                    if (SharedData.theme.objects[i].dataset == DataSets.pit)
                                    {

                                        standingsCount = SharedData.Sessions.SessionList[session].Standings.Count(c => c.TrackSurface == SurfaceTypes.InPitStall);
                                        logger.Debug("Pit detecteed count={0}", standingsCount);
                                    }

                                    SharedData.theme.objects[i].pagecount = (int)Math.Ceiling((Double)standingsCount / (Double)SharedData.theme.objects[i].itemCount);

                                    if (SharedData.theme.objects[i].carclass != null)
                                    {
                                        if ((SharedData.theme.objects[i].page + 1) * (SharedData.theme.objects[i].itemCount + SharedData.theme.objects[i].skip) >= SharedData.Sessions.SessionList[session].getClassCarCount(SharedData.theme.objects[i].carclass) ||
                                            (SharedData.theme.objects[i].maxpages > 0 && SharedData.theme.objects[i].page >= SharedData.theme.objects[i].maxpages - 1))
                                        {
                                            SharedData.lastPage[i] = true;
                                        }
                                    }
                                    else
                                    {
                                        if ((SharedData.theme.objects[i].page + 1) * (SharedData.theme.objects[i].itemCount + SharedData.theme.objects[i].skip) >= standingsCount ||
                                            (SharedData.theme.objects[i].maxpages > 0 && SharedData.theme.objects[i].page >= SharedData.theme.objects[i].maxpages - 1))
                                        {
                                            SharedData.lastPage[i] = true;
                                        }
                                    }

                                    if (driverPos <= standingsCount)
                                    {
                                        labels[i][(j * SharedData.theme.objects[i].itemCount) + k].Visibility = System.Windows.Visibility.Visible;                                        

                                        StandingsItem driver = new StandingsItem();

                                        if (SharedData.theme.objects[i].dataset == DataSets.standing)
                                        {
                                            if (SharedData.Sessions.SessionList[session].Type != SessionTypes.race && SharedData.theme.objects[i].dataorder == DataOrders.liveposition)
                                                driver = SharedData.Sessions.SessionList[session].FindPosition(driverPos, DataOrders.position, SharedData.theme.objects[i].carclass);
                                            else
                                                driver = SharedData.Sessions.SessionList[session].FindPosition(driverPos, SharedData.theme.objects[i].dataorder, SharedData.theme.objects[i].carclass);
                                        }
                                        else if (SharedData.theme.objects[i].dataset == DataSets.points)
                                        {
                                            KeyValuePair<int, int> item = SharedData.externalCurrentPoints.OrderByDescending(key => key.Value).Skip(driverPos - 1).FirstOrDefault();
                                            driver = SharedData.Sessions.SessionList[session].Standings.SingleOrDefault(si => si.Driver.UserId == item.Key);
                                            if (driver == null)
                                            {
                                                driver = new StandingsItem();
                                                driver.Driver.UserId = item.Key;
                                            }
                                        }

                                        if (SharedData.theme.objects[i].dataset == DataSets.pit)
                                        {
                                            var tmpItem = from st in SharedData.Sessions.SessionList[session].Standings
                                                          where
                                                              st.TrackSurface == SurfaceTypes.InPitStall
                                                          select st;
                                            driver = tmpItem.Skip(driverPos - 1).FirstOrDefault();
                                            logger.Debug("PIT driver==null = {0}", driver);
                                            if ( driver == null )
                                                continue;

                                        }

                                        labels[i][(j * SharedData.theme.objects[i].itemCount) + k].Content = SharedData.theme.formatFollowedText(
                                            SharedData.theme.objects[i].labels[j],
                                            driver,
                                            SharedData.Sessions.SessionList[session]);

                                        if (SharedData.theme.objects[i].labels[j].dynamic == true)
                                        {
                                            Theme.LabelProperties label = new Theme.LabelProperties();
                                            label.text = SharedData.theme.objects[i].labels[j].backgroundImage;

                                            string filename = Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.formatFollowedText(
                                                label,
                                                driver,
                                                SharedData.Sessions.SessionList[session]
                                            );

                                            // labels[i][(j * SharedData.theme.objects[i].itemCount) + k].Background = new SolidColorBrush(System.Windows.Media.Colors.Transparent);

                                            labels[i][(j * SharedData.theme.objects[i].itemCount) + k].Background = SharedData.theme.DynamicBrushCache.GetDynamicBrush(filename,
                                                Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.objects[i].labels[j].defaultBackgroundImage, 
                                                SharedData.theme.objects[i].labels[j].backgroundColor);                                            
                                        }
                                        else 
                                        {
                                            labels[i][(j * SharedData.theme.objects[i].itemCount) + k].Background = SharedData.theme.DynamicBrushCache.GetDynamicBrush( 
                                                Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.objects[i].labels[j].backgroundImage,
                                                SharedData.theme.objects[i].labels[j].backgroundColor);
                                        }
                                    }
                                    else 
                                    {
                                        labels[i][(j * SharedData.theme.objects[i].itemCount) + k].Visibility = System.Windows.Visibility.Hidden;
                                        labels[i][(j * SharedData.theme.objects[i].itemCount) + k].Content = null;
                                        labels[i][(j * SharedData.theme.objects[i].itemCount) + k].Background = SharedData.theme.objects[i].labels[j].backgroundColor;
                                    }
                                }
                            }
                            break;
                        case DataSets.sessionstate:
                            for (int j = 0; j < SharedData.theme.objects[i].labels.Length; j++)
                            {
                                if (SharedData.theme.objects[i].labels[j].session != SessionTypes.none)
                                    session = SharedData.Sessions.findSessionIndexByType(SharedData.theme.objects[i].labels[j].session);
                                else
                                    session = SharedData.OverlaySession;

                                labels[i][j].Content = SharedData.theme.formatSessionstateText(
                                        SharedData.theme.objects[i].labels[j],
                                        session);
                                if (SharedData.theme.objects[i].labels[j].dynamic == true)
                                {
                                    Theme.LabelProperties label = new Theme.LabelProperties();
                                    label.text = SharedData.theme.objects[i].labels[j].backgroundImage;

                                    string filename = Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.formatSessionstateText(
                                        label,
                                        session);

                                    // labels[i][(j * SharedData.theme.objects[i].itemCount) + k].Background = new SolidColorBrush(System.Windows.Media.Colors.Transparent);

                                    labels[i][j].Background = SharedData.theme.DynamicBrushCache.GetDynamicBrush(filename,
                                        Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.objects[i].labels[j].defaultBackgroundImage,
                                        SharedData.theme.objects[i].labels[j].backgroundColor);
                                }
                                else
                                {
                                    labels[i][j].Background = SharedData.theme.DynamicBrushCache.GetDynamicBrush(
                                        Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.objects[i].labels[j].backgroundImage,
                                        SharedData.theme.objects[i].labels[j].backgroundColor);
                                }
                            }
                            break;
                        default:
                        case DataSets.followed:
                        case DataSets.radio:
                        case DataSets.trigger:
                           
                            for (int j = 0; j < SharedData.theme.objects[i].labels.Length; j++)
                            {
                                if (SharedData.theme.objects[i].labels[j].session != SessionTypes.none)
                                    session = SharedData.Sessions.findSessionIndexByType(SharedData.theme.objects[i].labels[j].session);
                                else
                                    session = SharedData.OverlaySession;

                                int pos;
                                if (SharedData.theme.objects[i].dataorder == DataOrders.liveposition && SharedData.Sessions.SessionList[session].Type == SessionTypes.race)
                                    pos = SharedData.Sessions.SessionList[session].FollowedDriver.PositionLive;
                                else if (SharedData.theme.objects[i].dataorder == DataOrders.trackposition)
                                    pos = 0;
                                else
                                    pos = SharedData.Sessions.SessionList[session].FollowedDriver.Position;

                                int offset = SharedData.theme.objects[i].labels[j].offset + SharedData.theme.objects[i].offset;

                                switch (SharedData.theme.objects[i].dataset)
                                {
                                    case DataSets.trigger:
                                        labels[i][j].Content = SharedData.theme.formatFollowedText(SharedData.theme.objects[i].labels[j],
                                                        SharedData.Sessions.SessionList[session].FindDriver(SharedData.currentTriggerCarIdx),
                                                        SharedData.Sessions.SessionList[session]);
                                        break;
                                    case DataSets.radio:
                                        labels[i][j].Content = SharedData.theme.formatFollowedText(SharedData.theme.objects[i].labels[j],
                                                        SharedData.Sessions.SessionList[session].FindDriver(SharedData.currentRadioCarIdx),
                                                        SharedData.Sessions.SessionList[session]);
                                        break;
                                    default:
                                        labels[i][j].Content = SharedData.theme.formatFollowedText(SharedData.theme.objects[i].labels[j],
                                            SharedData.Sessions.SessionList[session].FindPosition(pos + offset, SharedData.theme.objects[i].dataorder),
                                            SharedData.Sessions.SessionList[session]);
                                        break;
                                }
                                

                                if (SharedData.theme.objects[i].labels[j].dynamic == true)
                                {
                                    Theme.LabelProperties label = new Theme.LabelProperties();
                                    label.text = SharedData.theme.objects[i].labels[j].backgroundImage;

                                    string filename = Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.formatFollowedText(
                                        label,
                                        SharedData.Sessions.SessionList[session].FindPosition(pos + offset, SharedData.theme.objects[i].dataorder),
                                        SharedData.Sessions.SessionList[session]
                                    );

                                    labels[i][j].Background = SharedData.theme.DynamicBrushCache.GetDynamicBrush(filename,
                                                Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.objects[i].labels[j].defaultBackgroundImage, 
                                                SharedData.theme.objects[i].labels[j].backgroundColor);                                            
                                                                           
                                }
                            }
                            break;
                    }
                }
                else
                {
                    SharedData.theme.objects[i].page = -1;
                    SharedData.lastPage[i] = false;
                }
            }

            // tickers
            for (int i = 0; i < SharedData.theme.tickers.Length; i++)
            {
                if (SharedData.theme.tickers[i].presistent)
                {
                    tickers[i].Visibility = System.Windows.Visibility.Visible;
                }
                else if (SharedData.theme.tickers[i].visible != visibility2boolean[tickers[i].Visibility])
                {
                    tickers[i].Visibility = boolean2visibility[SharedData.theme.tickers[i].visible];
                    tickerStackpanels[i].Margin = new Thickness(0 - tickerStackpanels[i].ActualWidth, 0, 0, 0);
                }

                if (tickers[i].Visibility == System.Windows.Visibility.Visible)
                {
                    switch (SharedData.theme.tickers[i].dataset)
                    {
                        case DataSets.standing:
                            if (tickerStackpanels[i].Margin.Left + tickerStackpanels[i].ActualWidth <= 0)
                            {
                                
                                // Create tickers
                                int length;
                                if (SharedData.theme.tickers[i].carclass != null)
                                    length = SharedData.Sessions.SessionList[SharedData.OverlaySession].getClassCarCount(SharedData.theme.tickers[i].carclass);
                                else
                                    length = SharedData.Sessions.SessionList[SharedData.OverlaySession].Standings.Count;
                                    
                                tickerScrolls[i].Children.Clear();
                                tickerStackpanels[i].Children.Clear();

                                tickerStackpanels[i] = new StackPanel();
                                tickerStackpanels[i].Margin = new Thickness(SharedData.theme.tickers[i].width, 0, 0, 0);
                                tickerStackpanels[i].Orientation = Orientation.Horizontal;

                                if (SharedData.theme.tickers[i].fillVertical)
                                    tickerRowpanels[i] = new StackPanel[length];

                                //tickers[i].Children.Add(tickerStackpanels[i]);
                                tickerScrolls[i].Children.Add(tickerStackpanels[i]);
                                tickerLabels[i] = new Label[SharedData.Sessions.SessionList[SharedData.OverlaySession].Standings.Count * SharedData.theme.tickers[i].labels.Length];

                                // add headers 
                                if (SharedData.theme.tickers[i].header.text != null)
                                {
                                    tickerHeaders[i] = DrawLabel(SharedData.theme.tickers[i].header);
                                    tickerHeaders[i].Content = SharedData.theme.tickers[i].header.text;
                                    tickerHeaders[i].Width = Double.NaN;
                                    tickerStackpanels[i].Children.Add(tickerHeaders[i]);
                                }

                                for (int j = 0; j < length; j++) // drivers
                                {
                                    if (SharedData.theme.tickers[i].fillVertical)
                                    {
                                        tickerRowpanels[i][j] = new StackPanel();
                                        tickerStackpanels[i].Children.Add(tickerRowpanels[i][j]);
                                    }

                                    for (int k = 0; k < SharedData.theme.tickers[i].labels.Length; k++) // labels
                                    {
                                        tickerLabels[i][(j * SharedData.theme.tickers[i].labels.Length) + k] = DrawLabel(SharedData.theme.tickers[i].labels[k]);
                                        tickerLabels[i][(j * SharedData.theme.tickers[i].labels.Length) + k].Content = SharedData.theme.formatFollowedText(
                                            SharedData.theme.tickers[i].labels[k],
                                            SharedData.Sessions.SessionList[SharedData.OverlaySession].FindPosition(j + 1, SharedData.theme.tickers[i].dataorder, SharedData.theme.tickers[i].carclass),
                                            SharedData.Sessions.SessionList[SharedData.OverlaySession]);
                                        if (SharedData.theme.tickers[i].labels[k].width == 0)
                                            tickerLabels[i][(j * SharedData.theme.tickers[i].labels.Length) + k].Width = Double.NaN;

                                        if (SharedData.theme.tickers[i].labels[k].dynamic == true)
                                        {
                                            Theme.LabelProperties label = new Theme.LabelProperties();
                                            label.text = SharedData.theme.tickers[i].labels[k].backgroundImage;

                                            string filename = Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.formatFollowedText(
                                                label,
                                                SharedData.Sessions.SessionList[SharedData.OverlaySession].FindPosition(j + 1, SharedData.theme.tickers[i].dataorder),
                                                SharedData.Sessions.SessionList[SharedData.OverlaySession]
                                            );

                                            tickerLabels[i][(j * SharedData.theme.tickers[i].labels.Length) + k].Background = SharedData.theme.DynamicBrushCache.GetDynamicBrush(filename,
                                                Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.tickers[i].labels[k].defaultBackgroundImage,
                                                SharedData.theme.tickers[i].labels[k].backgroundColor);                                            
                                                                                   
                                        }

                                        if (SharedData.theme.tickers[i].fillVertical)
                                            tickerRowpanels[i][j].Children.Add(tickerLabels[i][(j * SharedData.theme.tickers[i].labels.Length) + k]);
                                        else
                                            tickerStackpanels[i].Children.Add(tickerLabels[i][(j * SharedData.theme.tickers[i].labels.Length) + k]);

                                    }
                                }
                                    
                                // add footers
                                if (SharedData.theme.tickers[i].footer.text != null)
                                {
                                    tickerFooters[i] = DrawLabel(SharedData.theme.tickers[i].footer);
                                    tickerFooters[i].Content = SharedData.theme.tickers[i].footer.text;
                                    tickerFooters[i].Width = Double.NaN;
                                    tickerStackpanels[i].Children.Add(tickerFooters[i]);
                                }

                                if(this.FindName("tickerScroll" + i) == null)
                                    this.RegisterName("tickerScroll" + i, tickerStackpanels[i]);

                                Storyboard.SetTargetName(tickerAnimations[i], "tickerScroll" + i);
                                Storyboard.SetTargetProperty(tickerAnimations[i], new PropertyPath(StackPanel.MarginProperty));
                                tickerAnimations[i].From = new Thickness(SharedData.theme.tickers[i].width + tickerStackpanels[i].ActualWidth, 0, 0, 0);
                                tickerAnimations[i].To = new Thickness(0);
                                
                                tickerAnimations[i].RepeatBehavior = System.Windows.Media.Animation.RepeatBehavior.Forever;

                                tickerStoryboards[i].Children.Clear();
                                tickerStoryboards[i].Children.Add(tickerAnimations[i]);

                                tickerScrolls[i].Margin = new Thickness(0, 0, 0, 0);


                            }
                            else if (tickerScrolls[i].Margin.Left >= 0 && SharedData.tickerReady[i])
                            {
                                
                                tickerScrolls[i].Margin = new Thickness(0 - tickerStackpanels[i].ActualWidth, 0, 0, 0);
                                tickerAnimations[i].From = new Thickness(SharedData.theme.tickers[i].width + tickerStackpanels[i].ActualWidth, 0, 0, 0);
                                tickerAnimations[i].To = new Thickness(0);
                                tickerAnimations[i].Duration = TimeSpan.FromSeconds(tickerAnimations[i].From.Value.Left / (60 * SharedData.theme.tickers[i].speed));
                                tickerStoryboards[i].Begin(this,true);
                            }
                            else
                            {
                                
                                // update data
                                
                                tickerAnimations[i].From = new Thickness(SharedData.theme.tickers[i].width + tickerStackpanels[i].ActualWidth, 0, 0, 0);
                                tickerAnimations[i].To = new Thickness(0);
                                
                                Double margin = tickerStackpanels[i].Margin.Left; // +tickerScrolls[i].Margin.Left;
                                int length;
                                if (SharedData.theme.tickers[i].carclass != null)
                                    length = SharedData.Sessions.SessionList[SharedData.OverlaySession].getClassCarCount(SharedData.theme.tickers[i].carclass);
                                else
                                    length = SharedData.Sessions.SessionList[SharedData.OverlaySession].Standings.Count;
                                
                                for (int j = 0; j < length; j++) // drivers
                                {
                                    for (int k = 0; k < SharedData.theme.tickers[i].labels.Length; k++) // labels
                                    {
                                        if ((j * SharedData.theme.tickers[i].labels.Length) + k < tickerLabels[i].Length)
                                        {
                                            // TODO: This means tickers only get updated once every repeat
                                            if (margin > (0 - tickerLabels[i][(j * SharedData.theme.tickers[i].labels.Length) + k].DesiredSize.Width) && margin <= SharedData.theme.tickers[i].width)
                                            {

                                                tickerLabels[i][(j * SharedData.theme.tickers[i].labels.Length) + k].Content = SharedData.theme.formatFollowedText(
                                                    SharedData.theme.tickers[i].labels[k],
                                                    SharedData.Sessions.SessionList[SharedData.OverlaySession].FindPosition(j + 1, SharedData.theme.tickers[i].dataorder, SharedData.theme.tickers[i].carclass),
                                                    SharedData.Sessions.SessionList[SharedData.OverlaySession]);

                                                // fixing label width screwing up ticker.From
                                                if (tickerLabels[i][(j * SharedData.theme.tickers[i].labels.Length) + k].Content.ToString() != "")
                                                    SharedData.tickerReady[i] = true;

                                                if (SharedData.theme.tickers[i].labels[k].dynamic == true)
                                                {
                                                    Theme.LabelProperties label = new Theme.LabelProperties();
                                                    label.text = SharedData.theme.tickers[i].labels[k].backgroundImage;

                                                    string filename = Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.formatFollowedText(
                                                        label,
                                                        SharedData.Sessions.SessionList[SharedData.OverlaySession].FindPosition(j + 1, SharedData.theme.tickers[i].dataorder),
                                                        SharedData.Sessions.SessionList[SharedData.OverlaySession]
                                                    );

                                                    tickerLabels[i][(j * SharedData.theme.tickers[i].labels.Length) + k].Background = SharedData.theme.DynamicBrushCache.GetDynamicBrush(filename,
                                                        Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.tickers[i].labels[k].defaultBackgroundImage,
                                                        SharedData.theme.tickers[i].labels[k].backgroundColor);


                                                }
                                            }

                                            if (SharedData.theme.tickers[i].fillVertical == false)
                                            {
                                                //margin += tickerLabels[i][(j * SharedData.theme.tickers[i].labels.Length) + k].DesiredSize.Width;
                                            }
                                        }
                                    }
                                
                                    if (SharedData.theme.tickers[i].fillVertical == true && j < tickerRowpanels[i].Length)
                                    {
                                        //margin += tickerRowpanels[i][j].DesiredSize.Width;
                                    }                                    
                                }
                            }
                            break;
                        case DataSets.sessionstate:
                            if (/*tickerScrolls[i].Margin.Left +*/ tickerStackpanels[i].ActualWidth + tickerStackpanels[i].Margin.Left <= 0)
                            {
                                // create
                                //tickerScrolls[i].Children.Clear();
                                tickerStackpanels[i].Children.Clear();

                                tickerStackpanels[i] = new StackPanel();
                                tickerStackpanels[i].Margin = new Thickness(SharedData.theme.tickers[i].width, 0, 0, 0);

                                if (SharedData.theme.tickers[i].fillVertical)
                                    tickerStackpanels[i].Orientation = Orientation.Vertical;
                                else
                                    tickerStackpanels[i].Orientation = Orientation.Horizontal;

                                //tickerScrolls[i].Children.Add(tickerStackpanels[i]);
                                tickers[i].Children.Add(tickerStackpanels[i]);
                                tickerLabels[i] = new Label[SharedData.theme.tickers[i].labels.Length];

                                // add headers 
                                if (SharedData.theme.tickers[i].header.text != null)
                                {
                                    tickerHeaders[i] = DrawLabel(SharedData.theme.tickers[i].header);
                                    tickerHeaders[i].Content = SharedData.theme.tickers[i].header.text;
                                    tickerHeaders[i].Width = Double.NaN;
                                    tickerStackpanels[i].Children.Add(tickerHeaders[i]);
                                }

                                for (int j = 0; j < SharedData.theme.tickers[i].labels.Length; j++) // drivers
                                {
                                    tickerLabels[i][j] = DrawLabel(SharedData.theme.tickers[i].labels[j]);
                                    tickerLabels[i][j].Content = SharedData.theme.formatSessionstateText(
                                        SharedData.theme.tickers[i].labels[j],
                                        SharedData.OverlaySession);
                                    if (SharedData.theme.tickers[i].labels[j].width == 0)
                                        tickerLabels[i][j].Width = Double.NaN;

                                    tickerStackpanels[i].Children.Add(tickerLabels[i][j]);
                                }

                                // add footers
                                if (SharedData.theme.tickers[i].footer.text != null)
                                {
                                    tickerFooters[i] = DrawLabel(SharedData.theme.tickers[i].footer);
                                    tickerFooters[i].Content = SharedData.theme.tickers[i].footer.text;
                                    tickerFooters[i].Width = Double.NaN;
                                    tickerStackpanels[i].Children.Add(tickerFooters[i]);
                                }

                                /*
                                if (this.FindName("tickerScroll" + i) == null)
                                    this.RegisterName("tickerScroll" + i, tickerStackpanels[i]);

                                Storyboard.SetTargetName(tickerAnimations[i], "tickerScroll" + i);
                                Storyboard.SetTargetProperty(tickerAnimations[i], new PropertyPath(StackPanel.MarginProperty));
                                tickerAnimations[i].From = new Thickness(SharedData.theme.tickers[i].width + tickerStackpanels[i].ActualWidth, 0, 0, 0);
                                tickerAnimations[i].To = new Thickness(0);
                                tickerAnimations[i].RepeatBehavior = System.Windows.Media.Animation.RepeatBehavior.Forever;

                                tickerStoryboards[i].Children.Clear();
                                tickerStoryboards[i].Children.Add(tickerAnimations[i]);

                                tickerScrolls[i].Margin = new Thickness(0, 0, 0, 0);
                                */

                            }
                            else
                            {
                                /*
                                if (tickerScrolls[i].Margin.Left == 0)
                                {
                                    tickerScrolls[i].Margin = new Thickness(0 - tickerStackpanels[i].ActualWidth, 0, 0, 0);
                                    tickerAnimations[i].From = new Thickness(SharedData.theme.tickers[i].width + tickerStackpanels[i].ActualWidth, 0, 0, 0);
                                    tickerAnimations[i].Duration = TimeSpan.FromSeconds(tickerAnimations[i].From.Value.Left / 120);
                                    tickerStoryboards[i].Begin(this);
                                }
                                */

                                // update data
                                Double margin = tickerStackpanels[i].Margin.Left; // + tickerScrolls[i].Margin.Left;
                                for (int k = 0; k < SharedData.theme.tickers[i].labels.Length; k++) // labels
                                {
                                    if (k < tickerLabels[i].Length)
                                    {
                                        if (margin > (0 - tickerLabels[i][k].DesiredSize.Width) && margin < SharedData.theme.tickers[i].width)
                                        {
                                            tickerLabels[i][k].Content = SharedData.theme.formatSessionstateText(
                                                SharedData.theme.tickers[i].labels[k],
                                                SharedData.OverlaySession);

                                            if (SharedData.theme.tickers[i].labels[k].dynamic == true)
                                            {
                                                Theme.LabelProperties label = new Theme.LabelProperties();
                                                label.text = SharedData.theme.tickers[i].labels[k].backgroundImage;

                                                string filename = Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.formatSessionstateText(
                                                    label,
                                                    SharedData.OverlaySession
                                                );

                                                tickerLabels[i][k].Background = SharedData.theme.DynamicBrushCache.GetDynamicBrush(filename,
                                                    Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.tickers[i].labels[k].defaultBackgroundImage,
                                                    SharedData.theme.tickers[i].labels[k].backgroundColor);        
                                                

                                            }
                                        }
                                        margin += tickerLabels[i][k].DesiredSize.Width;
                                    }
                                }
                                /*
                                // old scroll
                                Thickness scroller = tickerStackpanels[i].Margin;
                                scroller.Left -= SharedData.settings.TickerSpeed;
                                tickerStackpanels[i].Margin = scroller;
                                    * */
                            }
                            break;
                        default:
                        case DataSets.followed:
                            if (tickerStackpanels[i].ActualWidth + tickerStackpanels[i].Margin.Left <= 0)
                            {
                                // create
                                //tickerScrolls[i].Children.Clear();
                                tickerStackpanels[i].Children.Clear();

                                tickerStackpanels[i] = new StackPanel();
                                tickerStackpanels[i].Margin = new Thickness(SharedData.theme.tickers[i].width, 0, 0, 0);

                                if (SharedData.theme.tickers[i].fillVertical)
                                    tickerStackpanels[i].Orientation = Orientation.Vertical;
                                else
                                    tickerStackpanels[i].Orientation = Orientation.Horizontal;

                                //tickerScrolls[i].Children.Add(tickerStackpanels[i]);
                                tickers[i].Children.Add(tickerStackpanels[i]);

                                tickerLabels[i] = new Label[SharedData.theme.tickers[i].labels.Length];

                                // add headers 
                                if (SharedData.theme.tickers[i].header.text != null)
                                {
                                    tickerHeaders[i] = DrawLabel(SharedData.theme.tickers[i].header);
                                    tickerHeaders[i].Content = SharedData.theme.tickers[i].header.text;
                                    tickerHeaders[i].Width = Double.NaN;
                                    tickerStackpanels[i].Children.Add(tickerHeaders[i]);
                                }

                                for (int j = 0; j < SharedData.theme.tickers[i].labels.Length; j++) // drivers
                                {
                                    tickerLabels[i][j] = DrawLabel(SharedData.theme.tickers[i].labels[j]);
                                    if (SharedData.theme.tickers[i].labels[j].width == 0)
                                        tickerLabels[i][j].Width = Double.NaN;

                                    tickerStackpanels[i].Children.Add(tickerLabels[i][j]);
                                }

                                // add footers
                                if (SharedData.theme.tickers[i].footer.text != null)
                                {
                                    tickerFooters[i] = DrawLabel(SharedData.theme.tickers[i].footer);
                                    tickerFooters[i].Content = SharedData.theme.tickers[i].footer.text;
                                    tickerFooters[i].Width = Double.NaN;
                                    tickerStackpanels[i].Children.Add(tickerFooters[i]);
                                }

                                /*
                                if (this.FindName("tickerScroll" + i) == null)
                                    this.RegisterName("tickerScroll" + i, tickerStackpanels[i]);

                                Storyboard.SetTargetName(tickerAnimations[i], "tickerScroll" + i);
                                Storyboard.SetTargetProperty(tickerAnimations[i], new PropertyPath(StackPanel.MarginProperty));
                                    
                                tickerAnimations[i].From = new Thickness(SharedData.theme.tickers[i].width, 0, 0, 0);
                                tickerStackpanels[i].Margin = new Thickness(SharedData.theme.tickers[i].width, 0, 0, 0);
                                tickerAnimations[i].To = new Thickness(0);
                                tickerAnimations[i].RepeatBehavior = System.Windows.Media.Animation.RepeatBehavior.Forever;
                                tickerAnimations[i].Duration = TimeSpan.FromSeconds(tickerAnimations[i].From.Value.Left / 120);
                                    
                                tickerStoryboards[i].Children.Clear();
                                tickerStoryboards[i].Children.Add(tickerAnimations[i]);
                                //tickerStoryboards[i].Begin(this);

                                tickerScrolls[i].Margin = new Thickness(0, 0, 0, 0);
                                    * */
                            }
                            else
                            {
                                /*
                                if (tickerScrolls[i].Margin.Left == 0)
                                {
                                        
                                    tickerScrolls[i].Margin = new Thickness(0 - tickerStackpanels[i].ActualWidth, 0, 0, 0);
                                    tickerAnimations[i].From = new Thickness(SharedData.theme.tickers[i].width + tickerStackpanels[i].ActualWidth, 0, 0, 0);
                                    //tickerAnimations[i].To = new Thickness(0);
                                    //tickerAnimations[i].RepeatBehavior = System.Windows.Media.Animation.RepeatBehavior.Forever;
                                    //tickerAnimations[i].Duration = TimeSpan.FromSeconds(tickerAnimations[i].From.Value.Left / 120);
                                    //tickerStackpanels[i].Margin = new Thickness(SharedData.theme.tickers[i].width + (tickerStackpanels[i].ActualWidth * 2), 0, 0, 0);
                                    //tickerStoryboards[i].Begin(this);
                                    //tickerStoryboards[i].Resume(this);

                                }
                                */
                                // update data
                                for (int k = 0; k < SharedData.theme.tickers[i].labels.Length; k++) // labels
                                {
                                    if (k < tickerLabels[i].Length)
                                    {
                                        tickerLabels[i][k].Content = SharedData.theme.formatFollowedText(
                                            SharedData.theme.tickers[i].labels[k],
                                            SharedData.Sessions.SessionList[SharedData.OverlaySession].FollowedDriver,
                                            SharedData.Sessions.SessionList[SharedData.OverlaySession]);

                                        if (SharedData.theme.tickers[i].labels[k].dynamic == true)
                                        {
                                            Theme.LabelProperties label = new Theme.LabelProperties();
                                            label.text = SharedData.theme.tickers[i].labels[k].backgroundImage;

                                            string filename = Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.formatFollowedText(
                                                label,
                                                SharedData.Sessions.SessionList[SharedData.OverlaySession].FollowedDriver,
                                                SharedData.Sessions.SessionList[SharedData.OverlaySession]
                                            );

                                            tickerLabels[i][k].Background = SharedData.theme.DynamicBrushCache.GetDynamicBrush(filename,
                                                   Directory.GetCurrentDirectory() + "\\" + SharedData.theme.path + "\\" + SharedData.theme.tickers[i].labels[k].defaultBackgroundImage,
                                                   SharedData.theme.tickers[i].labels[k].backgroundColor);        

                                        }
                                    }
                                }
                                /*
                                // old scroll
                                Thickness scroller = tickerStackpanels[i].Margin;
                                scroller.Left -= SharedData.settings.TickerSpeed;
                                tickerStackpanels[i].Margin = scroller;
                                    * */
                            }
                            break;
                    }
                }
                    /*
                else if (tickerStackpanels[i].Margin.Left + tickerStackpanels[i].ActualWidth > 0)
                {
                    tickerStackpanels[i].Margin = new Thickness(0 - tickerStackpanels[i].ActualWidth, 0, 0, 0);
                }
                        * */
            }

            // start lights
            /*
            for (int i = 0; i < SharedData.theme.images.Length; i++)
            {
                if (SharedData.theme.images[i].light != Theme.lights.none && SharedData.theme.images[i].visible == true)
                {
                    if (SharedData.Sessions.SessionList[SharedData.overlaySession].StartLight == SessionStartLights.set)
                    {
                        if (SharedData.theme.images[i].light == Theme.lights.red)
                            images[i].Visibility = System.Windows.Visibility.Visible;
                        else
                            images[i].Visibility = System.Windows.Visibility.Hidden;
                    }
                    else if (SharedData.Sessions.SessionList[SharedData.overlaySession].StartLight == SessionStartLights.go)
                    {
                        if (SharedData.theme.images[i].light == Theme.lights.green)
                            images[i].Visibility = System.Windows.Visibility.Visible;
                        else
                            images[i].Visibility = System.Windows.Visibility.Hidden;
                    }
                    else if (SharedData.Sessions.SessionList[SharedData.overlaySession].StartLight == SessionStartLights.off)
                    {
                        if (SharedData.theme.images[i].light == Theme.lights.off)
                            images[i].Visibility = System.Windows.Visibility.Visible;
                        else
                            images[i].Visibility = System.Windows.Visibility.Hidden;
                    }
                }
            }

                
            for (int i = 0; i < SharedData.theme.images.Length; i++)
            {
                // flags
                if (SharedData.theme.images[i].flag != Theme.flags.none && SharedData.theme.images[i].visible == true) 
                {
                    // race
                    if (SharedData.Sessions.SessionList[SharedData.overlaySession].State == SessionStates.racing)
                    {
                        // yellow
                        if (SharedData.Sessions.SessionList[SharedData.overlaySession].Flag == SessionFlags.yellow)
                        {
                            if (SharedData.theme.images[i].flag == Theme.flags.yellow)
                                images[i].Visibility = System.Windows.Visibility.Visible;
                            else
                                images[i].Visibility = System.Windows.Visibility.Hidden;
                        }

                        // white
                        else if (SharedData.Sessions.SessionList[SharedData.overlaySession].Flag == SessionFlags.white) 
                        {
                            if(SharedData.theme.images[i].flag == Theme.flags.white)
                                images[i].Visibility = System.Windows.Visibility.Visible;
                            else
                                images[i].Visibility = System.Windows.Visibility.Hidden;
                        }
                        // green
                        else
                        {
                            if (SharedData.theme.images[i].flag == Theme.flags.green)
                                images[i].Visibility = System.Windows.Visibility.Visible;
                            else
                                images[i].Visibility = System.Windows.Visibility.Hidden;
                        }

                    }
                    // finishing
                    else if (SharedData.Sessions.SessionList[SharedData.overlaySession].State == SessionStates.checkered ||
                        SharedData.Sessions.SessionList[SharedData.overlaySession].State == SessionStates.cooldown)
                    {
                        if (SharedData.theme.images[i].flag == Theme.flags.checkered)
                            images[i].Visibility = System.Windows.Visibility.Visible;
                        else
                            images[i].Visibility = System.Windows.Visibility.Hidden;
                    }
                    // gridding & pace lap
                    else if (SharedData.Sessions.SessionList[SharedData.overlaySession].State != SessionStates.gridding ||
                        SharedData.Sessions.SessionList[SharedData.overlaySession].State != SessionStates.pacing ||
                        SharedData.Sessions.SessionList[SharedData.overlaySession].State != SessionStates.warmup)
                    {
                        if (SharedData.theme.images[i].flag == Theme.flags.yellow)
                            images[i].Visibility = System.Windows.Visibility.Visible;
                        else
                            images[i].Visibility = System.Windows.Visibility.Hidden;
                    }
                    else
                        images[i].Visibility = System.Windows.Visibility.Hidden;
                }
                    
                // replay transition
                if (SharedData.theme.images[i].replay == true)
                {
                    if (SharedData.replayInProgress)
                        images[i].Visibility = System.Windows.Visibility.Visible;
                    else
                        images[i].Visibility = System.Windows.Visibility.Hidden;
                }
            }
            */
            // videos
            for (int i = 0; i < videos.Length; i++)
            {
                if (SharedData.theme.videos[i].visible != visibility2boolean[videos[i].Visibility])
                    videos[i].Visibility = boolean2visibility[SharedData.theme.videos[i].visible];

                if (videos[i].Visibility == System.Windows.Visibility.Visible && SharedData.theme.videos[i].playing == false)
                {
                    
                    videos[i].Position = new TimeSpan(0);
                    videos[i].Volume = SharedData.theme.videos[i].volume;

                    if (SharedData.theme.videos[i].muteSimulator) 
                    {
                        VolumeMixer.SetApplicationMute("iRacingSim", true);
                    }
                    videoBoxes[i].Visibility = System.Windows.Visibility.Visible;
                    videos[i].Tag = i;
                    videos[i].Play();
                    
                    SharedData.theme.videos[i].playing = true;

                    if (SharedData.theme.videos[i].loop == true)
                    {
                        videos[i].UnloadedBehavior = MediaState.Manual;
                        videos[i].MediaEnded += new RoutedEventHandler(loopVideo);
                    }
                    else
                    {
                       
                        videos[i].UnloadedBehavior = MediaState.Close;
                        videos[i].MediaEnded += new RoutedEventHandler(VideoEnded);
                    }

                }
                else if (videos[i].NaturalDuration.HasTimeSpan 
                    && (videos[i].Position >= videos[i].NaturalDuration.TimeSpan) 
                    && (SharedData.theme.videos[i].playing == true)
                    && (SharedData.theme.videos[i].loop ==  false))
                {                    
                    SharedData.theme.videos[i].playing = false;
                    SharedData.theme.videos[i].visible = false;
                    videos[i].Stop();
                    videos[i].Close();
                    videoBoxes[i].Visibility = System.Windows.Visibility.Hidden;
                    videos[i].Visibility = boolean2visibility[SharedData.theme.videos[i].visible];
                    if (SharedData.theme.videos[i].muteSimulator)
                    {
                        VolumeMixer.SetApplicationMute("iRacingSim", false);
                    }
                }
                if (videos[i].Visibility == System.Windows.Visibility.Hidden && SharedData.theme.videos[i].playing == true)
                {
                    SharedData.theme.videos[i].playing = false;
                    SharedData.theme.videos[i].visible = false;
                    videos[i].Stop();
                    videos[i].Close();
                    videoBoxes[i].Visibility = System.Windows.Visibility.Hidden;
                    videos[i].Visibility = boolean2visibility[SharedData.theme.videos[i].visible];
                    if (SharedData.theme.videos[i].muteSimulator)
                    {
                        VolumeMixer.SetApplicationMute("iRacingSim", false);
                    }
                }
            }

            // sounds
            for (int i = 0; i < sounds.Length; i++)
            {
                if (SharedData.theme.sounds[i].playing == true)
                {

                    // start
                    if (sounds[i].Position == new TimeSpan(0))
                    {
                        sounds[i].Position = new TimeSpan(0);
                        sounds[i].Play();
                        sounds[i].Volume = SharedData.theme.sounds[i].volume;   
                        logger.Debug("Soundvolume = {0}",SharedData.theme.sounds[i].volume);
                        if (SharedData.theme.sounds[i].loop == true)
                        {
                            sounds[i].MediaEnded += new EventHandler(loopSound);
                        }
                    }
                    // stop
                    else if (sounds[i].NaturalDuration.HasTimeSpan && sounds[i].Position >= sounds[i].NaturalDuration.TimeSpan)
                    {
                        SharedData.theme.sounds[i].playing = false;
                    }
                }
                else
                {
                    if(sounds[i].Position > new TimeSpan(0))
                        sounds[i].Stop();
                }
            }

            // scripts
            SharedData.scripting.OverlayTick(overlay);

            SharedData.overlayUpdateTime = (Int32)(DateTime.Now - mutexLocked).TotalMilliseconds;
#if DEBUG
            logger.Trace("Overlayupdate "+SharedData.overlayUpdateTime.ToString());
#endif
            SharedData.mutex.ReleaseMutex();
            
        }