-- Fractal 01 : Based on a quadratic time escape fractal algorithm found in the book Keys to Infinity by Clifford Pickover.
-- Revision 5

--@TBCONFIG SLIDER: Seed1, 0
--@TBCONFIG SLIDER: Seed2, 0
--@TBCONFIG SLIDER: Iterations, 25
--@TBCONFIG SLIDER: Saturation, 50
--@TBCONFIG SLIDER: Low Lum Filter, 20
--@TBCONFIG FLAG: Fill Black First, true
--@TBCONFIG FLAG: Random Color, true
--@TBCONFIG FLAG: Use Random Seeds, true
--@TBCONFIG FLAG: Low Quality Preview, true
--@TBCONFIG FLAG: Zoomed (much slower), false
--@TBCONFIG STYLE: Stylized, 2, None, Warp, Neon Web, Spiral World, Spiral Web, Landscape, Embossed, Outlined, Metallic, Foamy
--@TBCONFIG INFO: Fractal 01
--@TBCONFIG INFO: Revision 4
--@TBCONFIG INFO:  
--@TBCONFIG INFO: Quadratic Time Escape Fractal Exploration based on an algorithm by Clifford Pickover from the book Keys to Infinity. 
--@TBCONFIG INFO:  
--@TBCONFIG INFO: This filter is extremely slow due to the processing required. 
--@TBCONFIG INFO: 
--@TBCONFIG INFO: Press and hold the ESC key to exit the script early
--@TBCONFIG INFO:
--@TBCONFIG INFO: The Seed1 and Seed2 sliders allow for selecting 1 million starting combination.
--@TBCONFIG INFO:
--@TBCONFIG INFO: The Iterations slider controls the number of overlapping fractals generated.
--@TBCONFIG INFO:
--@TBCONFIG INFO: The Saturation slider controls the color richness during the fractal rendering.
--@TBCONFIG INFO:
--@TBCONFIG INFO: Use the Low Lum Filter to keep dim outer areas from rendering. This allows for overall better contrast.
--@TBCONFIG INFO:
--@TBCONFIG INFO: The Stylized options give choices for post processing of the render fractals.
--@TBCONFIG INFO:
--@TBCONFIG INFO: Check the Fill Black First box to paint the canvas black overwise your current image data will be shown.
--@TBCONFIG INFO:
--@TBCONFIG INFO: If the Random Color box is checked each fractal will have a random color otherwise your currently selected color will be used.
--@TBCONFIG INFO:
--@TBCONFIG INFO: Check the Random Seeds box to enabled the 3 Seed sliders. This allows for repeatable fractal patterns otherwise the fractals will be completely random and non-repeatable.
--@TBCONFIG INFO:
--@TBCONFIG INFO: The Low Quality Preview check box allows for a faster preview of the current settings. Use this when exploring different settings.
--@TBCONFIG INFO:
--@TBCONFIG INFO: The Zoomed check box renders the fractal closer. This option generally takes much more time.
--@TBCONFIG INFO:
--@TBCONFIG INFO: While this filter is slow there are a number of things you can do to work with this. When exploring settings work on a very small page size, for example 250x250. When trying different Seed settings set the Stylized option to None and check the Low Quality Preview box. With these settings you should be able to work with the Preview button checked. When you find a combination that looks good uncheck the Low Quality Preview and select a Stylized option if you like. When satisfied push the Apply/Exit button. Now the trick is to go to a new larger page and select the menu Filter > Repeat Last Filter. Your little 250x250 fractal art will now be rendered at any page size you like for example 1000x1000 or larger sizes for prints for example 3000x3000. Remember the larger the page the more time it will take to render.

-- Changed zoomed to true will result in a zoom in render
if flagVal5 == true then
  zoomed = true
else
  zoomed = false
end

a = {}
e = 0
x = 0
y = 0
rr, rg, rb = 0

if flagVal3 == true then
  math.randomseed((1000 * sliderVal1) + ((1000 * sliderVal2) * 1000))
end

-- Fill to black
if flagVal1 == true then
  for ix = 0, width - 1 do
    for iy = 0, height - 1 do
      set_rgba(ix, iy, 0, 0, 0, 1.0)
    end
  end
end
flush()

