import random

def livingColor(picture):
  for pxl in getPixels(picture):
        r= getRed(pxl)  
        g=getGreen(pxl)  
        b = getBlue(pxl) 
        avg=(r+g+b)/3 
        R=r+(r-avg)*.5
        G=g+(g-avg)*.5
        B=b+(b-avg)*.5                
        R=check(R)
        G=check(G)
        B=check(B)   
        newColor = makeColor(R,G,B)
        setColor(pxl,newColor)


def getDistance(px1,px2):
  r1=getRed(px1) 
  g1=getGreen(px1)
  b1=getBlue(px1)
  r2=getRed(px2)
  g2=getGreen(px2)
  b2=getBlue(px2)
  return pow((r1-r2),2)+pow((g1-g2),2)+pow((b1-b2),2)

def getGrayDistance(px1,px2):
  r1=getRed(px1)
  g1=getGreen(px1)
  b1=getBlue(px1)
  r2=getRed(px2)
  g2=getGreen(px2)
  b2=getBlue(px2)
  dst=r1+g1+b1-r1-g2-b2
  if (dst<0):
    dst=dst*-1
  return dst


def darken(pxl,fctr): 
  setRed(pxl,int(getRed(pxl)*fctr)  )  
  setGreen(pxl,int(getGreen(pxl)*fctr))
  setBlue(pxl,int(getBlue(pxl)*fctr))  

def check(clr):
    if(clr>255):
      clr=255
    if(clr<0):
      clr=0  
    return int(clr)
 

def coloringBook(picture): 
  w=getWidth(picture)   
  h=getHeight(picture)
  limit=30
  for x in range(1,w-1):
    for y in range(1,h-1):
      pixel0=getPixel(picture,x,y)
      pixel1=getPixel(picture,x+1,y)
      pixel2=getPixel(picture,x+1,y+1)
      pixel3=getPixel(picture,x,y+1) 
      d1=getGrayDistance(pixel0,pixel1)
      d2=getGrayDistance(pixel0,pixel2)
      d3=getGrayDistance(pixel0,pixel3)
      if(d1>limit)or(d2>limit)or(d3>limit):
        setColor(pixel0, black)
      else:
        setColor(pixel0, white)

 
def wave(picture):
  ripple=requestInteger("0 for Wave, 1 for Ripple")
#               0=wave effect
#               1=ripple effect
  wave2(picture,ripple)
 
def wave2(picture,ripple):
  m=0.0
  pxl=getPixels(picture)
  w=getWidth(picture)
  h=getHeight(picture)
  for y in range(1,(96*h)/100):
    if(ripple==0):
      m=0.0
    for x in range(1,w):
      m=m+.6282/w  
      a=int(h*(sin(m)+1.0)/50.0)
      nuColor=getColor(getPixel(picture,x,y+a))
      setColor(getPixel(picture,x,y),nuColor)


def chromakey(bg): 
  bgH=getHeight(bg)
  bgW=getWidth(bg)
  greenPic=makePicture(pickAFile())
  h=getHeight(greenPic)
  w=getWidth(greenPic)
  xOff=bgW/2-w/2 +requestInteger("X offset   0=center")
  yOff=bgH/2-h/2 +requestInteger("Y Offset   0=center")  
  limit=4.0
  for p in getPixels(greenPic): 
    r =getRed( p )
    g =getGreen( p )+.1 # Avoid Division by Zero
    b =getBlue( p )
    sqrg=sqrt(g)
    dr=(g-r)/sqrg
    db=(g-b)/sqrg
    if(dr <limit or db<limit ) :
      x=getX(p)
      y=getY(p)
      if (y+yOff<bgH)and(x+xOff<bgW)and(y+yOff>0)and(x+xOff>0):
        nuColor=getColor(p)
        bgPixel=getPixel(bg,x+xOff,y+yOff)
        setColor(bgPixel,nuColor)

