/// <summary>
        /// This control behaves a bit differently from the configuration tabs.  It always initializes itself to whatever the current settings are.
        /// If the user switches tabs without saving, there is no warning and selections are lost.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public override void ControlGainingFocus(object sender, EventArgs e)
        {
            base.ControlGainingFocus(sender, e);

            ZAMappearance settings = ZAMsettings.Settings.Appearance;

            this.BeginInitializingControls();

            nudFontSize.Value = nudFontSize.Minimum;
            nudFontSize.Value = (int)settings.FontSize;

            if (settings.Theme.HasValue)
            {
                cbTheme.SelectedValue = settings.Theme.Value.Value;
            }

            if (settings.Transparency.HasValue)
            {
                cbTransparency.SelectedValue = settings.Transparency.Value.Value;
            }

            this.btnColor.SelectedColor = settings.ManagedColor;

            this.cbFonts.SelectedIndex = cbFonts.Items.IndexOf(settings.FontFamily);
            //this.cbFonts.SelectedItem = settings.FontFamily;

            cbBold.Checked   = settings.IsFontBold;
            cbItalic.Checked = settings.IsFontItalic;

            this.EndInitializingControls();
        }
Exemplo n.º 2
0
        public AdvancedOptions()
        {
            InitializeComponent();

            if (DesignMode)
            {
                return;
            }

            if (ZAMsettings.LoggerFactory == null)
            {
                return;
            }

            Logger = ZAMsettings.LoggerFactory.CreateLogger <AdvancedOptions>();

            this.BackColor = Color.AliceBlue;
            this.ForeColor = Color.AliceBlue;

            MSoffice2010ColorManager colorTable = ZAMappearance.ApplyColorTable(this);

            // SfForm is not firing the property changed events so doing it manually here.
            this.AdvancedOptions_BackColorChanged(this, null);
            this.AdvancedOptions_ForeColorChanged(this, null);

            this.Icon = Properties.Resources.ZAMicon;

            UserControlBase.SetListViewHeaderColor(ref this.lvTrace, SystemColors.Control, SystemColors.ControlText);
        }
        private void btnAccept_Click(object sender, EventArgs e)
        {
            if (cbTheme.SelectedItem == null || cbTransparency.SelectedItem == null || cbFonts.SelectedItem == null)
            {
                MessageBox.Show(this.ParentForm, "Please make sure to select a valid theme, transparency, and font before saving.", "Unable to save", MessageBoxButtons.OK);
                return;
            }

            Logger.LogDebug($"Theme: {cbTheme.SelectedValue}, ManagedColor: {btnColor.SelectedColor}, Font: {cbFonts.SelectedItem} Transparency: {cbTransparency.SelectedValue}");

            ZAMsettings.BeginCachedConfiguration();

            ZAMsettings.Settings.Appearance.ThemeSetting        = ((KeyValuePair <ThemeType, string>)cbTheme.SelectedItem).Key;
            ZAMsettings.Settings.Appearance.TransparencySetting = ((KeyValuePair <TransparencyType, string>)cbTransparency.SelectedItem).Key;
            ZAMsettings.Settings.Appearance.ManagedColor        = btnColor.SelectedColor;
            ZAMsettings.Settings.Appearance.FontFamily          = cbFonts.SelectedItem.ToString();
            ZAMsettings.Settings.Appearance.FontSize            = (float)nudFontSize.Value;
            ZAMsettings.Settings.Appearance.IsFontBold          = cbBold.Checked;
            ZAMsettings.Settings.Appearance.IsFontItalic        = cbItalic.Checked;

            ZAMsettings.CommitCachedConfiguration();

            ZAMappearance cs = ZAMsettings.Settings.Appearance;

            ColorsAndFontChangedEventArgs args = new(cs.ThemeSetting, cs.TransparencySetting, cs.ManagedColor, cs.FontFamily, cs.FontSize, cs.IsFontBold, cs.IsFontItalic);

            // The MainForm listens for this event so it can refresh all colors
            this.OnColorsAndFontChanged(args);

            this.sfToolTip.Show("Configuration saved.", Cursor.Position, 2000);
        }
        public ConfigurationOptions(Point ZAMWindowPos)
        {
            InitializeComponent();

            if (DesignMode)
            {
                return;
            }

            if (ZAMsettings.LoggerFactory == null)
            {
                return;
            }

            Logger = ZAMsettings.LoggerFactory.CreateLogger <ConfigurationOptions>();

            SystemControl.ZAMWindowPos = ZAMWindowPos;

            MSoffice2010ColorManager colorTable = ZAMappearance.ApplyColorTable(this);

            this.Icon = Properties.Resources.ZAMicon;

            //ZAMappearance.ApplyColorScheme(this);

            tabOptions.TabPanelBackColor  = colorTable.ActiveFormBorderColor;
            tabOptions.ActiveTabColor     = colorTable.ActiveFormBorderColor;
            tabOptions.ActiveTabForeColor = colorTable.FormTextColor;

            tabOptions.InactiveTabColor     = colorTable.InactiveFormBorderColor;;
            tabOptions.InActiveTabForeColor = colorTable.FormTextColor;

            // the user controls will receive notifications that their parent's (the tabpages) colors have changed
            this.tpSystem.BackColor       = Color.AliceBlue;
            this.tpSystem.ForeColor       = Color.AliceBlue;
            this.tpLaps.BackColor         = Color.AliceBlue;
            this.tpLaps.ForeColor         = Color.AliceBlue;
            this.tpSplits.BackColor       = Color.AliceBlue;
            this.tpSplits.ForeColor       = Color.AliceBlue;
            this.tpUserProfiles.BackColor = Color.AliceBlue;
            this.tpUserProfiles.ForeColor = Color.AliceBlue;
            this.tpGeneral.BackColor      = Color.AliceBlue;
            this.tpGeneral.ForeColor      = Color.AliceBlue;

            this.tpSystem.BackColor = colorTable.FormBackground;
            this.tpSystem.ForeColor = colorTable.FormTextColor;

            this.tpLaps.BackColor = colorTable.FormBackground;
            this.tpLaps.ForeColor = colorTable.FormTextColor;

            this.tpSplits.BackColor = colorTable.FormBackground;
            this.tpSplits.ForeColor = colorTable.FormTextColor;

            this.tpUserProfiles.BackColor = colorTable.FormBackground;
            this.tpUserProfiles.ForeColor = colorTable.FormTextColor;

            this.tpGeneral.BackColor = colorTable.FormBackground;
            this.tpGeneral.ForeColor = colorTable.FormTextColor;
        }
