using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Text;
using System.Threading.Tasks;

namespace Operators
{
    class Examples26_27
    {
        private static IConnectableObservable<char> keySource = Observable.Create(
            (Func<IObserver<char>, IDisposable>) (obs =>
            {
                while (true)
                {
                    obs.OnNext(Console.ReadKey(true).KeyChar);
                }
            })).Publish();

        public static void WindowWordBreakIndefinite()
        {
            // Listing 11-26
            IObservable<IObservable<char>> wordWindows = keySource.Window(
                () => keySource.FirstAsync(char.IsWhiteSpace));

            IObservable<string> words = from wordWindow in wordWindows
                                        from chars in wordWindow.ToArray()
                                        select new string(chars).Trim();

            words.Subscribe(word => Console.WriteLine("Słowo: " + word));

            keySource.Connect();
        }

        public static void BufferWordBreakIndefinite()
        {
            // Listing 11-27
            IObservable<IList<char>> wordWindows = keySource.Buffer(
                () => keySource.FirstAsync(char.IsWhiteSpace));

            IObservable<string> words = from wordWindow in wordWindows
                                        select new string(wordWindow.ToArray()).Trim();


            words.Subscribe(word => Console.WriteLine("Słowo: " + word));

            keySource.Connect();
        }
    }
}