def rainbow(picture):
  h=getHeight(picture)
  w=getWidth(picture) 
  m=0.3 
  for y in range(1,h):
    repaint(picture) 
    m=m+6.3/h
    a=sin(m)+0.65
    b=sin(m+2.09)+0.65
    c=sin(m+4.18)+0.65
    if(a>1.0):
      a=1.0
    if(b>1.0):
      b=1.0
    if(c>1.0):
      c=1.0
    if(a<0):
      a=0    
    if(b<0):
      b=0    
    if(c<0):
      c=0
    for x in range(1,w): 
      px=getPixel(picture,x,y)  
      r1=getRed(px)
      g1=getGreen(px)
      b1=getBlue(px)
      bright=((r1 + g1 + b1)/3)
      nuColor=makeColor(int(bright*a) ,int(bright*b),int(bright*c))
      setColor(px,nuColor)

def circles(picture):
  h=getHeight(picture)
  w=getWidth(picture)
  size=w
  if(size>h):
    size=h
  size=(size*9)/20
  cX = w/2
  cY = h/2
  g=1
# Get the color data
  colorData=[] 
  for k in range (1,size):
    for m in range(0,628):
      n=m/100.0 
      a=int(k*sin(n))
      b=int(k*cos(n))
      colorData.append( getColor(getPixel(picture,cX+a,cY+b)))
      g=g+1
# call four versions of makeCircle
  size=(size*5)/10  
  dist=(size*5)/4
  makeCircle(picture,colorData,cX+dist,cY+dist,size)
  makeCircle(picture,colorData,cX-dist,cY+dist,size)
  makeCircle(picture,colorData,cX+dist,cY-dist,size)
  makeCircle(picture,colorData,cX-dist,cY-dist,size)
      

def makeCircle(picture,data,x,y,size): 
  g=1
  max=len(data)/628
  for k in range (1,max):
    for m in range(0,628):
      n=m/100.0
      a=int(k*size*sin(n)/(2.0*max))
      b=int(k*size*cos(n)/(2.0*max))
      setColor(getPixel(picture,x+a,y+b),data[g])
      g=g+1
  repaint(picture)
# call four versions of makeCircle
  size=(size*1)/2
  if(size>20):
# call four versions of makeCircle
    dist=(size*4)/4
    makeCircle(picture,data,x+dist,y+dist,size)
    makeCircle(picture,data,x-dist,y+dist,size)
    makeCircle(picture,data,x+dist,y-dist,size)
    makeCircle(picture,data,x-dist,y-dist,size)
      
def lake(picture):
  pixel=getPixels(picture)
  H=getHeight(picture)
  W=getWidth(picture)
  h=H/3
  tempPic=makeEmptyPicture(W,h)
  tempPxl=getPixels(tempPic)
  for x in range(1,W):
    for y in range (1,h+1):
      nuColor=getColor(pixel[x+2*y*W])
      setColor(tempPxl[x+(h-y)*W],nuColor)
  wave2(tempPic,1)  
  pos=h*2*W
  for z in tempPxl :
    setColor(pixel[pos], getColor(z))  
    pos=pos+1

def checkers(picture):
  H=getHeight(picture)
  W=getWidth(picture)
  px=getPixels(picture)
  for k in px:
   setColor(k,makeDarker(getColor(k))) 
  h=H/8
  w=(W/8) 
  for q in range(0,8):
    for z in range(0,8,2):
      for y in range(0,h-1):
        for x in range(0,w):
          p=px[x+z*w+y*W+(h*W+w)*q]
          setColor(p,makeLighter(getColor(p)))    
          setColor(p,makeLighter(getColor(p)))    

def cartoon(picture):
  color=[]
  for a in range(0,255,64):
    for b in range(0,255,64):
      for c in range(0,255,64):  
        color.append(makeColor(a,b,c))
  px=getPixels(picture)
  for v in range(0,len(px)): 
    choice=0
    dist=90000
    pxColor=getColor(px[v]) 
    for w in range (0,len(color)):
       d=distance(pxColor,color[w])
       if (d<dist):
          dist=d
          choice=w 
    setColor(px[v],color[choice])


