// ************************************************************************** //
//                                                                            //
//    eses                   eses                                             //
//   eses                     eses                                            //
//  eses    eseses  esesese    eses   Embedded Systems Group                  //
//  ese    ese  ese ese         ese                                           //
//  ese    eseseses eseseses    ese   Department of Computer Science          //
//  eses   eses          ese   eses                                           //
//   eses   eseses  eseseses  eses    University of Kaiserslautern            //
//    eses                   eses                                             //
//                                                                            //
// ************************************************************************** //
// This modules computes a Mandelbrot set for a given image size.             //
// ************************************************************************** //

// size of the image
macro imageSize = (5,4);

// coordinates of lower left and upper right corner
macro lowerLeft  = (-2.0,-1.2);
macro upperRight = (1.0,1.2);

// size of a pixel
macro unit = (
    (re(upperRight)-re(lowerLeft))/re(imageSize),
    (im(upperRight)-im(lowerLeft))/im(imageSize)
);

// maximum number of iterations for divergence test
macro maxIterations = 20;

// imaginary numbers
macro re(x) = x.0;
macro im(x) = x.1;

module Mandelbrot( [re(imageSize)][im(imageSize)]bool image ) {
    // for all columns of the image
    for(x=0..re(imageSize)-1) do || {
        // current x position in the image
        real cx;
        cx = re(lowerLeft) + x * re(unit);
        // for all row of the image
        for(y=0..im(imageSize)-1) do || {
            int i;
            (real * real) z;

            real cy;
            cy = im(lowerLeft) + y * im(unit);

            // approximate convergence by iteration
            weak abort {
                // z = (cx,cy);
                re(z) = cx;
                im(z) = cy;
                i = 0;
                do {
                    // next(z) = ( re(z)*re(z)-im(z)*im(z)+cx, 2*re(z)*im(z)+cy );
                    next(re(z)) = re(z)*re(z)-im(z)*im(z)+cx;
                    next(im(z)) = 2*re(z)*im(z)+cy;
                    next(i) = i + 1;
                    pause;
                } while (i<maxIterations);
                // max iterations reached -> assume convergence
                image[x][y] = true;
            } when( re(z)*re(z) + im(z)*im(z) > 4.0 );
        }
    }
}
drivenby {
    for(i=0..maxIterations)
        pause;
}