private void PerformClick(WindowRectangle window, Click click,
                                  bool needDelay = true)
        {
            if (window == null)
            {
                throw new ArgumentNullException(nameof(window));
            }

            if (click == null)
            {
                throw new ArgumentNullException(nameof(click));
            }

            Point point = window.GetScreenPoint(click.Position);

            VirtualMouse.SendLeftClick(point);

            if (needDelay)
            {
                Thread.Sleep(click.Delay);
            }
        }
        public void OrderATaxi()
        {
            var resultDelay = EnterAddresses();

            if (resultDelay != TimeSpan.Zero)
            {
                Thread.Sleep(resultDelay);
            }

            int startIndex = 23;

            KeyValuePair <IntPtr, WindowRectangle>[]
            windows = _windows.ToArray();

            Stopwatch nextDelay = Stopwatch.StartNew();

            for (int i = 0; i < windows.Length; i++)
            {
                int index = startIndex;
                if (nextDelay.IsRunning)
                {
                    nextDelay.Stop();
                    resultDelay = TimeSpan.FromMilliseconds(_clickManager
                                                            .TaxiOrderingClicks[index].Delay) -
                                  nextDelay.Elapsed;

                    if (resultDelay > TimeSpan.Zero)
                    {
                        Thread.Sleep(resultDelay);
                    }
                }

                // Запускаем поиск такси в первом окне.
                // Click Select Bolt
                PerformClick(windows[i].Value,
                             _clickManager.TaxiOrderingClicks[index++]);

                // Click Request Bolt
                PerformClick(windows[i].Value,
                             _clickManager.TaxiOrderingClicks[index++]);

                // Click OK in messagebox (only once)
                PerformClick(windows[i].Value,
                             _clickManager.TaxiOrderingClicks[index++]);

                // Click chevron-up button
                PerformClick(windows[i].Value,
                             _clickManager.TaxiOrderingClicks[index++]);

                // Click Call
                PerformClick(windows[i].Value,
                             _clickManager.TaxiOrderingClicks[index++]);

                // DoubleClick to copy number

                VirtualMouse.SendMouseDoubleClick(windows[i].Value
                                                  .GetScreenPoint(_clickManager.TaxiOrderingClicks[index]
                                                                  .Position));

                // Ожидание для гарантии, что номер успел скопироваться в буфер обмена.
                Thread.Sleep(1000);

                // Сохранение номера телефона водителя.
                SaveNumberFromBuffer();

                Thread.Sleep(_clickManager.TaxiOrderingClicks[index++].Delay);

                // Click Home
                PerformClick(windows[i].Value,
                             _clickManager.TaxiOrderingClicks[index++]);

                // Click Bolt icon
                PerformClick(windows[i].Value,
                             _clickManager.TaxiOrderingClicks[index], false);

                Stopwatch startTime = Stopwatch.StartNew();
                if (i + 1 < windows.Length)
                {
                    // Запускаем поиск такси в следующем окне, если такое есть.
                    // Click Select Bolt
                    PerformClick(windows[i + 1].Value,
                                 _clickManager.TaxiOrderingClicks[startIndex]);

                    // Click Request Bolt
                    PerformClick(windows[i + 1].Value,
                                 _clickManager.TaxiOrderingClicks[startIndex + 1]);

                    // Click OK in messagebox (only once)
                    PerformClick(windows[i + 1].Value,
                                 _clickManager.TaxiOrderingClicks[startIndex + 2],
                                 false);

                    // Запускаем отсчёт времени для следующего окна.
                    nextDelay = Stopwatch.StartNew();
                }

                startTime.Stop();
                resultDelay = TimeSpan.FromMilliseconds(_clickManager
                                                        .TaxiOrderingClicks[index++].Delay) -
                              startTime.Elapsed;

                if (resultDelay > TimeSpan.Zero)
                {
                    Thread.Sleep(resultDelay);
                }

                // Click Cancel
                PerformClick(windows[i].Value,
                             _clickManager.TaxiOrderingClicks[index++]);

                // Click Cancel ride
                PerformClick(windows[i].Value,
                             _clickManager.TaxiOrderingClicks[index++]);

                // Click reason for cancellation
                int reasonIndex          = new Random().Next(0, 6); // всего 6 причин
                int caseAbsolutePosition =
                    450 + 41 *
                    reasonIndex; // (y=450 - первая причина на экране с h=768)
                double caseRelativePosition =
                    caseAbsolutePosition / 768.0;

                Point point = windows[i].Value.GetScreenPoint(new PointF(0.5f,
                                                                         (float)(_clickManager.TaxiOrderingClicks[index].Position
                                                                                 .Y * caseRelativePosition)));

                VirtualMouse.SendLeftClick(point);
                Thread.Sleep(_clickManager.TaxiOrderingClicks[index].Delay);
            }
        }