def vacuum(picture):
  H=getHeight(picture)
  h=H/2
  W=getWidth(picture)
  m=1.571
  for x in range(1,W): 
   n=4.712
   m=m+3.8/W
   for y in range(h-1,1,-1):     
      adj=(1.0+sin(m))*(1.0+sin(n))*0.5
    #  printNow(adj)
      n=n+1.51/h
      Y1=int(y-adj*H) 
      Y2=int(2*h-y+adj*h)
      if(Y1>0):
        nuColor1=getColor(getPixel(picture,x,Y1))
        setColor(getPixel(picture,x,y),nuColor1)
        nuColor2=getColor(getPixel(picture,x,Y2))
        setColor(getPixel(picture,x,2*h-y),nuColor2)

      else:
         setColor(getPixel(picture,x,y),black)
         setColor(getPixel(picture,x,2*h-y),black)

def melt(picture):
  H=getHeight(picture)
  W=getWidth(picture)
  m=H/3
  movement=0.0
  for x in range(1,W): 
   n=0
   randy = (random.random()-0.5)*3
   movement=int(movement+randy)
   m=m+movement
   if(m<0):
     m=0
   for y in range(H,1,-1):     
      adj=sin(n)
      adj=adj*adj
      n=n+1.5/H
      Y=int(y-m*adj) 
      if(Y>0)and (Y<H):
        nuColor1=getColor(getPixel(picture,x,Y))
        setColor(getPixel(picture,x,y),nuColor1) 
      else:
         setColor(getPixel(picture,x,y),black) 

def watermark(picture):
  H=getHeight(picture)
  W=getWidth(picture)
  cX=W/2
  cY=H/2
  wtrmk=makePicture(pickAFile())
  h=getHeight(wtrmk)
  w=getWidth(wtrmk)  
  intensity=-1
  while(intensity>100)or(intensity<0):
    intensity=requestInteger("Watermark intensity? 0 - 100%")
  intensity=intensity/100.0
  for x in range(1,w):
    for y in range(1,h):
      p=getPixel(wtrmk,x,y)   
      brightness=(getRed(p)+ getGreen(p)+ getBlue(p))/765.0
      if (cX-w/2+x>0)and(cX-w/2+x<W)and(cY-h/2+y>0)and(cY-h/2+y<H):
        pxl=getPixel(picture,cX-w/2+x,cY-h/2+y)
        brightness=1.0-intensity+intensity*brightness
        darken(pxl,brightness)

def orb(picture): 
 m=0.0
 h=getHeight(picture)
 w=getWidth(picture)
 cX=w/2
 cY=h/2
# pxl=getPixels(picture):
 r=h
 if (w<h):
  r=w 
 amount=0.15
 r=r/4
 xoff=requestNumber("X offset (0=center)")
 yoff=requestNumber("Y offset (0=center)")
 for span in range (1,r):
  amount=amount*0.98
  for z in range(6283): 
     m=z/1000.0
     x= int(sin(m)*(span) )
     y= int(cos(m)*(span)) 
     X=int(cX+x+xoff)
     Y=int(cY+y+yoff)
     if(X>1 and X<w and Y>1 and Y<h):
      px=getPixel(picture,X,Y)
      r=getRed(px)
      g=getGreen(px)
      b=getBlue(px)
      r=r*(1.0-amount)+255*amount
      g=g*(1.0-amount)+255*amount
      b=b*(1.0-amount)+255*amount
      clr=makeColor(r,g,b)
      setColor(px,clr)

def halo(picture):  
  glowColor=pickAColor()
  testPx=getPixel(picture,1,1)
  tmp=getColor(testPx)
  setColor(testPx,glowColor)
  R=getRed(testPx)
  G=getGreen(testPx)
  B=getBlue(testPx)
  setColor(testPx,tmp)
  w=getWidth(picture)   
  h=getHeight(picture)  
