private void PartitionAndPlanTasks()
        {
            var numTilesX = (int)Math.Ceiling(_pixelWidth / (double)_maxPixelTileSize);
            var numTilesY = (int)Math.Ceiling(_pixelHeight / (double)_maxPixelTileSize);
            var stepX     = _complexWidth / _pixelWidth;
            var stepY     = _complexHeight / _pixelHeight;

            for (var tileY = 0; tileY < numTilesY; tileY++)
            {
                for (var tileX = 0; tileX < numTilesX; tileX++)
                {
                    if (_stopRendering)
                    {
                        return;
                    }
                    var borderX = Math.Min(_pixelWidth - tileX * _maxPixelTileSize, _maxPixelTileSize);
                    var borderY = Math.Min(_pixelHeight - tileY * _maxPixelTileSize, _maxPixelTileSize);


                    var currentCornerX = tileX * _maxPixelTileSize;
                    var currentCornerY = tileY * _maxPixelTileSize;
                    var complexStartX  = _x + currentCornerX * stepX;
                    var complexStartY  = _y + _complexHeight - currentCornerY * stepY;

                    var t = new FractalTask(_maxIterations, stepX, stepY, complexStartX, complexStartY,
                                            new Point(currentCornerX, currentCornerY), borderX, borderY, TaskType.Calculate);

                    _tasks.Enqueue(t);
                }
            }
        }
        private void Draw(FractalTask t)
        {
            System.Diagnostics.Debug.WriteLine(Thread.CurrentThread.Name + ": Drawing");

            var colorBuffer = new byte[3];


            for (var y = 0; y < t.Height; y++)
            {
                for (var x = 0; x < t.Width; x++)
                {
                    var currentPos = 4 * ((int)t.UpperLeftCorner.X + x +
                                          ((int)t.UpperLeftCorner.Y + y) * _pixelWidth);

                    if (_colorMapper != null)
                    {
                        _colorMapper.MapColor(Convert.ToInt32(t.GetIterations(x, y)), _maxIterations,
                                              Math.Abs(Convert.ToDouble(t.GetImaginaryPart(y))),
                                              Math.Abs(Convert.ToDouble(t.GetRealPart(x))), ref colorBuffer);
                    }
                    else
                    {
                        _defaultColorMapper.MapColor(Convert.ToInt32(t.GetIterations(x, y)), _maxIterations,
                                                     Math.Abs(Convert.ToDouble(t.GetImaginaryPart(y))),
                                                     Math.Abs(Convert.ToDouble(t.GetRealPart(x))), ref colorBuffer);
                    }
                    _pixelValues[currentPos]     = colorBuffer[2];
                    _pixelValues[currentPos + 1] = colorBuffer[1];
                    _pixelValues[currentPos + 2] = colorBuffer[0];
                    _pixelValues[currentPos + 3] = 255;
                }
            }
            if (_stopRendering)
            {
                return;
            }

            _previousDrawnTasks.Enqueue(t);
            OnTileAvailable(new EventArgs());
        }
        //  public double[][,] calculate(int resultX = 1920, int resultY = 1080, int maxIterations = 1000, Image img = null)

        private void InternalCalculate(FractalTask t)
        {
            System.Diagnostics.Debug.WriteLine(Thread.CurrentThread.Name + ": Calculating");
            for (var y = 0; y < t.Height; y++)
            {
                var cIm = t.GetImaginaryPart(y);

                for (var x = 0; x < t.Width; x++)
                {
                    var     cReal = t.GetRealPart(x);
                    decimal zReal = 0;
                    decimal zIm   = 0;
                    decimal zAbs  = 0;
                    var     n     = 0;

                    while (zAbs <= 4 && n <= t.MaxIterations)
                    {
                        var tmp = zReal;
                        zReal = zReal * zReal - zIm * zIm + cReal;
                        zIm   = 2 * tmp * zIm + cIm;
                        zAbs  = zReal * zReal + zIm * zIm;
                        n++;
                    }
                    if (_stopRendering)
                    {
                        return;
                    }

                    t.SetIterations(x, y, n);
                }
            }

            t.Type = TaskType.Draw;
            if (!_stopRendering)
            {
                _drawingTasks.Enqueue(t);
            }
        }