// ============================================================================
//  mandelbrot_strip_task.cpp —— 调色板构造 + renderStrip 纯计算实现
//  MandelbrotStripTask 的成员全部内联在头文件，本 .cpp 只需让 AUTOMOC 扫到
//  strip_task.h 的 Q_OBJECT（#include 它即可），并实现非内联的 MandelPalette
//  与 renderStrip。
// ============================================================================
#include "mandelbrot_strip_task.h"

#include <QColor>
#include <QtGlobal>

// 迭代次数 → HSV 色相循环（彩虹环），集合内部点统一黑色。
MandelPalette::MandelPalette(int maxIter) {
    const int n = qMax(1, maxIter);
    table_.resize(n);
    for (int i = 0; i < n; ++i) {
        if (i == n - 1) { table_[i] = qRgb(0, 0, 0); continue; }  // 集合内 → 黑
        const int hue = static_cast<int>((360.0 * 4.0 * i / n));
        table_[i] = QColor::fromHsv(hue % 360, 255, 255).rgb();
    }
}

// 标准 Mandelbrot 迭代 z = z² + c，逃逸半径 2。逐像素写入 RGB32。
QImage renderStrip(const MandelViewport& vp, const MandelPalette& pal, int y0, int y1) {
    const int w = vp.width;
    const int top = qBound(0, y0, vp.height);
    const int bot = qBound(0, y1, vp.height);
    if (w <= 0 || bot <= top) return {};

    QImage img(w, bot - top, QImage::Format_RGB32);
    const double x0 = vp.centerX - vp.scale * vp.width / 2.0;
    const double y0c = vp.centerY - vp.scale * vp.height / 2.0;
    const int maxIter = vp.maxIter;

    for (int py = top; py < bot; ++py) {
        const double cy = y0c + vp.scale * py;
        auto* line = reinterpret_cast<QRgb*>(img.scanLine(py - top));  // RGB32 = 每像素 1 个 QRgb
        for (int px = 0; px < w; ++px) {
            const double cx = x0 + vp.scale * px;
            double zx = 0.0, zy = 0.0;
            int iter = 0;
            while (iter < maxIter) {
                const double zx2 = zx * zx;
                const double zy2 = zy * zy;
                if (zx2 + zy2 > 4.0) break;  // 逃逸
                zy = 2.0 * zx * zy + cy;
                zx = zx2 - zy2 + cx;
                ++iter;
            }
            line[px] = pal.color(iter >= maxIter ? maxIter - 1 : iter);
        }
    }
    return img;
}