#  Edge detection & replace with glow color
  for x in range(1,w-1):
    for y in range(1,h-1): 
      pixel0=getPixel(picture,x,y)
      pixel1=getPixel(picture,x+1,y)
      pixel2=getPixel(picture,x+1,y+1)
      pixel3=getPixel(picture,x,y+1)  
      d1=getDistance(pixel0,pixel1)
      d2=getDistance(pixel0,pixel2)
      d3=getDistance(pixel0,pixel3)
      if (d1>11000)or(d2>11000)or(d3>11000):
        setColor(pixel0,glowColor)
# Now glow around glow pixels in circles
  for x in range(10,w-10):
    for y in range(10,h-10): 
      pxl=getPixel(picture,x,y)
      pxlClr=getColor(pxl) 
      if(pxlClr==glowColor):
       for size in range(1,w/30):
        for m in range(0,63):
         n=m/10.0
         a=int(size*sin(n) )
         b=int(size*cos(n) )
         if(x+a>w-1 or x+a<1 or y+b>h-1 or y+b<1):
          continue
         currentPxl=getPixel(picture,x+a,y+b)
         r=getRed(currentPxl)
         g=getGreen(currentPxl)
         b=getBlue(currentPxl)
         if(R>r):
          r=r+1
         if(G>g):
          g=g+1
         if(B>b):
          b=b+1 
         r=check(r)
         g=check(g)
         b=check(b)
         nuColor=makeColor(r,g,b) 
         setColor(currentPxl,nuColor)

def chromaClean(picture): 
  limit=4 
  for p in getPixels(picture): 
    r =getRed( p )
    g =getGreen( p )+1
    b =getBlue( p )
    sqrg=sqrt(g)
    dr=(g-r)/sqrg
    db=(g-b)/sqrg
    if(dr >limit and db>limit ) :
        setColor(p,green)

def mirror(picture):
  pixel=getPixels(picture)
  H=getHeight(picture)
  W=getWidth(picture)
  for x in range(1,W/2):
    for y in range (1,H):
      nuColor=getColor(pixel[x+y*W])  
      setColor(pixel[W-x+y*W], nuColor)  
    

def collage(bg): 
  bgH=getHeight(bg)
  bgW=getWidth(bg)
  newPic=makePicture(pickAFile())
  h=getHeight(newPic)
  w=getWidth(newPic)
  xOff=bgW/2-w/2 +requestInteger("X offset 0=center")
  yOff=bgH/2-h/2 +requestInteger("Y Offset 0=center")  
  for p in getPixels(newPic):   
      x=getX(p)
      y=getY(p)
      if (y+yOff<bgH)and(x+xOff<bgW)and(y+yOff>0)and(x+xOff>0):
        nuColor=getColor(p)
        bgPixel=getPixel(bg,x+xOff,y+yOff)
        setColor(bgPixel,nuColor)


#__MAIN___
pic=makePicture(pickAFile())
show(pic)
filter=99
while(filter>16)or (filter<0):
  random.random()
  filter=requestNumber("0-Coloring Book 1-Wave 2-Chromakey\n 3-Rainbow 4-Circles 5-Lake 6-Checkers\n7-Cartoon 8-Vacuum 9-Melt 10-Watermark \n11-Orb 12-Halo 13-ChromaClean \n14=Living Color 15-Mirror 16-Collage")
  if(filter==0):
    coloringBook(pic)
  elif(filter==1):
    wave(pic)
  elif(filter==2):
    chromakey(pic)
  elif(filter==3):
    rainbow(pic)
  elif(filter==4):
    circles(pic)
  elif(filter==5):
    lake(pic)
  elif(filter==6):
    checkers(pic)
  elif(filter==7):
    cartoon(pic)
  elif(filter==8):
    vacuum(pic)
  elif(filter==9):
    melt(pic)
  elif(filter==10):
    watermark(pic)
  elif(filter==11):
    orb(pic)
  elif(filter==12):
    halo(pic)
  elif(filter==13):
    chromaClean(pic)
  elif(filter==14):
     livingColor(pic)
  elif(filter==15):
    mirror(pic)
  elif(filter==16):
    collage(pic)
repaint(pic)
path=requestString("Save as")
if(path!=''):
  path=pickAFolder() + '\\' + path + ".jpg"
  printNow(path)
  writePictureTo(pic,path)