Exemplo n.º 5
0
        private void AdvancedOptions_BackColorChanged(object sender, EventArgs e)
        {
            this.btnClose.BackColor = this.BackColor;
            this.btnStart.BackColor = this.BackColor;
            this.btnStop.BackColor  = this.BackColor;

            MSoffice2010ColorManager colorTable = ZAMappearance.GetColorTable();

            this.gbZwiftPacketMonitor.BorderColor = colorTable.ActiveFormBorderColor;
        }
Exemplo n.º 6
0
        protected override void Parent_BackColorChanged(object sender, EventArgs e)
        {
            base.Parent_BackColorChanged(sender, e);

            this.tbDescUsers.BackColor = this.BackColor;

            MSoffice2010ColorManager colorTable = ZAMappearance.GetColorTable();

            this.gbUserProfiles.BorderColor = colorTable.ActiveFormBorderColor;
        }
Exemplo n.º 7
0
        public void CreateDocumentText()
        {
            /*
             #000001 BackColor
             #000002 ActiveFormBorderColor
             #000003 ForeColor
             #000004 ActiveTitleGradientEnd
             */
            MSoffice2010ColorManager colorTable = ZAMappearance.GetColorTable();

            string styleSheet = Properties.Resources.StyleSheet;

            styleSheet = styleSheet.Replace("000001", $"{colorTable.FormBackground.R:X2}{ colorTable.FormBackground.G:X2}{ colorTable.FormBackground.B:X2}");
            styleSheet = styleSheet.Replace("000002", $"{colorTable.ActiveFormBorderColor.R:X2}{ colorTable.ActiveFormBorderColor.G:X2}{ colorTable.ActiveFormBorderColor.B:X2}");
            styleSheet = styleSheet.Replace("000003", $"{colorTable.FormTextColor.R:X2}{ colorTable.FormTextColor.G:X2}{ colorTable.FormTextColor.B:X2}");
            styleSheet = styleSheet.Replace("000004", $"{colorTable.ActiveTitleGradientEnd.R:X2}{ colorTable.ActiveTitleGradientEnd.G:X2}{ colorTable.ActiveTitleGradientEnd.B:X2}");

            string splitStatus = Properties.Resources.SplitStatusFreeform;
            string delta       = "";

            if (this.mSplitEventArgs.DeltaTime.HasValue)
            {
                TimeSpan std     = (TimeSpan)this.mSplitEventArgs.DeltaTime;
                bool     negated = false;

                if (std.TotalSeconds < 0)
                {
                    std     = std.Negate();
                    negated = true;
                }

                delta = $"{(negated ? "-" : "+")}{(std.Minutes > 0 ? std.ToString("m'@QT's'\"'").Replace("@QT", "\'") : std.ToString("s'\"'"))}";

                splitStatus = splitStatus.Replace("DeltaColorCode", this.mSplitEventArgs.AheadOfGoalTime.Value ? "00C000" : "C00000");
            }
            else
            {
                splitStatus = splitStatus.Replace("DeltaColorCode", "00C000");
                //splitStatus = splitStatus.Replace("DeltaColorCode", $"{colorTable.FormBackground.R:X2}{ colorTable.FormBackground.G:X2}{ colorTable.FormBackground.B:X2}");
                delta = "No Goal";
            }

            splitStatus = splitStatus.Replace("DeltaTime", delta);
            splitStatus = splitStatus.Replace("SplitNumber", this.mSplitEventArgs.SplitNumber.ToString());
            splitStatus = splitStatus.Replace("SplitSpeedKph", this.mSplitEventArgs.SplitSpeedKph.ToString("0.0"));
            splitStatus = splitStatus.Replace("SplitSpeedMph", this.mSplitEventArgs.SplitSpeedMph.ToString("0.0"));
            splitStatus = splitStatus.Replace("SplitTime", this.mSplitEventArgs.SplitTime.ToString("hh\\:mm\\:ss"));
            splitStatus = splitStatus.Replace("TotalKmTravelled", this.mSplitEventArgs.TotalKmTravelled.ToString("0.0"));
            splitStatus = splitStatus.Replace("TotalMiTravelled", this.mSplitEventArgs.TotalMiTravelled.ToString("0.0"));
            splitStatus = splitStatus.Replace("TotalTime", this.mSplitEventArgs.TotalTime.ToString("hh\\:mm\\:ss"));

            Logger.LogDebug($"{this.GetType()}::CreateDocumentText - \n{splitStatus}");
            this.DocumentText = styleSheet + splitStatus;
        }
