public MainWindowViewModel()
        {
            CalculateTheAnswer = new ReactiveAsyncCommand();

            CalculateTheAnswer.RegisterAsyncTask(_ => AnswerCalculator())
                .ToProperty(this, x => x.TheAnswer);

            CalculateTheAnswer.ThrownExceptions
                .SelectMany(ex => UserError.Throw(ex.Message))
                .Subscribe(result =>
                {
                    if (result == RecoveryOptionResult.RetryOperation)
                    {
                        _retryCalculate = true;
                        CalculateTheAnswer.Execute(null);
                    }
                    else
                        Application.Current.Shutdown();
                });
        }
        public void ReactiveAsyncCommandInitialConditionDefaultBehavior()
        {
            (new TestScheduler()).With(sched => {
                var canExecute = sched.CreateHotObservable(
                    sched.OnNextAt(0, false),
                    sched.OnNextAt(250, true)
                    );

                var fixture = new ReactiveAsyncCommand(canExecute);

                fixture.RegisterAsyncTask(_ => DummyTestFunction());

                Assert.True(fixture.CanExecute(null));

                sched.AdvanceToMs(10);
                Assert.False(fixture.CanExecute(null));

                sched.AdvanceToMs(255);
                Assert.True(fixture.CanExecute(null));
            });
        }
        public SettingsVM(
            ISettingsService Settings,
            ICleanupData Cleanup,
            IConnectivityService Connectivity
            ) {
            this.Cleanup = Cleanup;
            this.Settings = Settings;
            this.Connectivity = Connectivity;

            this.WhenAny(x => x.Model, x => x.Value)
                .Where(x => x != null)
                .Select(m => m.UseGPS)
                .Subscribe(x => UseGPS = x);

            Reset = new ReactiveAsyncCommand(Connectivity.WifiAvailable());

            Reset.RegisterAsyncTask(OnReset);

            var setting_changed =
                this.WhenAny(x => x.UseGPS, x => x.Model,
                    (gps, model) => (model.Value != null) ? model.Value.UseGPS != gps.Value : false);

            Save = new ReactiveCommand(setting_changed);
            Messenger.RegisterMessageSource(
                Save
                .Do(_ => saveModel())
                .Select(_ => Page.Previous)
                );

            RefreshVocabulary = new ReactiveCommand(Connectivity.WifiAvailable());
            RefreshVocabulary
                .Subscribe(_ => {
                    Messenger.SendMessage(Page.SetupVocabulary);
                });





            ManageTaxa = new ReactiveCommand();
            Messenger.RegisterMessageSource(
                ManageTaxa
                .Select(_ => Page.TaxonManagement)
                );

            UploadData = new ReactiveCommand();
            Messenger.RegisterMessageSource(
                UploadData
                .Select(_ => Page.Upload)
                );

            DownloadData = new ReactiveCommand();
            Messenger.RegisterMessageSource(
                DownloadData
                .Select(_ => Page.Download)
                );

            Info = new ReactiveCommand();
            Messenger.RegisterMessageSource(
                Info
                .Select(_ => Page.Info)
                );

            ImportExport = new ReactiveCommand();
            Messenger.RegisterMessageSource(
                ImportExport
                .Select(_ => Page.ImportExport)
                );

            Settings
                .SettingsObservable()
                .Subscribe(x => Model = x);
        }
        public EditViewModel()
        {
            LoadImage = new ReactiveAsyncCommand();
            ShareImage = new ReactiveCommand();

            this.WhenAny(x => x.ImagePath, x => x.Value)
                .Where(x => !String.IsNullOrWhiteSpace(x) && File.Exists(x))
                .InvokeCommand(LoadImage);

            LoadImage.RegisterAsyncTask(x => BitmapLoader.Current.Load(File.OpenRead((string)x)))
                .Do(_ => { if(LoadedImage != null) LoadedImage.Dispose(); })
                .ToProperty(this, x => x.LoadedImage);

            var huffRects = this.WhenAny(x => x.ScreenRect, x => x.DatImg, x => x.DensityFactor, x => x.OnBottom, x => x.OnRight, 
                (screen, img, density, bottom, right) => CalculateHuffmanRects(screen.Value, img.Value, density.Value, bottom.Value, right.Value));

            huffRects.Select(x => x.Item1).ToProperty(this, x => x.HuffmanSrcRect);
            huffRects.Select(x => x.Item2).ToProperty(this, x => x.HuffmanDestRect);

            this.WhenAny(x => x.ScreenRect, x => x.LoadedImage, x => x.DensityFactor, 
                (frame, img, density) => calculateImageRect(frame.Value, img.Value, density.Value))
                .ToProperty(this, x => x.ImageDestRect);

        }
        public WelcomeViewModel(MediaPicker picker)
        {
            TakeNewPhoto = new ReactiveAsyncCommand();
            ChooseExistingPhoto = new ReactiveAsyncCommand();
            StartEdit = new ReactiveCommand();

            var defaultCamera = new StoreCameraMediaOptions() { DefaultCamera = CameraDevice.Rear, Directory = "LeeMe", Name = "turnt.jpg", };

            Observable.Merge(
                    TakeNewPhoto.RegisterAsyncTask(_ => picker.TakePhotoAsync(defaultCamera)),
                    ChooseExistingPhoto.RegisterAsyncTask(_ => picker.PickPhotoAsync()))
                .Select(x => x.Path)
                .InvokeCommand(StartEdit);

            // TODO: Write a proper UserError handler for this
            TakeNewPhoto.ThrownExceptions.Subscribe(ex => Console.WriteLine(ex));
            ChooseExistingPhoto.ThrownExceptions.Subscribe(ex => Console.WriteLine(ex));
        }