'use strict';
angular.module('beamng.apps')
.directive('gooseDataLogger', ['$timeout', function($timeout) {
  return {
    template: '<object style="width:100%; height:100%;" type="image/svg+xml" data="/ui/modules/apps/DataLogger/DataLogger.svg"></object>',
    replace: true,
    restrict: 'EA',
    link: function(scope, element, attrs) {
      const localStorageKey = 'loggerData';

      // Unit systems for metric only
      const unitSystems = {
        metric: {
          speedFactor: 1, // m/s to meters
          label: 'meters'
        }
      };

      // Always use metric system
      scope.units = unitSystems.metric;
      scope.goalEnd_330ft = 100.5;    // 330 feet in meters
      scope.goalEnd_60ft = 18.2;      // 60 feet in meters
      scope.goalEnd_660ft = 201;      // 660 feet in meters
      scope.goalEnd_1000ft = 304;     // 1000 feet in meters
      scope.goalEnd_1320ft = 402;     // 1320 feet in meters (1/4 mile)

      let targetTimes = {
        start: null,
        '60ft': null,
        '330ft': null,
        '660ft': null,
        '1000ft': null,
        '1320ft': null,
      };

      let loggerStartTime = null; // Store the start time of the logger

      // Function to move the vertical line to the correct time
      scope.moveToTargetTime = function(timeInSeconds) {
        if (timeInSeconds === null) {
          console.log('Target time is not available for this button');
          return;
        }

        // Calculate the relative position of the time on the graph (0-20 seconds)
        const relativePosition = (timeInSeconds / 20);
        currentX = minX + relativePosition * (maxX - minX);
        updateLinePosition();
        console.log('Moved to time:', timeInSeconds, 's (relative position:', relativePosition, ')');
      };

      function saveData() {
        const data = {
          rpmData,
          wpData,
          asData,
          tpsData,
          psiData,
          gearData,
          gforceData,
          currentX // Save the vertical line position
        };
        localStorage.setItem(localStorageKey, JSON.stringify(data));
      }

      function loadData() {
        const data = JSON.parse(localStorage.getItem(localStorageKey));
        if (data) {
          rpmData = data.rpmData || [];
          wpData = data.wpData || [];
          asData = data.asData || [];
          tpsData = data.tpsData || [];
          psiData = data.psiData || [];
          gearData = data.gearData || [];
          gforceData = data.gforceData || [];
          currentX = data.currentX || 135; // Default to 135 if no saved position
        }
      }

      let svgDocument, rpmLine, wpLine, asLine, tpsLine, psiLine, gearLine, gforceLine;
      let rpmReadout, wheelSpeedReadout, airSpeedReadout, tpsReadout, psiReadout, gearReadout, gforceReadout;
      let movableLineElement, linePositionElement;
      let currentX = 135;
      const minX = 130;
      const maxX = 590;
      let rpmData = [], wpData = [], asData = [], tpsData = [], psiData = [], gearData = [], gforceData = [];
      let isRecording = false;  // Track recording state
      let currentRPM = 0, currentWheelSpeed = 0, currentAirSpeed = 0, currentTPS = 0, currentPSI = 0, currentGear = 0, currentGForce = 0;
      let maxRPM = 16000;
      const secondsPerUnit = (maxX - minX) / 20;

      // Initialize Drag Pass Timers
      scope.initializeDragPassTimers = function() {
        scope.distance_60ft = 0;
        scope.distance_330ft = 0;
        scope.distance_660ft = 0;
        scope.distance_1000ft = 0;
        scope.distance_1320ft = 0;
      };

      // This function should track the logger's progress and note when each milestone is hit
      scope.updateDragPassTimers = function(streams) {
        if (!isRecording) {
          console.log("Logger is not recording. Drag pass timers will not run.");
          return;  // Exit early if not recording
        }

        const speedMs = streams.electrics.airspeed;
        const loggerTimeInSeconds = (performance.now() - loggerStartTime) / 1000;  // Logger time in seconds

        // Check the distance traveled and log milestone times
        const deltaTime = loggerTimeInSeconds - (scope.lastUpdateTime || loggerTimeInSeconds);
        scope.lastUpdateTime = loggerTimeInSeconds;

        const distanceTraveled = speedMs * deltaTime;

        // 60ft Logic
        scope.distance_60ft += distanceTraveled;
        if (scope.distance_60ft >= scope.goalEnd_60ft && !targetTimes['60ft']) {
          targetTimes['60ft'] = loggerTimeInSeconds;
          console.log("60ft reached! Logger time: " + targetTimes['60ft'] + "s");
        }

        // 330ft Logic
        scope.distance_330ft += distanceTraveled;
        if (scope.distance_330ft >= scope.goalEnd_330ft && !targetTimes['330ft']) {
          targetTimes['330ft'] = loggerTimeInSeconds;
          console.log("330ft reached! Logger time: " + targetTimes['330ft'] + "s");
        }

        // 660ft Logic
        scope.distance_660ft += distanceTraveled;
        if (scope.distance_660ft >= scope.goalEnd_660ft && !targetTimes['660ft']) {
          targetTimes['660ft'] = loggerTimeInSeconds;
          console.log("660ft reached! Logger time: " + targetTimes['660ft'] + "s");
        }

        // 1000ft Logic
        scope.distance_1000ft += distanceTraveled;
        if (scope.distance_1000ft >= scope.goalEnd_1000ft && !targetTimes['1000ft']) {
          targetTimes['1000ft'] = loggerTimeInSeconds;
          console.log("1000ft reached! Logger time: " + targetTimes['1000ft'] + "s");
        }

        // 1320ft Logic
        scope.distance_1320ft += distanceTraveled;
        if (scope.distance_1320ft >= scope.goalEnd_1320ft && !targetTimes['1320ft']) {
          targetTimes['1320ft'] = loggerTimeInSeconds;
          console.log("1320ft reached! Logger time: " + targetTimes['1320ft'] + "s");
        }
      };

      // Function to start recording and set loggerStartTime
      function startRecording() {
        isRecording = true;
        loggerStartTime = performance.now();  // Capture logger start time
        console.log("Recording started at: " + loggerStartTime);

        scope.initializeDragPassTimers();  // Reset all distances
      }

      // Add your event listeners to buttons and elements as needed...
      element.on('load', function() {
        svgDocument = element[0].contentDocument;

        const startButton = svgDocument.getElementById('startButton');
        const btn60ft = svgDocument.getElementById('60ftButton');
        const btn330ft = svgDocument.getElementById('330ftButton');
        const btn660ft = svgDocument.getElementById('660ftButton');
        const btn1000ft = svgDocument.getElementById('1000ftButton');
        const btn1320ft = svgDocument.getElementById('1320ftButton');

        startButton.addEventListener('click', function() {
          startRecording();  // Start the logger when the start button is clicked
        });

        btn60ft.addEventListener('click', function() {
          if (targetTimes['60ft'] !== null) {
            scope.moveToTargetTime(targetTimes['60ft']);
          }
        });

        btn330ft.addEventListener('click', function() {
          if (targetTimes['330ft'] !== null) {
            scope.moveToTargetTime(targetTimes['330ft']);
          }
        });

        btn660ft.addEventListener('click', function() {
          if (targetTimes['660ft'] !== null) {
            scope.moveToTargetTime(targetTimes['660ft']);
          }
        });

        btn1000ft.addEventListener('click', function() {
          if (targetTimes['1000ft'] !== null) {
            scope.moveToTargetTime(targetTimes['1000ft']);
          }
        });

        btn1320ft.addEventListener('click', function() {
          if (targetTimes['1320ft'] !== null) {
            scope.moveToTargetTime(targetTimes['1320ft']);
          }
});
});

      function updateLinePosition() {
        movableLineElement.setAttribute('x1', currentX);
        movableLineElement.setAttribute('x2', currentX);
        updatePositionDisplay();
      }


      // Update Drag Pass Timers Logic
      scope.updateDragPassTimers = function(streams) {
        // Only update the timers if the logger is recording
        if (!isRecording) {
          console.log("Logger is not recording. Drag pass timers will not run.");
          return;  // Exit early if not recording
        }

        const speedMs = streams.electrics.airspeed;
        const stopThreshold = 0.1;  // Small threshold to treat the car as stopped

        // Use time delta to calculate distance traveled
        const newTime = performance.now();
        const deltaTime = (newTime - scope.lastUpdateTime) / 1000; // Time in seconds since last update
        scope.lastUpdateTime = newTime;

        const distanceTraveled = speedMs * deltaTime;

        // 330ft Timer Logic
        if (scope.ready_330ft && speedMs >= stopThreshold) {
          scope.distance_330ft += distanceTraveled;

          if (scope.distance_330ft >= scope.goalEnd_330ft) {
            console.log("330ft reached! Timer: " + scope.timer_330ft + "ms");
            scope.ready_330ft = false;  // Stop the timer
            scope.distance_330ft = 0;   // Reset distance
          } else {
            scope.timer_330ft += deltaTime * 1000;  // Update the timer in milliseconds
          }

          console.log("330ft: Recording, Distance: " + scope.distance_330ft + "m, Timer: " + scope.timer_330ft + "ms");
        } else if (speedMs < stopThreshold) {
          console.log("330ft: Car stopped, ready to record");
          scope.ready_330ft = true;
          scope.timer_330ft = 0;  // Reset timer when stopped
          scope.distance_330ft = 0; // Reset distance when stopped
        }

        // 660ft Timer Logic
        if (scope.ready_660ft && speedMs >= stopThreshold) {
          scope.distance_660ft += distanceTraveled;

          if (scope.distance_660ft >= scope.goalEnd_660ft) {
            console.log("660ft reached! Timer: " + scope.timer_660ft + "ms");
            scope.ready_660ft = false;  // Stop the timer
            scope.distance_660ft = 0;   // Reset distance
          } else {
            scope.timer_660ft += deltaTime * 1000;  // Update the timer in milliseconds
          }

          console.log("660ft: Recording, Distance: " + scope.distance_660ft + "m, Timer: " + scope.timer_660ft + "ms");
        } else if (speedMs < stopThreshold) {
          console.log("660ft: Car stopped, ready to record");
          scope.ready_660ft = true;
          scope.timer_660ft = 0;  // Reset timer when stopped
          scope.distance_660ft = 0; // Reset distance when stopped
        }

        // 60ft Timer Logic
        if (scope.ready_60ft && speedMs >= stopThreshold) {
          scope.distance_60ft += distanceTraveled;

          if (scope.distance_60ft >= scope.goalEnd_60ft) {
            console.log("60ft reached! Timer: " + scope.timer_60ft + "ms");
            scope.ready_60ft = false;  // Stop the timer
            scope.distance_60ft = 0;   // Reset distance
          } else {
            scope.timer_60ft += deltaTime * 1000;  // Update the timer in milliseconds
          }

          console.log("60ft: Recording, Distance: " + scope.distance_60ft + "m, Timer: " + scope.timer_60ft + "ms");
        } else if (speedMs < stopThreshold) {
          console.log("60ft: Car stopped, ready to record");
          scope.ready_60ft = true;
          scope.timer_60ft = 0;  // Reset timer when stopped
          scope.distance_60ft = 0; // Reset distance when stopped
        }

        // 1000ft Timer Logic
        if (scope.ready_1000ft && speedMs >= stopThreshold) {
          scope.distance_1000ft += distanceTraveled;

          if (scope.distance_1000ft >= scope.goalEnd_1000ft) {
            console.log("1000ft reached! Timer: " + scope.timer_1000ft + "ms");
            scope.ready_1000ft = false;  // Stop the timer
            scope.distance_1000ft = 0;   // Reset distance
          } else {
            scope.timer_1000ft += deltaTime * 1000;  // Update the timer in milliseconds
          }

          console.log("1000ft: Recording, Distance: " + scope.distance_1000ft + "m, Timer: " + scope.timer_1000ft + "ms");
        } else if (speedMs < stopThreshold) {
          console.log("1000ft: Car stopped, ready to record");
          scope.ready_1000ft = true;
          scope.timer_1000ft = 0;  // Reset timer when stopped
          scope.distance_1000ft = 0; // Reset distance when stopped
        }

        // 1320ft Timer Logic
        if (scope.ready_1320ft && speedMs >= stopThreshold) {
          scope.distance_1320ft += distanceTraveled;

          if (scope.distance_1320ft >= scope.goalEnd_1320ft) {
            console.log("1320ft reached! Timer: " + scope.timer_1320ft + "ms");
            scope.ready_1320ft = false;  // Stop the timer
            scope.distance_1320ft = 0;   // Reset distance
          } else {
            scope.timer_1320ft += deltaTime * 1000;  // Update the timer in milliseconds
          }

          console.log("1320ft: Recording, Distance: " + scope.distance_1320ft + "m, Timer: " + scope.timer_1320ft + "ms");
        } else if (speedMs < stopThreshold) {
          console.log("1320ft: Car stopped, ready to record");
          scope.ready_1320ft = true;
          scope.timer_1320ft = 0;  // Reset timer when stopped
          scope.distance_1320ft = 0; // Reset distance when stopped
        }
      };

      // Update graph and position of the vertical data line
      function moveToTargetDistance(targetDistance) {
        let timeAtTarget = 0;
        if (targetDistance === 60) {
          timeAtTarget = scope.timer_60ft;
        } else if (targetDistance === 330) {
          timeAtTarget = scope.timer_330ft;
        } else if (targetDistance === 660) {
          timeAtTarget = scope.timer_660ft;
        } else if (targetDistance === 1000) {
          timeAtTarget = scope.timer_1000ft;
        } else if (targetDistance === 1320) {
          timeAtTarget = scope.timer_1320ft;
        }

        // Calculate the x position of the vertical line based on time
        const xPos = minX + (timeAtTarget / 20) * (maxX - minX);
        currentX = xPos;
        updateLinePosition(); // Update the position of the vertical line on the graph
      }

      element.on('load', function() {
        svgDocument = element[0].contentDocument;
        rpmLine = svgDocument.getElementById('rpmLine');
        wpLine = svgDocument.getElementById('wpLine');
        asLine = svgDocument.getElementById('asLine');
        tpsLine = svgDocument.getElementById('tpsLine');
        psiLine = svgDocument.getElementById('psiLine');
        gearLine = svgDocument.getElementById('gearLine');
        gforceLine = svgDocument.getElementById('gforceLine');

        rpmReadout = svgDocument.getElementById('rpmReadout');
        wheelSpeedReadout = svgDocument.getElementById('wheelSpeed');
        airSpeedReadout = svgDocument.getElementById('airSpeed');
        tpsReadout = svgDocument.getElementById('tpsReadout');
        psiReadout = svgDocument.getElementById('psiReadout');
        gearReadout = svgDocument.getElementById('gearReadout');
        gforceReadout = svgDocument.getElementById('gforceReadout');

        movableLineElement = svgDocument.getElementById('movableLine');
        linePositionElement = svgDocument.getElementById('linePosition');

        const leftArrowInner = svgDocument.getElementById('leftArrowInner');
        const rightArrowInner = svgDocument.getElementById('rightArrowInner');
        const leftArrowOuter = svgDocument.getElementById('leftArrowOuter');
        const rightArrowOuter = svgDocument.getElementById('rightArrowOuter');
        const playPauseButton = svgDocument.getElementById('playPauseButton');  // Play/Pause button
        const playSymbol = svgDocument.getElementById('playSymbol');  // Play symbol
        const pauseSymbol = svgDocument.getElementById('pauseSymbol');  // Pause symbol

        const Record = svgDocument.getElementById('Record');  // Group containing the button
        const RecordRect = Record.querySelector('rect');  // The <rect> element for color
        const RecordText = Record.querySelector('text');  // The <text> element for label
        let rpmCheckbox = svgDocument.getElementById('rpmCheckbox');
        let wpCheckbox = svgDocument.getElementById('wpCheckbox');
        let asCheckbox = svgDocument.getElementById('asCheckbox');
        let tpsCheckbox = svgDocument.getElementById('tpsCheckbox');
        let psiCheckbox = svgDocument.getElementById('psiCheckbox');
        let gearCheckbox = svgDocument.getElementById('gearCheckbox');
        let gforceCheckbox = svgDocument.getElementById('gforceCheckbox');

        function toggleCheckbox(checkbox, line) {
          let isChecked = checkbox.getAttribute('fill') === 'green';
          checkbox.setAttribute('fill', isChecked ? 'red' : 'green');  // Change checkbox color
          line.style.display = isChecked ? 'none' : 'inline';  // Toggle line visibility
        }

        rpmCheckbox.addEventListener('click', function() {
          toggleCheckbox(rpmCheckbox, rpmLine);
        });

        wpCheckbox.addEventListener('click', function() {
          toggleCheckbox(wpCheckbox, wpLine);
        });

        asCheckbox.addEventListener('click', function() {
          toggleCheckbox(asCheckbox, asLine);
        });

        tpsCheckbox.addEventListener('click', function() {
          toggleCheckbox(tpsCheckbox, tpsLine);
        });

        psiCheckbox.addEventListener('click', function() {
          toggleCheckbox(psiCheckbox, psiLine);
        });

        gearCheckbox.addEventListener('click', function() {
          toggleCheckbox(gearCheckbox, gearLine);
        });

        gforceCheckbox.addEventListener('click', function() {
          toggleCheckbox(gforceCheckbox, gforceLine);
        });

        function updateGraph() {
          let rpmPoints = rpmData.map(data => {
            let x = 130 + (data.time / 20) * (590 - 128);
            let y = 263 - (data.rpm / maxRPM) * (263 - 110);
            return `${x},${y}`;
          }).filter(point => point !== '').join(' ');
          rpmLine.setAttribute('points', rpmPoints);

          let wpPoints = wpData.map(data => {
            let x = 130 + (data.time / 20) * (590 - 128);
            let y = 263 - (data.wheelSpeed * 2.23694 / 400) * (263 - 50);
            return `${x},${y}`;
          }).filter(point => point !== '').join(' ');
          wpLine.setAttribute('points', wpPoints);

          let asPoints = asData.map(data => {
            let x = 130 + (data.time / 20) * (590 - 128);
            let y = 263 - (data.airSpeed * 2.23694 / 400) * (263 - 50);
            if (isNaN(x) || isNaN(y)) return '';
            return `${x},${y}`;
          }).filter(point => point !== '').join(' ');
          asLine.setAttribute('points', asPoints);

          let tpsPoints = tpsData.map(data => {
            let x = 130 + (data.time / 20) * (590 - 128);
            let y = 263 - ((data.tps * 100) / 100) * (263 - 90);
            if (isNaN(x) || isNaN(y)) return '';
            return `${x},${y}`;
          }).filter(point => point !== '').join(' ');
          tpsLine.setAttribute('points', tpsPoints);

          let psiPoints = psiData.map(data => {
            let x = 130 + (data.time / 20) * (590 - 128);
            let y = 263 - ((data.psi + 14.7) / (150 + 14.7)) * (263 - 50);
            if (isNaN(x) || isNaN(y)) return '';
            return `${x},${y}`;
          }).filter(point => point !== '').join(' ');
          psiLine.setAttribute('points', psiPoints);

          let gearPoints = gearData.map(data => {
            let x = 130 + (data.time / 20) * (590 - 128);
            let y = 263 - ((data.gear + 1) / 11) * (263 - 50);
            if (isNaN(x) || isNaN(y)) return '';
            return `${x},${y}`;
          }).filter(point => point !== '').join(' ');
          gearLine.setAttribute('points', gearPoints);

          let gforcePoints = gforceData.map(data => {
            let x = 130 + (data.time / 20) * (590 - 128);
            let y = 263 - ((data.gforce + 3) / 15) * (263 - 50);
            if (isNaN(x) || isNaN(y)) return '';
            return `${x},${y}`;
          }).filter(point => point !== '').join(' ');
          gforceLine.setAttribute('points', gforcePoints);
        }

        function updateRPMReadout(timeInSeconds) {
          const closestDataPoint = rpmData.reduce((prev, curr) => {
            return (Math.abs(curr.time - timeInSeconds) < Math.abs(prev.time - timeInSeconds) ? curr : prev);
          }, rpmData[0]);

          if (closestDataPoint) {
            rpmReadout.textContent = ' ' + closestDataPoint.rpm.toFixed(2);
          }
        }

        function updateWheelSpeedReadout(timeInSeconds) {
          const closestWPData = wpData.reduce((prev, curr) => {
            return (Math.abs(curr.time - timeInSeconds) < Math.abs(prev.time - timeInSeconds) ? curr : prev);
          }, wpData[0]);

          if (closestWPData) {
            wheelSpeedReadout.textContent = ' ' + (closestWPData.wheelSpeed * 2.23694).toFixed(2) + ' mph';
          }
        }

        function updateAirSpeedReadout(timeInSeconds) {
          const closestASData = asData.reduce((prev, curr) => {
            return (Math.abs(curr.time - timeInSeconds) < Math.abs(prev.time - timeInSeconds) ? curr : prev);
          }, asData[0]);

          if (closestASData) {
            airSpeedReadout.textContent = ' ' + (closestASData.airSpeed * 2.23694).toFixed(2) + ' mph';
          }
        }

        function updateTPSReadout(timeInSeconds) {
          const closestTPSData = tpsData.reduce((prev, curr) => {
            return (Math.abs(curr.time - timeInSeconds) < Math.abs(prev.time - timeInSeconds) ? curr : prev);
          }, tpsData[0]);

          if (closestTPSData) {
            tpsReadout.textContent = ' ' + (closestTPSData.tps * 100).toFixed(2) + ' %';
          }
        }

        function updatePSIReadout(timeInSeconds) {
          const closestPSIData = psiData.reduce((prev, curr) => {
            return (Math.abs(curr.time - timeInSeconds) < Math.abs(prev.time - timeInSeconds) ? curr : prev);
          }, psiData[0]);

          if (closestPSIData) {
            psiReadout.textContent = ' ' + closestPSIData.psi.toFixed(2) + ' psi';
          }
        }

        function updateGearReadout(timeInSeconds) {
          const closestGearData = gearData.reduce((prev, curr) => {
            return (Math.abs(curr.time - timeInSeconds) < Math.abs(prev.time - timeInSeconds) ? curr : prev);
          }, gearData[0]);

          if (closestGearData) {
            gearReadout.textContent = ' ' + closestGearData.gear;
          }
        }

        function updateGForceReadout(timeInSeconds) {
          const closestGForceData = gforceData.reduce((prev, curr) => {
            return (Math.abs(curr.time - timeInSeconds) < Math.abs(prev.time - timeInSeconds) ? curr : prev);
          }, gforceData[0]);

          if (closestGForceData) {
            gforceReadout.textContent = ' ' + closestGForceData.gforce.toFixed(2);
          }
        }

        function updatePositionDisplay() {
          const seconds = ((currentX - minX) / secondsPerUnit).toFixed(2);
          linePositionElement.textContent = seconds + 's';
          updateRPMReadout(seconds);
          updateWheelSpeedReadout(seconds);
          updateAirSpeedReadout(seconds);
          updateTPSReadout(seconds);
          updatePSIReadout(seconds);
          updateGearReadout(seconds);
          updateGForceReadout(seconds);
        }

        function updateLinePosition() {
          movableLineElement.setAttribute('x1', currentX);
          movableLineElement.setAttribute('x2', currentX);
          updatePositionDisplay();
        }

        function startRecording() {
          isRecording = true;
          currentX = minX;  // Move the line to the beginning
          updateLinePosition();  // Update the line position to the start

          let currentTime = 0;
          rpmData = [], wpData = [], asData = [], tpsData = [], psiData = [], gearData = [], gforceData = [];

          let interval = setInterval(function() {
              if (currentTime >= 20 || !isRecording) {  // Stop recording when time reaches or user clicks stop
                  clearInterval(interval);
                  isRecording = false;

                  // Move the line back to the center when done recording
                  currentX = (minX + maxX) / 2;
                  updateLinePosition();

                  // Change button back to green Start
                  RecordRect.setAttribute('fill', '#00FF00');
                  RecordText.textContent = 'Record';
                  return;
              }
            currentTime += 0.010;

            currentX = minX + (currentTime / 20) * (maxX - minX);  // Move the line with time
            updateLinePosition();  // Update the line position along with recording

            rpmData.push({ time: currentTime, rpm: currentRPM });
            wpData.push({ time: currentTime, wheelSpeed: currentWheelSpeed });
            asData.push({ time: currentTime, airSpeed: currentAirSpeed });
            tpsData.push({ time: currentTime, tps: currentTPS });
            psiData.push({ time: currentTime, psi: currentPSI });
            gearData.push({ time: currentTime, gear: currentGear });
            gforceData.push({ time: currentTime, gforce: currentGForce });

            updateGraph();
          }, 10);
        }

        // Toggle Start/Stop button functionality
        Record.addEventListener('click', function() {
         if (!isRecording) {
             // Start recording
             startRecording();

             // Change button to red Stop
             RecordRect.setAttribute('fill', 'red');
             RecordText.textContent = 'Stop';
             isRecording = true;
         } else {
             // Stop recording
             isRecording = false;  // Stop the recording

             // Change button back to green Start
             RecordRect.setAttribute('fill', '#00FF00');
             RecordText.textContent = 'Record';
         }
     });

        function togglePlayPause() {
          if (isPlaying) {
            // Pause the playback
            clearInterval(playInterval);
            isPlaying = false;
            playSymbol.style.display = 'inline';  // Show the play triangle
            pauseSymbol.style.display = 'none';   // Hide the pause bars
          } else {
            // Start playing
            playInterval = setInterval(function() {
              if (currentX < maxX) {
                currentX += (secondsPerUnit / 100); // Adjust for playback speed
                if (currentX > maxX) {
                  currentX = maxX;
                  clearInterval(playInterval);
                }
                updateLinePosition();
              } else {
                clearInterval(playInterval);  // Stop playback at the end
              }
            }, 10); // Adjust this for speed control (10ms = smooth real-time)
            isPlaying = true;
            playSymbol.style.display = 'none';   // Hide the play triangle
            pauseSymbol.style.display = 'inline'; // Show the pause bars
          }
        }

        playPauseButton.addEventListener('click', function() {
          togglePlayPause();  // Toggle play or pause when the button is clicked
        });

        // Event listeners for the inner and outer arrows
        leftArrowInner.addEventListener('mousedown', function(event) {
          if (event.button === 0) {  // Left click
            if (currentX > minX) {
              currentX -= secondsPerUnit;
              if (currentX < minX) currentX = minX;  // Bound check
              updateLinePosition();
            }
          } else if (event.button === 2) {  // Right click
            if (currentX > minX) {
              currentX -= secondsPerUnit / 2;
              if (currentX < minX) currentX = minX;
              updateLinePosition();
            }
          }
        });

        rightArrowInner.addEventListener('mousedown', function(event) {
          if (event.button === 0) {  // Left click
            if (currentX < maxX) {
              currentX += secondsPerUnit;
              if (currentX > maxX) currentX = maxX;  // Bound check
              updateLinePosition();
            }
          } else if (event.button === 2) {  // Right click
            if (currentX < maxX) {
              currentX += secondsPerUnit / 2;
              if (currentX > maxX) currentX = maxX;
              updateLinePosition();
            }
          }
        });

        leftArrowOuter.addEventListener('mousedown', function(event) {
          if (event.button === 0) {  // Left click
            if (currentX > minX) {
              currentX -= (secondsPerUnit / 10);
              if (currentX < minX) currentX = minX;
              updateLinePosition();
            }
          } else if (event.button === 2) {  // Right click
            if (currentX > minX) {
              currentX -= (secondsPerUnit / 100);
              if (currentX < minX) currentX = minX;
              updateLinePosition();
            }
          }
        });

        rightArrowOuter.addEventListener('mousedown', function(event) {
          if (event.button === 0) {  // Left click
            if (currentX < maxX) {
              currentX += (secondsPerUnit / 10);
              if (currentX > maxX) currentX = maxX;
              updateLinePosition();
            }
          } else if (event.button === 2) {  // Right click
            if (currentX < maxX) {
              currentX += (secondsPerUnit / 100);
              if (currentX > maxX) currentX = maxX;
              updateLinePosition();
            }
          }
        });

        svgDocument.addEventListener('contextmenu', function(event) {
          event.preventDefault();
        });

        scope.$on('streamsUpdate', function(event, streams) {
          if (streams.engineInfo && streams.engineInfo.length > 4) {
            currentRPM = streams.engineInfo[4];
            currentWheelSpeed = streams.electrics.wheelspeed;
            currentAirSpeed = streams.electrics.airspeed;
            currentTPS = streams.electrics.throttle;
            currentPSI = streams.electrics.boost;
            currentGear = streams.electrics.gear;

            if (streams.engineInfo.length > 1) {
              maxRPM = streams.engineInfo[1] || 16000;
            }

            const gravity = streams.sensors.gravity || 9.81;
            const gx2 = streams.sensors.gx2 || 0;
            const gy2 = streams.sensors.gy2 || 0;
            const gz2 = streams.sensors.gz2 || 0;

            currentGForce = Math.sqrt(gx2 * gx2 + gy2 * gy2 + (gz2 + 9.81) * (gz2 + 9.81)) / 9.81;
          }

          // Update drag pass timers with the stream data
          scope.updateDragPassTimers(streams);
        });

        scope.$on('$destroy', function() {
          saveData();
          rpmLine = null;
          wpLine = null;
          asLine = null;
          tpsLine = null;
          psiLine = null;
          gearLine = null;
          gforceLine = null;
          rpmReadout = null;
          wheelSpeedReadout = null;
          airSpeedReadout = null;
          tpsReadout = null;
          psiReadout = null;
          gearReadout = null;
          gforceReadout = null;
          movableLineElement = null;
          linePositionElement = null;
        });

        loadData();
        updateLinePosition(); // Restore the vertical line position on load
        updateGraph(); // Restore the graph data on load
        scope.initializeDragPassTimers(); // Initialize drag pass timers on load
      });
    }
  };
}]);