Exemplo n.º 8
0
        protected override void Parent_BackColorChanged(object sender, EventArgs e)
        {
            base.Parent_BackColorChanged(sender, e);

            this.tbDescSystem.BackColor = this.BackColor;

            this.dgvSplits.RowBackColor    = this.BackColor;
            this.dgvSplits.BackgroundColor = this.BackColor;
            this.dgvSplits.RowHeadersDefaultCellStyle.BackColor = this.BackColor;

            MSoffice2010ColorManager colorTable = ZAMappearance.GetColorTable();

            this.gbSplitGoals.BorderColor = colorTable.ActiveFormBorderColor;
            this.gbSplits.BorderColor     = colorTable.ActiveFormBorderColor;
        }
        /// <summary>
        /// This needs to be called on the UI thread
        /// </summary>
        /// <param name="form"></param>
        public virtual void InitializeStatus(Form form)
        {
            Debug.Assert(!this.mIsStatusInitialized, $"InitializeStatus already called.");
            Debug.Assert(ZAMsettings.Settings.StatusViewerDurationSecs.HasValue, $"StatusViewerDurationSecs is null.");

            this.mParentForm = form;
            this.mParentForm.Controls.Add(this);

            MSoffice2010ColorManager colorTable = ZAMappearance.GetColorTable();

            this.tlPanel.BackColor = colorTable.FormBackground;
            this.pStatus.BackColor = colorTable.FormBackground;
            this.pStatus.ForeColor = colorTable.FormTextColor;

            this.mStatusViewerDuration = ZAMsettings.Settings.StatusViewerDurationSecs.Value;
            this.btnAutoDismiss.Text   = this.mDismissBtnBaseText;
            this.mIsStatusInitialized  = true;
        }
