private TrainingInterval[] GetLaps(IActivity activity)
        {
            ActivityInfo activityInfo = ActivityInfoCache.Instance.GetInfo(activity);
            List<TrainingInterval> newLaps = new List<TrainingInterval>();
            IList<LapDetailInfo> activityLaps;

            if (Plugin.GetApplication().DisplayOptions.SelectedLapsType.Kind == ActivityLapsType.LapKind.RecordedLaps)
                activityLaps = activityInfo.RecordedLapDetailInfo;
            else if (Plugin.GetApplication().DisplayOptions.SelectedLapsType.Kind == ActivityLapsType.LapKind.CustomDistance)
                activityLaps = activityInfo.CustomDistanceLapDetailInfo;
            else
                activityLaps = activityInfo.DistanceLapDetailInfo(Plugin.GetApplication().DisplayOptions.SelectedLapsType.DistanceMeters);

            foreach (LapDetailInfo lapInfo in activityLaps)
            {
                TrainingInterval newLap = new TrainingInterval();
                newLap.Distance = lapInfo.LapDistanceMeters / 1000;
                newLap.Comment = lapInfo.Notes;
                newLap.Duration = new Duration();
                newLap.Duration.Hours = lapInfo.LapElapsed.Hours;
                newLap.Duration.Minutes = lapInfo.LapElapsed.Minutes;
                newLap.Duration.Seconds = lapInfo.LapElapsed.Seconds;
                newLaps.Add(newLap);
            }
            return newLaps.ToArray();
        }
        public static int? SendTraining(DateTime startDate, bool hasStartTime, TimeSpan duration, float?TE, int? cadenceAvg, float? distance, string comment,
            int? hrAvg, int? hrMax, int? intensity, int? kcal, string privateComment, int? repetitions, int? sets,
            int trainingType, TrainingInterval[] laps, TrackPoint[] trackPoints, Privacy RoutePrivacy, string[] equipment)
        {
            if (Settings.Settings.Instance.User.Username.Length == 0 || Settings.Settings.Instance.User.Password.Length == 0)
            {
                MessageBox.Show("Funbeat user name and password must be entered in the ST2funbeat settings", "Login failure", MessageBoxButtons.OK);
                return null;
            }
            else if (Settings.Settings.Instance.User.LoginId.Length == 0 || Settings.Settings.Instance.User.LoginSecret.Length == 0)
            {
                MessageBox.Show("Funbeat user name and password could not be confirmed. Make sure they are correct and that you are connected to the internet", "Login failure", MessageBoxButtons.OK);
                return null;
            }
            else
            {
                Training training = new Training();
                training.Description = comment;
                training.Distance = distance;
                training.StartDateTime = startDate;
                training.HasTimeOfDay = hasStartTime;
                training.Duration = new Duration();
                training.Duration.Hours = duration.Hours;
                training.Duration.Minutes = duration.Minutes;
                training.Duration.Seconds = duration.Seconds;

                training.TE = TE;
                training.CadAvg = cadenceAvg;
                training.HRAvg = hrAvg;
                training.HRMax = hrMax;
                training.Intensity = intensity;
                training.KCal = kcal;
                training.PrivateComment = privateComment;
                training.Repetitions = repetitions;
                training.Sets = sets;
                training.TrainingTypeID = trainingType;
                training.IntervalsAndLaps = laps;
                training.NewRoutePrivacy = RoutePrivacy;
                training.Equipment = equipment;

                // Workaround for the funbeat server not working when two or more subsequent GPS points have identical position
                // Ought to be fixed on the server side
                if (trackPoints != null)
                {
                    List<TrackPoint> trackPointsList = new List<TrackPoint>(trackPoints);
                    if (trackPointsList.Count > 0)
                    {
                        for (int i = trackPointsList.Count - 1; i > 0; i--)
                        {
                            TrackPoint tp = trackPointsList[i];
                            if (tp.Latitude == trackPointsList[i - 1].Latitude && tp.Longitude == trackPointsList[i - 1].Longitude)
                            {
                                tp.Latitude = null;
                                tp.Longitude = null;
                            }
                            if (!tp.Altitude.HasValue && !tp.Cad.HasValue && !tp.Distance.HasValue && !tp.HR.HasValue &&
                                !tp.Latitude.HasValue && !tp.Longitude.HasValue && !tp.Pace.HasValue && !tp.Power.HasValue &&
                                !tp.Speed.HasValue)
                                trackPointsList.Remove(tp);
                        }

                    }
                    training.TrackPoints = trackPointsList.ToArray();
                }
                else
                {
                    training.TrackPoints = trackPoints; // i.e. null
                }

                if (training.TrackPoints != null)
                {
                    training.NewRouteName = startDate.ToString();
                }
                else
                {
                    // Do nothing, leave at value null
                }

            #if DEBUG
                FileInfo t = new FileInfo("Training.txt");
                StreamWriter Tex = t.CreateText();
                Tex.WriteLine("Description: " + comment.ToString());
                Tex.WriteLine("Distance: " + distance.ToString());
                Tex.WriteLine("StartDateTime: " + startDate.ToString());
                Tex.WriteLine("HasTimeOfDay: " + hasStartTime.ToString());
                Tex.WriteLine("Duration: " + duration.ToString());
                Tex.WriteLine("TE: " + TE.ToString());
                Tex.WriteLine("CadAvg: " + cadenceAvg.ToString());
                Tex.WriteLine("HRAvg: " + hrAvg.ToString());
                Tex.WriteLine("HRMax: " + hrMax.ToString());
                Tex.WriteLine("Intensity: " + intensity.ToString());
                Tex.WriteLine("KCal: " + kcal.ToString());
                Tex.WriteLine("PrivateComment: " + privateComment.ToString());
                Tex.WriteLine("Repetitions: " + repetitions.ToString());
                Tex.WriteLine("Sets: " + sets.ToString());
                Tex.WriteLine("TrainingTypeID: " + trainingType.ToString());
                Tex.WriteLine("NewRouteName: " + startDate.ToString());
                Tex.WriteLine("NewRoutePrivacy: " + training.NewRoutePrivacy.ToString());
                Tex.WriteLine();
                if (trackPoints != null)
                {
                    for(int i=0; i<trackPoints.Length; i++)
                    {
                        TrackPoint tp = trackPoints[i];
                        Tex.WriteLine("Trackpoint");
                        Tex.WriteLine("isStartPoint: " + tp.isStartPoint.ToString());
                        Tex.WriteLine("TimeStamp: " + tp.TimeStamp.ToString());
                        Tex.WriteLine("HR: " + tp.HR.ToString());
                        Tex.WriteLine("Latitude: " + tp.Latitude.ToString());
                        Tex.WriteLine("Longitude: " + tp.Longitude.ToString());
                        Tex.WriteLine("Pace: " + tp.Pace.ToString());
                        Tex.WriteLine("Power: " + tp.Power.ToString());
                        Tex.WriteLine("Speed: " + tp.Speed.ToString());
                        Tex.WriteLine("Altitude: " + tp.Altitude.ToString());
                        Tex.WriteLine("Cadence: " + tp.Cad.ToString());
                        Tex.WriteLine("Distance: " + tp.Distance.ToString());
                        Tex.WriteLine("TrackPoint no;" + i.ToString());

                        if (i>0)
                        {
                            if (tp.Latitude == trackPoints[i - 1].Latitude && tp.Longitude == trackPoints[i - 1].Longitude)
                            {
                                Tex.WriteLine("Marker: Same latitude and longitude");
                            }
                            else
                            {
                                if (tp.Latitude == trackPoints[i - 1].Latitude)
                                    Tex.WriteLine("Marker: Same latitude");
                                if (tp.Longitude == trackPoints[i - 1].Longitude)
                                    Tex.WriteLine("Marker: Same longitude");
                            }
                            if (tp.TimeStamp.CompareTo(trackPoints[i - 1].TimeStamp) == 0)
                                Tex.WriteLine("Marker: Same time");
                        }

                        Tex.WriteLine();
                    }
                }

                if(equipment != null)
                {
                    for (int i = 0; i < equipment.Length; i++)
                    {
                        Tex.WriteLine("Equipment: " + equipment[i]);
                    }
                }
                Tex.Close();
            #endif

                try
                {
                    MobileService client = new MobileService();
                    ClientServerRelationResult result = client.SaveTraining(appID,
                                                                            Settings.Settings.Instance.User.LoginId,
                                                                            Settings.Settings.Instance.User.LoginSecret,
                                                                            training,
                                                                            clientID);
                    if (result != null)
                        return result.ServerID;
                    else
                        return null;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(string.Concat("Problem sending the activity to funbeat\n", ex.Message), "Funbeat communication error");
                    return null;
                }
            }
        }
        public void GetExportData(IActivity activity,
            bool boExportNameInComment,
            out DateTime startDate,
            out bool hasStartTime,
            out TimeSpan duration,
            out float? TE,
            out int? cadenceAvg,
            out float? distance,
            out string comment,
            out int? hrAvg,
            out int? hrMax,
            out int? intensity,
            out int? kcal,
            out string privateComment,
            out int? repetitions,
            out int? sets,
            out TrainingInterval[] laps,
            out TrackPoint[] trackPoints)
        {
            if (activity != null)
            {

                int? RPECustFieldData, RepetitionsCustFieldData, SetsCustFieldData;
                double? TECustFieldData;
            #if !ST_2_1
                GetCustomFieldsData(activity,
                                    out RPECustFieldData,
                                    out TECustFieldData,
                                    out RepetitionsCustFieldData,
                                    out SetsCustFieldData);
            #else
                RPECustFieldData = null;
                TECustFieldData = null;
                RepetitionsCustFieldData = null;
                SetsCustFieldData = null;
            #endif

                // Get pulse data. Works with and without a HR data track.
                ActivityInfo activityInfo = ActivityInfoCache.Instance.GetInfo(activity);
                if (activityInfo.AverageHeartRate == 0)
                    hrAvg = null;
                else
                    hrAvg = (int?)Math.Round(activityInfo.AverageHeartRate);
                if (activityInfo.MaximumHeartRate == 0)
                    hrMax = null;
                else
                    hrMax = (int?)Math.Round(activityInfo.MaximumHeartRate);
                if (activityInfo.AverageCadence == 0)
                    cadenceAvg = null;
                else
                    cadenceAvg = (int?)Math.Round(activityInfo.AverageCadence);

                startDate = ConvertToLocalTime(activity.StartTime);
                hasStartTime = activity.HasStartTime;
                duration = activityInfo.Time;
                TE = (float?)TECustFieldData;
                distance = (float?)activityInfo.DistanceMeters/1000;
                if (boExportNameInComment)
                {
                    comment = activity.Name + "\r\n" + activity.Notes;
                }
                else
                {
                    comment = activity.Notes;
                }
                intensity = RPECustFieldData;
                if (activity.TotalCalories == 0)
                    kcal = null;
                else
                    kcal = (int?)Math.Round(activity.TotalCalories);
                privateComment = "SportsTracks reference: " + activity.ReferenceId;
                repetitions = RepetitionsCustFieldData;
                sets = SetsCustFieldData;
                laps = GetLaps(activity);
                trackPoints = GetTrackPoints(activity);
            }
            else
            {
                startDate = new DateTime(1900, 1, 1, 0, 0, 0);
                hasStartTime = false;
                duration = new TimeSpan(0, 0, 0);
                TE = null;
                cadenceAvg = null;
                distance = null;
                comment = "";
                hrAvg = null;
                hrMax = null;
                intensity = null;
                kcal = null;
                privateComment = "";
                repetitions = null;
                sets = null;
                laps = null;
                trackPoints = null;

            }
        }