from bmp import *

last = [169,252,252,252]

def main(n=0, m = 25):
    zoom = 0.00000005 * (2**n)
    while zoom < 2 and n <= m:
        name = str(n) + ".bmp"
        msetColor(2000, [-.743647477037151 - zoom, -.743647477037151+ zoom, -0.131830275205330 - zoom, -0.131830275205330 + zoom], name)
        zoom = zoom * 4
        n+=1

def inMSet( c, n ):
    '''that takes as input a complex number c and an integer n. Your function
    will return a boolean: True if the complex number c is in the Mandelbrot
    set and False otherwise.'''
    z = 0
    while n > 0:
        z = z**2 + c
        if abs(z) >= 2: return False
        n-=1
    return True
    
def testImage():
    """ a function to demonstrate how
        to create and save a bitmap image
    """
    width = 200
    height = 200
    image = BitMap( width, height )

    # create a loop in order to draw some pixels
    
    for col in range(width):
        if col % 10 == 0: print 'col is', col
        for row in range(height):
            if col % 10 == 0 or row % 10 == 0:
                image.plotPoint( col, row )

    # we have now looped through every image pixel
    # next, we write it out to a file

    image.saveFile( "test.bmp" )

# Using OR instead of AND results in a grid instead of dots
    
def scale(pix, pixNum, floatMin, floatMax):
    '''takes in four things: pix, an integer representing a pixel column, pixNum,
    the total number of pixel columns available, floatMin, the floating-point
    lower endpoint of the image's real axis (x-axis), and floatMax, the floating
    -point upper endpoint of the image's real axis (x-axis)'''
    return float(pix)/pixNum * (floatMax - floatMin) + floatMin

def mset(width, coordinateList):
    """ computes the set of points in the Mandelbrot set on the complex plane
    and creates a bitmap of them. For the moment, we will use images of width
    width and height height and we will limit the part of the plane to the
    ranges -2.0 x or real coordinate +1.0  """

    height = width*(coordinateList[3]-coordinateList[2])/(coordinateList[1]-coordinateList[0])
    image = BitMap( width, height )
    numIterations = 45  #after this many tries, we assume z in in the MSet

    # create a loop in order to draw some pixels
    
    for col in range(width):
        for row in range(height):
            x = scale(col, width, coordinateList[0],coordinateList[1])
            y = scale(row, height, coordinateList[2],coordinateList[3])
            if inMSet(x + y*1j, numIterations): image.plotPoint( col, row )

    # we have now looped through every image pixel
    # next, we write it out to a file

    image.saveFile( "mset.bmp" )

    # numIterations describes the detail of the image.  When it's high, the image
    # is very detailed

def msetColor(width, coordinateList, name):
    """ computes the set of points in the Mandelbrot set on the complex plane
    and creates a bitmap of them. For the moment, we will use images of width
    width and height height and we will limit the part of the plane to the
    ranges -2.0 ≤ x or real coordinate ≤ +1.0  """

    height = int(width*(coordinateList[3]-coordinateList[2])/(coordinateList[1]-coordinateList[0]))
    image = BitMap( width, height )
    numIterations = 196  #after this many tries, we assume z in in the MSet
    
    for col in range(width): # create a loop in order to draw some pixels
        for row in range(height):
            colorList = [0,0,0]
            y = scale(row, height, coordinateList[2],coordinateList[3])
            x = scale(col, width, coordinateList[0],coordinateList[1] )
            drawPic(x,y,col,row,colorList,image,numIterations)
        if width % 10 ==0: print str((float(100) * col / width)) + " of picture " + name + " of 12"# Prints progress for those long files where you wonder whether or not it's working...
    image.saveFile(name)

        
def drawPic(x,y,col,row,colorList,image,iterations, doLast = True):
    ''' Helper function to draw each pixel using recursion relative to how
    close it is to being in the Mandelbrot set'''
    if doLast and inMSet(x + y*1j, last[0]) and not inMSet(x + y*1j, last[0]+1):
        #print "REPEAT"
        mycolor = Color(last[1],last[2],last[3])
        image.setPenColor(mycolor)
        image.plotPoint( col, row )
    else:
        if iterations == 0: return
        mycolor = Color(colorList[0],colorList[1],colorList[2])
        image.setPenColor(mycolor)
        if inMSet(x + y*1j, iterations):
            image.plotPoint( col, row )
            last[0] = iterations
            last[1] = colorList[0]
            last[2] = colorList[1]
            last[3] = colorList[2]
            #print last
        else: drawPic(x,y,col,row,changeColor(colorList),image,iterations-1, False)
    

def changeColor(colorList):
    if colorList[0] < 252 and colorList[1] == 0 and colorList[2] == 0:
        colorList[0]+=9
    elif colorList[0] == 252 and colorList[1] <252 and colorList[2] == 0:
        colorList[1]+=9
    elif colorList[0] > 0 and colorList[1] == 252 and colorList[2] == 0:
        colorList[0] -=9
    elif colorList[0] == 0 and colorList[1] == 252 and colorList[2] < 252:
        colorList[2] +=9
    elif colorList[0] == 0 and colorList[1] > 0 and colorList[2] == 252:
        colorList[1] -=9
    elif colorList[0] < 252 and colorList[1] == 0 and colorList[2] == 252:
        colorList[0]+=9
    elif colorList[0] == 252 and colorList[1] == 0 and colorList[2] > 0:
        colorList[2]-=9
    return colorList
    