Exemplo n.º 10
0
        protected override void Parent_ForeColorChanged(object sender, EventArgs e)
        {
            base.Parent_ForeColorChanged(sender, e);

            this.tbDescSystem.ForeColor = this.ForeColor;

            this.dgvSplits.RowForeColor    = this.ForeColor;
            this.dgvSplits.ForeColor       = this.ForeColor;
            this.dgvSplits.HeaderForeColor = this.ForeColor;

            this.gbSplitGoals.ForeColor = this.ForeColor;
            this.gbSplits.ForeColor     = this.ForeColor;

            MSoffice2010ColorManager colorTable = ZAMappearance.GetColorTable();

            //Office2010Colors t = Office2010Colors.GetColorTable(Office2010Colors.DefaultTheme);
            dgvSplits.HeaderGradientBeginColor = colorTable.ActiveTitleGradientBegin;
            dgvSplits.HeaderGradientEndColor   = colorTable.ActiveTitleGradientEnd;
        }
        private void ColorAndFontViewControl_Load(object sender, EventArgs e)
        {
            if (this.DesignMode)
            {
                return;
            }

            Logger.LogDebug($"{this.GetType()}.ViewControl_Load");

            ZAMappearance settings = ZAMsettings.Settings.Appearance;

            this.BeginInitializingControls();

            cbTheme.DataSource = new BindingSource(settings.ThemeItems, null);

            cbTransparency.DataSource = new BindingSource(settings.TransparencyItems, null);

            this.EndInitializingControls();

            sfToolTip.SetToolTip(this.btnAccept, "Save and apply selections.");
        }
        public void CreateDocumentText()
        {
            /*
             #000001 BackColor
             #000002 ActiveFormBorderColor
             #000003 ForeColor
             #000004 ActiveTitleGradientEnd
             */
            MSoffice2010ColorManager colorTable = ZAMappearance.GetColorTable();

            string styleSheet = Properties.Resources.StyleSheet;

            styleSheet = styleSheet.Replace("000001", $"{colorTable.FormBackground.R:X2}{ colorTable.FormBackground.G:X2}{ colorTable.FormBackground.B:X2}");
            styleSheet = styleSheet.Replace("000002", $"{colorTable.ActiveFormBorderColor.R:X2}{ colorTable.ActiveFormBorderColor.G:X2}{ colorTable.ActiveFormBorderColor.B:X2}");
            styleSheet = styleSheet.Replace("000003", $"{colorTable.FormTextColor.R:X2}{ colorTable.FormTextColor.G:X2}{ colorTable.FormTextColor.B:X2}");
            styleSheet = styleSheet.Replace("000004", $"{colorTable.ActiveTitleGradientEnd.R:X2}{ colorTable.ActiveTitleGradientEnd.G:X2}{ colorTable.ActiveTitleGradientEnd.B:X2}");

            string lapStatus = Properties.Resources.LapStatusFreeform;


            lapStatus = lapStatus.Replace("LapAPwattsPerKg", this.mLapEventArgs.LapAPwattsPerKg.HasValue ? this.mLapEventArgs.LapAPwattsPerKg.Value.ToString("0.00") + "w/kg" : "");
            lapStatus = lapStatus.Replace("LapAPwatts", this.mLapEventArgs.LapAPwatts.ToString());
            lapStatus = lapStatus.Replace("LapDistanceKm", this.mLapEventArgs.LapDistanceKm.ToString("0.0"));
            lapStatus = lapStatus.Replace("LapDistanceMi", this.mLapEventArgs.LapDistanceMi.ToString("0.0"));
            lapStatus = lapStatus.Replace("LapNumber", this.mLapEventArgs.LapNumber.ToString());
            lapStatus = lapStatus.Replace("LapSpeedKph", this.mLapEventArgs.LapSpeedKph.ToString("0.0"));
            lapStatus = lapStatus.Replace("LapSpeedMph", this.mLapEventArgs.LapSpeedMph.ToString("0.0"));
            lapStatus = lapStatus.Replace("LapTime", this.mLapEventArgs.LapTime.ToString("hh\\:mm\\:ss"));
            lapStatus = lapStatus.Replace("TotalTime", this.mLapEventArgs.TotalTime.ToString("hh\\:mm\\:ss"));

            lapStatus = lapStatus.Replace("LapPower", $"{this.mLapEventArgs.LapAPwatts + " w"}{(this.mLapEventArgs.LapAPwattsPerKg.HasValue ? " (" + this.mLapEventArgs.LapAPwattsPerKg.Value.ToString("0.00") + " w/kg)" : "")}");
            lapStatus = lapStatus.Replace("LapDistance", $"{this.mLapEventArgs.LapDistanceKm.ToString("0.0") + " km"}{" (" + this.mLapEventArgs.LapDistanceMi.ToString("0.0") + " mi)"}");
            lapStatus = lapStatus.Replace("LapSpeed", $"{this.mLapEventArgs.LapSpeedKph.ToString("0.0") + " km/h"}{" (" + this.mLapEventArgs.LapSpeedMph.ToString("0.0") + " mi/h)"}");

            Logger.LogDebug($"{this.GetType()}::CreateDocumentText - \n{lapStatus}");
            this.DocumentText = styleSheet + lapStatus;
        }
