// We can also pass the strategy implementation objects in the method
        // and not in the constructor to apply different behaviors to the same image.
        public void Store(string fileName, ICompressorStrategy compressor, IFilterStrategy filter)
        {
            compressor.ApplyCompression(fileName);

            filter.ApplyFilter(fileName);

            Console.WriteLine($"Store image with name {fileName}.");
        }
        public double ProcessReading(double rawValue)
        {
            double result = rawValue;

            if (!_initialized)
            {
                lock (_initilizedLock)
                {
                    if (!_initialized)
                    {
                        /* Initialize buffer with first value. */
                        _sampleSum    = rawValue * _samplesCount;
                        _averageValue = rawValue;

                        for (int i = 0; i < _samplesCount; i++)
                        {
                            _sampleBuffer[i] = _averageValue;
                        }

                        _initialized = true;
                    }
                }
            }

            double latestValue;

            if (_filterStrategy != null)
            {
                latestValue = result = _filterStrategy.ApplyFilter(rawValue, result);
            }
            else
            {
                latestValue = rawValue;
            }

            /* Increment circular buffer insertion index. */
            if (++_sampleIndex >= _samplesCount)
            {
                /* If at max length then wrap samples back
                 * to the beginning position in the list. */
                _sampleIndex = 0;
            }

            /* Add new and remove old at sampleIndex. */
            _sampleSum += latestValue;
            _sampleSum -= _sampleBuffer[_sampleIndex];
            _sampleBuffer[_sampleIndex] = latestValue;

            _averageValue = _sampleSum / _samplesCount;

            /* Stability check */
            double deltaAcceleration = _averageValue - latestValue;

            if (Math.Abs(deltaAcceleration) > StabilityDelta)
            {
                /* Unstable */
                _deviceStableCount = 0;
            }
            else
            {
                if (_deviceStableCount < _samplesCount)
                {
                    ++_deviceStableCount;
                }
            }

            if (_filterStrategy == null)
            {
                result = _averageValue;
            }

            return(result);
        }