  #!/usr/bin/env python

#***********************************************
#Load required software
import pygame,sys,random
import pygame.gfxdraw
import math
import time
from pygame.locals import *
pygame.init()


#************************************************
# Definitions
PI = math.pi 
rb1 = 600
scale = 0.4 #Reduce size to fit window
#*************************************************
#Determine colours
col=0
red=(240,0,0); green=(0,240,0); blue=(0,0,240);black=(0,0,0)
lred=(240,100,0); lgreen=(100,0,0); lblue=(0,100,240)
cyan=(0,250,0); yellow=(0,250,0); magenta=(250,100,0);white=(250,250,250)        
colr=[white,red,green,blue,lred,lgreen,lblue,yellow,cyan,magenta]

#**********************************************
#Distance of graphics screen from LHS of screen
x = 800 #Distance of graphics screen from top of screen
y = 50
#Set up graphics screen
import os
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (x,y)
#*************************************************
#Size of grahics screen
#screen = pygame.display.set_mode((100,100))
x = 800 ; y = 600
xc = int(x/2); yc = int(y/2)
pygame.display.set_caption("Roulette")
window = pygame.display.set_mode((x,y), 0 ,32)
#************************************************

def my_range(start, end, step) :
    while start  <= end:
        yield start
        start += step

def gcd(A, B): # Greatest  common divisor of the two radii
    while B :
        C = A
        A = B
        B = C % B
        P = abs(A)
    return P


def  bigcircle():
    pygame.gfxdraw.circle(window,xc,yc,rb,black)

def  smallcircle():
    xn = int(xc+(rb-rs)*math.cos(theta)) ; yn = int(yc+(rb-rs)*math.sin(theta))
    pygame.gfxdraw.circle(window,xn,yn,rs,black)

def erasecircle(): # Erase circle after a delay - drawn in background colour
    for i in range(1,1000):
        xn = int(xc+(rb-rs)*math.cos(theta)) ; yn = int(yc+(rb-rs)*math.sin(theta))
        pygame.gfxdraw.circle(window,xn,yn,rs,white)

def roulette(): # Draw the lot for the necessary number of cycles
    for theta in my_range(0, cycles*2*PI , 0.001):
        X1=int(xc+m*rs*math.cos(theta)+rs*math.cos(m*theta))
        Y1=int(yc+m*rs*math.sin(theta)-rs*math.sin(m*theta))
        pygame.gfxdraw.pixel(window,X1,Y1,black)
    
#----------------------------------------------
print()
print()
        
rs1 = input( " input small circle diameter - Large is 600  ")
rs1 = float(rs1)

# Q = FN_LCM(rb,rs)
P = gcd(rb1, rs1)
cusps = int(rb1/P) 
cycles = int(rs1/P)
delay = 3000

#fnm = str(input("Enter File name to save image - MUST BE IN QUOTES \n Can be .bmp, .png. .jpg, .tga "))
#fnm = (input("Enter File name to save image" )

#Image is saved with filename "Pic" + small circle radius + .png. eg Pic300.png
fnm = "Pic" + str(int(rs1)) + "_" + str(cusps) + ".png"
print ()

#print()
print ("The image is saved as ", fnm) ;print()
print ("The image is saved on QUIT X ") ;print()
print (" The main display completes just one revolution to save time")

print(" The roulette rotates the appropriate number of times") ;print()


#rb = xc.0 #600
m = float(rb1/rs1 -1)
rs = int(rs1*scale)
rb = int(rb1*scale)
#print ("m   =  ",m)

print("Rbig = ",rb1, "Rsmall = ", rs1); print()
print ("GCD ",P)
print ("cusps  ",cusps)
print ("cycles  ",cycles)
    
''' Main Program  '''
    
'''The code below quits the program if the X button is pressed'''
for i in range(1):

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            # most reliable exit on x click
            print ("File is saved as  ", fnm)
            pygame.quit()
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            # optional exit with escape key
            if event.key == pygame.K_ESCAPE:
                pygame.quit()
                sys.exit()


    window.fill(white)
    bigcircle()
    pygame.display.flip()

  #  START ROLLING*********************************************
    for theta in my_range(0, 2*PI , 0.015 ):

        smallcircle()
        pygame.display.flip()

        erasecircle()  #  Erase it after a delay

#  REINFORCE BIG CIRCLE FOR EACH theta step        
        bigcircle()
#  FOLLOW THE INITIAL DIAMETER
#  CALCULATE ENDS OF DIAMETER

        X1=int(xc+m*rs*math.cos(theta)+rs*math.cos(m*theta))
        Y1=int(yc+m*rs*math.sin(theta)-rs*math.sin(m*theta))
        pygame.gfxdraw.pixel(window,X1,Y1,black)
        pygame.display.flip()
    
#  THE DIAMETER SWEEPS OUT A HYPOCYCLOID
#   X2=1xc+m*rs*math.math.cos(theta) + rs*math.math.cos(PI-m*theta)
        X2=int(xc+m*rs*math.cos(theta) + rs*math.cos(PI-m*theta))
        Y2=int(yc+m*rs*math.sin(theta) + rs*math.sin(PI-m*theta))      
        
        pygame.gfxdraw.line(window,X1,Y1,X2,Y2,red)
        pygame.gfxdraw.pixel(window,X1,Y1,black)
        
        pygame.display.flip()

#  Erase it after a delay
        for i in range(delay):
            pygame.gfxdraw.line(window,X1,Y1,X2,Y2,white)
           
        pygame.gfxdraw.pixel(window,X1,Y1,black)
#        pygame.gfxdraw.circle(window,xc,yc,rb,white )

#  Redraw roulette

roulette()
pygame.display.flip()


while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.image.save(window, fnm)
            print("file ",fnm, "has been saved")
            # most reliable exit on x click
            pygame.quit()                          
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            # optional exit with escape key
            if event.key == pygame.K_ESCAPE:
                pygame.image.save(window, fnm)
                print("file ",fnm, "has been saved")
                pygame.quit()
                sys.exit()
key1 = input("press key to quit   ")

pygame.quit()
sys.exit()