Exemplo n.º 13
0
        public RideRecap(RideRecapMetrics rideRecapMetrics)
        {
            mRideRecapMetrics = rideRecapMetrics;

            InitializeComponent();

            if (DesignMode)
            {
                return;
            }

            if (ZAMsettings.LoggerFactory == null)
            {
                return;
            }

            Logger = ZAMsettings.LoggerFactory.CreateLogger <RideRecap>();

            this.toolStrip.Renderer = new ToolStripProfessionalRendererEx();

            MSoffice2010ColorManager colorTable = ZAMappearance.ApplyColorTable(this);

            this.Icon = Properties.Resources.ZAMicon;
        }
Exemplo n.º 14
0
        private void RideRecap_Load(object sender, EventArgs e)
        {
            /*
             #000001 BackColor
             #000002 ActiveFormBorderColor
             #000003 ForeColor
             #000004 ActiveTitleGradientEnd
             */
            MSoffice2010ColorManager colorTable = ZAMappearance.GetColorTable();

            this.pControls.BackColor = colorTable.FormBackground;
            this.pControls.ForeColor = colorTable.FormTextColor;
            this.toolStrip.BackColor = colorTable.FormBackground;

            string styleSheet = Properties.Resources.StyleSheet;

            styleSheet = styleSheet.Replace("000001", $"{colorTable.FormBackground.R:X2}{ colorTable.FormBackground.G:X2}{ colorTable.FormBackground.B:X2}");
            styleSheet = styleSheet.Replace("000002", $"{colorTable.ActiveFormBorderColor.R:X2}{ colorTable.ActiveFormBorderColor.G:X2}{ colorTable.ActiveFormBorderColor.B:X2}");
            styleSheet = styleSheet.Replace("000003", $"{colorTable.FormTextColor.R:X2}{ colorTable.FormTextColor.G:X2}{ colorTable.FormTextColor.B:X2}");
            styleSheet = styleSheet.Replace("000004", $"{colorTable.ActiveTitleGradientEnd.R:X2}{ colorTable.ActiveTitleGradientEnd.G:X2}{ colorTable.ActiveTitleGradientEnd.B:X2}");

            mRideRecapHtml = Properties.Resources.RideRecap;

            StringBuilder xAxis = new StringBuilder("");
            StringBuilder yAxis = new StringBuilder("");

            if (this.mRideRecapMetrics.Power.Length > 0)
            {
                foreach (var power in this.mRideRecapMetrics.Power)
                {
                    xAxis.Append($"'{DurationEnum.Instance.GetText(power.DurationType)}',");
                    yAxis.Append($"{power.APwattsMax},");
                }
            }
            else
            {
                // no power values, build an empty chart
                foreach (var item in DurationEnum.Instance.GetValues())
                {
                    xAxis.Append($"'{item}',");
                }
            }

            string chartDef = "{type:'line',data:{labels:[xAxisValues],datasets:[{fill:true,lineTension:0,backgroundColor:'#000004',borderColor:'#000002',data:[yAxisValues],}]},options:{legend:{display:false},title:{display:true,text:'Peak Power',fontSize:20,fontFamily:'Segoe UI, sans-serif',fontColor:'#000003',},scales:{yAxes:[{ticks:{fontFamily:'Segoe UI, sans-serif',fontColor: '#000003'},scaleLabel:{display:true,labelString:'Watts',fontSize:16,fontFamily:'Segoe UI, sans-serif',fontColor:'#000003',},gridLines:{display:false,}}],xAxes:[{ticks:{fontFamily:'Segoe UI, sans-serif',fontColor: '#000003'},scaleLabel:{display:false,labelString:'Time',fontSize:16,fontFamily:'Segoe UI, sans-serif',fontColor:'#000003',},gridLines:{display:false,}}],}}}";

            chartDef = chartDef.Replace("xAxisValues", xAxis.ToString());
            chartDef = chartDef.Replace("yAxisValues", yAxis.ToString());

            // Define and encode the chart URL
            string urlStr = WebUtility.UrlEncode(chartDef);

            Debug.WriteLine(urlStr);

            mRideRecapHtml = mRideRecapHtml.Replace("EncodedChartUrl", urlStr);


            mRideRecapHtml = mRideRecapHtml.Replace("000001", $"{colorTable.FormBackground.R:X2}{ colorTable.FormBackground.G:X2}{ colorTable.FormBackground.B:X2}");
            mRideRecapHtml = mRideRecapHtml.Replace("000002", $"{colorTable.ActiveFormBorderColor.R:X2}{ colorTable.ActiveFormBorderColor.G:X2}{ colorTable.ActiveFormBorderColor.B:X2}");
            mRideRecapHtml = mRideRecapHtml.Replace("000003", $"{colorTable.FormTextColor.R:X2}{ colorTable.FormTextColor.G:X2}{ colorTable.FormTextColor.B:X2}");
            mRideRecapHtml = mRideRecapHtml.Replace("000004", $"{colorTable.ActiveTitleGradientEnd.R:X2}{ colorTable.ActiveTitleGradientEnd.G:X2}{ colorTable.ActiveTitleGradientEnd.B:X2}");

            //public TimeSpan Duration { get; set; }
            //public double DistanceKm { get; set; }
            //public double DistanceMi { get; set; }
            //public double AverageKph { get; set; }
            //public double AverageMph { get; set; }
            //public int APwatts { get; set; }
            //public double? APwattsPerKg { get; set; }
            //public int NPwatts { get; set; }
            //public double? NPwattsPerKg { get; set; }
            //public double? IntensityFactor { get; set; } // null if FTP not set
            //public int? TrainingStressScore { get; set; } // null if FTP not set

            mRideRecapHtml = mRideRecapHtml.Replace("Duration", $"{this.mRideRecapMetrics.Duration.ToString("hh\\:mm\\:ss")}");
            mRideRecapHtml = mRideRecapHtml.Replace("DistanceKm", $"{this.mRideRecapMetrics.DistanceKm:0.0}");
            mRideRecapHtml = mRideRecapHtml.Replace("DistanceMi", $"{this.mRideRecapMetrics.DistanceMi:0.0}");
            mRideRecapHtml = mRideRecapHtml.Replace("AverageKph", $"{this.mRideRecapMetrics.AverageKph:0.0}");
            mRideRecapHtml = mRideRecapHtml.Replace("AverageMph", $"{this.mRideRecapMetrics.AverageMph:0.0}");
            mRideRecapHtml = mRideRecapHtml.Replace("APwattsPerKg", $"{(this.mRideRecapMetrics.APwattsPerKg.HasValue ? this.mRideRecapMetrics.APwattsPerKg.Value.ToString("0.00") + " w/kg" : "")}");
            mRideRecapHtml = mRideRecapHtml.Replace("APwatts", $"{this.mRideRecapMetrics.APwatts}");
            mRideRecapHtml = mRideRecapHtml.Replace("NPwattsPerKg", $"{(this.mRideRecapMetrics.NPwattsPerKg.HasValue ? this.mRideRecapMetrics.NPwattsPerKg.Value.ToString("0.00") + " w/kg" : "")}");
            mRideRecapHtml = mRideRecapHtml.Replace("NPwatts", $"{this.mRideRecapMetrics.NPwatts}");
            mRideRecapHtml = mRideRecapHtml.Replace("IntensityFactor", $"{(this.mRideRecapMetrics.IntensityFactor.HasValue ? this.mRideRecapMetrics.IntensityFactor.Value.ToString(".00") : "")}");
            mRideRecapHtml = mRideRecapHtml.Replace("TrainingStressScore", $"{(this.mRideRecapMetrics.TrainingStressScore.HasValue ? this.mRideRecapMetrics.TrainingStressScore.Value : "")}");
            mRideRecapHtml = mRideRecapHtml.Replace("WorkKiloJoules", $"{this.mRideRecapMetrics.KiloJoules}");

            StringBuilder powerStr = new StringBuilder("");

            foreach (var power in this.mRideRecapMetrics.Power)
            {
                powerStr.AppendLine("<tr>");
                powerStr.AppendLine($"<td>{DurationEnum.Instance.GetText(power.DurationType)}</td>");
                powerStr.AppendLine($"<td>{power.APwattsMax}</td>");
                powerStr.AppendLine($"<td>{(power.APwattsKgMax.HasValue ? power.APwattsKgMax.Value.ToString("0.00") : "")}</td>");
                powerStr.AppendLine("</tr>");
            }

            mRideRecapHtml = mRideRecapHtml.Replace("RideRecapPower", powerStr.ToString());


            /*
             * <tr>
             *  <td>1</td>
             *  <td>1:45:43</td>
             *  <td>34.5 km/h (25.3 mi/h)</td>
             *  <td>21.0 km (18.3 mi)</td>
             *  <td>245 (3.2 w/kg)</td>
             *  <td>05:45:43</td>
             * </tr>
             */

            StringBuilder lapStr = new StringBuilder("");

            foreach (var lap in this.mRideRecapMetrics.Laps)
            {
                lapStr.AppendLine("<tr>");
                lapStr.AppendLine($"<td>{lap.LapNumber}</td>");
                lapStr.AppendLine($"<td>{lap.LapTime.ToString("hh\\:mm\\:ss")}</td>");
                lapStr.AppendLine($"<td>{lap.LapSpeedKph:0.0} km/h ({lap.LapSpeedMph:0.0} mi/h)</td>");
                lapStr.AppendLine($"<td>{lap.LapDistanceKm:0.0} km ({lap.LapDistanceMi:0.0} mi)</td>");
                lapStr.AppendLine($"<td>{lap.LapAPwatts} w{(lap.LapAPwattsPerKg.HasValue ? " (" + lap.LapAPwattsPerKg.Value.ToString("0.00") + " w/kg)" : "")}</td>");
                lapStr.AppendLine($"<td>{lap.TotalTime.ToString("hh\\:mm\\:ss")}</td>");
                lapStr.AppendLine("</tr>");
            }

            mRideRecapHtml = mRideRecapHtml.Replace("RideRecapLaps", lapStr.ToString());

            /*
             * <tr>
             *  <td>1</td>
             *  <td>1:45:43</td>
             *  <td>34.5 km/h (25.3 mi/h)</td>
             *  <td>21.0 km (18.3 mi)</td>
             *  <td>05:45:43</td>
             *  <td>-01:43</td>
             * </tr>
             */

            StringBuilder splitStr = new StringBuilder("");

            foreach (var split in this.mRideRecapMetrics.Splits)
            {
                string delta;
                //string deltaColorCode;
                if (split.DeltaTime.HasValue)
                {
                    TimeSpan std     = (TimeSpan)split.DeltaTime;
                    bool     negated = false;

                    if (std.TotalSeconds < 0)
                    {
                        std     = std.Negate();
                        negated = true;
                    }

                    delta = $"{(negated ? "-" : "+")}{(std.Minutes > 0 ? std.ToString("m'@QT's'\"'").Replace("@QT", "\'") : std.ToString("s'\"'"))}";
                    //deltaColorCode = negated ? "00C000" : "C00000";
                }
                else
                {
                    delta = "No Goal";
                }

                splitStr.AppendLine("<tr>");
                splitStr.AppendLine($"<td>{split.SplitNumber}</td>");
                splitStr.AppendLine($"<td>{split.SplitTime.ToString("hh\\:mm\\:ss")}</td>");
                splitStr.AppendLine($"<td>{split.SplitSpeedKph:0.0} km/h ({split.SplitSpeedMph:0.0} mi/h)</td>");
                splitStr.AppendLine($"<td>{split.SplitDistanceKm:0.0} km ({split.SplitDistanceMi:0.0} mi)</td>");
                splitStr.AppendLine($"<td>{split.TotalTime.ToString("hh\\:mm\\:ss")}</td>");
                splitStr.AppendLine($"<td>{delta}</td>");
                splitStr.AppendLine("</tr>");
            }

            mRideRecapHtml = mRideRecapHtml.Replace("RideRecapSplits", splitStr.ToString());

            Logger.LogDebug($"{this.GetType()}::RideRecap_Load - \n{mRideRecapHtml}");

            this.webBrowser.BrowserControl.DocumentText = styleSheet + mRideRecapHtml;

            tsbEmail.ToolTipText = this.CurrentUserProfile.EmailAddress.Length > 0 ? "MailTo:" + this.CurrentUserProfile.EmailAddress : "Please set email address in your user profile to use this feature.";
        }