HamBook – Rev 48

Subversion Repositories:
Rev:
using HamBook.Radios.Generic;
using HamBook.Radios;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Serilog;
using HamBook.Properties;
using System.Media;
using System.Reflection;
using RJCP.IO.Ports;

namespace HamBook
{
    public class MemoryTune
    {
        private CancellationTokenSource _scanningCancellationTokenSource;
        private CancellationToken _scanningCancellationToken;
        private Thread _scanThread;
        private CatAssemblies _catAssemblies;
        private SerialPortStream _serialPort;
        private Configuration.Configuration _configuration;
        private MemoryBanks _memoryBanks;

        private MemoryTune()
        {
        }

        public MemoryTune(CatAssemblies catAssemblies, SerialPortStream serialPort, Configuration.Configuration configuration) : this()
        {
            _catAssemblies = catAssemblies;
            _serialPort = serialPort;
            _configuration = configuration;

            _memoryBanks = MemoryBanks.Create(_configuration.Radio);
        }

        public void Start()
        {
            if (_scanThread != null)
            {
                if (!_scanningCancellationToken.IsCancellationRequested)
                {
                    _scanningCancellationTokenSource.Cancel();
                }

                _scanThread.Join();
                _scanThread = null;
            }

            _scanningCancellationTokenSource = new CancellationTokenSource();
            _scanningCancellationToken = _scanningCancellationTokenSource.Token;

            _scanThread = new Thread(new ParameterizedThreadStart(Tune));

            var memoryBankQueue = new Queue<string>();
            foreach (var bank in _memoryBanks.GetMemoryBanks())
            {
                memoryBankQueue.Enqueue(bank);
            }

            _scanThread.Start(memoryBankQueue);
        }

        public void Stop()
        {
            if (_scanThread != null)
            {
                if (!_scanningCancellationToken.IsCancellationRequested)
                {
                    _scanningCancellationTokenSource.Cancel();
                }

                _scanThread.Join();
                _scanThread = null;
            }
        }

        private async void Tune(object obj)
        {
            var memoryBankQueue = (Queue<string>)obj;

            do
            {
                try
                {

                    var memoryBank = memoryBankQueue.Dequeue();

                    using (var soundPlayer = new SoundPlayer(Assembly.GetExecutingAssembly().GetManifestResourceStream("HamBook.Effects.pot.wav")))
                    {
                        soundPlayer.Play();

                        if (!await _catAssemblies.CatSetAsync<int, bool>("MC", new object[] { memoryBank }, _scanningCancellationToken))
                        {
                            throw new MemoryTuneException(MemoryTuneExceptionCode.CouldNotChangeChannel, Resources.Could_not_change_channel);
                        }
                    }

                    if (!await _catAssemblies.CatSetAsync<TunerState, bool>("AC", new object[] { TunerState.TUNER_ON }, _scanningCancellationToken))
                    {
                        throw new MemoryTuneException(MemoryTuneExceptionCode.CouldNotEnableTuner, Resources.Could_not_enable_tuner);
                    }

                    do
                    {
                        await Task.Delay(TimeSpan.FromSeconds(1), _scanningCancellationToken);

                        try
                        {
                            var tuneState = await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { }, _scanningCancellationToken);

                            if (tuneState == TunerState.TUNER_ON)
                            {
                                break;
                            }
                        }
                        catch (Exception)
                        {
                            // retry
                        }

                    } while (!_scanningCancellationToken.IsCancellationRequested);

                    if (!await _catAssemblies.CatSetAsync<TunerState, bool>("AC", new object[] { TunerState.TUNING_START }, _scanningCancellationToken))
                    {
                        throw new MemoryTuneException(MemoryTuneExceptionCode.CouldNotStartTuning, Resources.Could_not_start_tuning);
                    }

                    do
                    {
                        await Task.Delay(TimeSpan.FromSeconds(1), _scanningCancellationToken);

                        try
                        {
                            var tuneState = await _catAssemblies.CatReadAsync<TunerState>("AC", new object[] { }, _scanningCancellationToken);

                            if (tuneState != TunerState.TUNING_START)
                            {
                                break;
                            }
                        }
                        catch (Exception)
                        {
                            // retry
                        }

                    } while (!_scanningCancellationToken.IsCancellationRequested);

                }
                catch(MemoryTuneException exception)
                {
                    Log.Error(exception, exception.Message);
                }
                catch (Exception exception)
                {
                    Log.Error(exception, Resources.Unknown_error_while_tuning);
                }

            } while (!_scanningCancellationToken.IsCancellationRequested && memoryBankQueue.Count != 0);

        }
    }
}