for i1 = 0, 20 * sliderVal3 do

  -- Initialize	
  e = 0
  x = 0
  y = 0
  for i1 = 1, 12 do
    a[i1] = (math.random(0, 25) - 12) / 10.0	
  end

  -- Generate a random color
  if flagVal2 == true then
    rr = math.random(0, 255) / 255.0
    rg = math.random(0, 255) / 255.0
    rb = math.random(0, 255) / 255.0
  else
    rr, rg, rb = get_color()
  end

  if flagVal4 == true then
    stepx = 10
    stepy = 10
  else
    stepx = 1
    stepy = 1
  end

  -- Render the fractal
  local tempx
  for ix = 0, width - 1, stepx do
    -- If the Escape key is pressed exit the loop
    if (is_escape() > 0) then
      return
    end

    for iy = 0, height - 1, stepy do
      local r, g, b, alpha  = get_rgba(ix, iy)
      local scaleFactor = 10
      local scaleFactor2 = scaleFactor / 2			
      if zoomed == false then
        scaleFactor = 10
        scaleFactor2 = 5
      else
        scaleFactor = 2
        scaleFactor2 = 1
      end	

      x = -scaleFactor2 + ix / (width / scaleFactor)
      y = scaleFactor2 - iy / (height / scaleFactor)

      e = 0
      while (e < 200 and x * x + y * y < 100000) do
        tempx = a[1] + x * (a[2] + a[3] * x + a[4] * y) + y * (a[5] + a[6] * y)
        y = a[7] + x * (a[8] + a[9] * x + a[10] * y) + y * (a[11] + a[12] * y)
        x = tempx
        e = e + 1
      end
      local v = ((e * (sliderVal4 * 20)) % 255) / 255.0

      if v < sliderVal5 then 
        v = 0
      end

      if alpha == 0 then
        r = rr
        g = rg
        b = rb
        alpha = v
      else
        r = r + (v * rr)
        g = g + (v * rg)
        b = b + (v * rb)
        alpha = alpha + v
      end

      if flagVal4 == true then
        for ix2 = ix, ix + stepx - 1 do
          for iy2 = iy, iy + stepy - 1 do
            set_rgba(ix2, iy2, r, g, b, alpha)
          end
        end
      else 
        set_rgba(ix, iy, r, g, b, alpha)
      end 
	  end
  end
  flush()
end

-- Post process stylizing
if styleVal1 == 1 then
  -- nothing to do

elseif styleVal1 == 2 then
  -- Warp
  paint_open(0)
  paint_filter("Zoom Blur 2",0,700,500,500,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_close()

elseif styleVal1 == 3 then
  -- Neon Web
  paint_open(0)
  paint_filter("Zoom Blur",0,800,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_filter("Edge",0,150,10,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_filter("Anti Alias",0,500,500,1000,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
--  paint_filter("Outliner 2",0,200,600,400,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_close()

elseif styleVal1 == 4 then
  -- Spiral World
  paint_open(0)
  paint_filter("Zoom Blur 2",0,700,500,500,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_filter("Twirl",0,400,10,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_close()

elseif styleVal1 == 5 then
  -- Spiral Web
  paint_open(0)
  paint_filter("Twirl",0,300,10,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_filter("Zoom Blur",0,800,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_filter("Edge",0,150,10,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_filter("Anti Alias",0,500,500,1000,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_close()

elseif styleVal1 == 6 then
  -- Landscape
  paint_open(0)
  paint_filter("Gaussian Blur",0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_filter("Voxel",0,70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_filter("Emboss",0,850,250,430,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_close()

elseif styleVal1 == 7 then
  -- Emboss
  paint_open(0)
  paint_filter("Anti Alias",0,500,500,1000,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_filter("Edge",0,150,10,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_filter("Emboss",0,850,250,430,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_filter("Anti Alias",0,500,500,1000,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_close()

elseif styleVal1 == 8 then
  -- Outlined
  paint_open(0)
  paint_filter("Outliner 2",0,250,600,500,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_filter("Anti Alias",0,500,500,1000,1000,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_close()

elseif styleVal1 == 9 then
  -- Metallic
  paint_open(0)
  paint_filter("Gaussian Blur",0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_filter("Emboss2",0,100,300,400,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  stretchX = (8 / width) * 1000
  stretchY = (8 / height) * 1000
  paint_filter("Stretch",0,500 + stretchX,500 + stretchY,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_close()

elseif styleVal1 == 10 then
  -- Foamy
  paint_open(0)
  paint_filter("Gaussian Blur",0,90,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_filter("Emboss2",0,100,300,400,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_filter("Voxel",0,250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  stretchX = (24 / width) * 1000
  stretchY = (24 / height) * 1000
  paint_filter("Stretch",0,500 + stretchX,500 + stretchY,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  paint_close()

end





