import sys
import time
import os
import Image # http://www.pythonware.com/products/pil/
import datetime
from colorama import init, Fore, Back, Style
init()

# Import the platform specific mouse libraries
if os.name == "nt":
        import win32api # http://sourceforge.net/projects/pywin32/files/pywin32/Build%20219/
        import win32con
        from PIL import ImageGrab

elif os.name == "posix":
        from Quartz.CoreGraphics import CGEventCreateMouseEvent
        from Quartz.CoreGraphics import CGEventPost
        from Quartz.CoreGraphics import kCGEventMouseMoved
        from Quartz.CoreGraphics import kCGEventLeftMouseDown
        from Quartz.CoreGraphics import kCGEventLeftMouseUp
        from Quartz.CoreGraphics import kCGMouseButtonLeft
        from Quartz.CoreGraphics import kCGHIDEventTap

else:
        print "Unknown OS",os.name
        exit()

def mouseclick(posx,posy):

        if os.name == "nt":
                win32api.SetCursorPos((posx,posy))
                win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,posx,posy,0,0)
                win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,posx,posy,0,0)

        elif os.name == "posix":
                CGEventPost(kCGHIDEventTap, CGEventCreateMouseEvent(None, kCGEventLeftMouseDown, (posx,posy), kCGMouseButtonLeft))
                CGEventPost(kCGHIDEventTap, CGEventCreateMouseEvent(None, kCGEventLeftMouseUp, (posx,posy), kCGMouseButtonLeft))
        
        else:
                print "Unknown OS",os.name
                exit()

def openLogFile(pathToLogs,extension):

        if os.name == "nt":
                lfile = open(pathToLogs+'/spins-'+str(time.time())+'.'+extension, 'w')
       
        elif os.name == "posix":
                lfile = open('/Users/lee/Desktop/spinlogs/spins-'+str(time.time())+'.'+extension, 'w')
       
        else:
                print "Unknown OS when opening log file",os.name
                exit()

        return lfile

def checkColour(pixelX,pixelY):

        if os.name == "nt":
                image = ImageGrab.grab()

        elif os.name == "posix":
                os.popen('screencapture -x -o /Users/lee/Desktop/latest.png > /dev/null 2>&1')
                image = Image.open('/Users/lee/Desktop/latest.png');
                os.popen('rm /Users/lee/Desktop/latest.png')        
        else:
                print "Unknown OS when checking colour",os.name
                exit()

        colour = image.getpixel((pixelX,pixelY))
        return colour

def snapColour(pixelX,pixelY):

        if os.name == "nt":
                image = ImageGrab.grab((pixelX-30,pixelY-60,pixelX+30,pixelY+60))
                image.save(newPath+"/"+str(totalSpins)+".jpg")      
        else:
                print "Can only save image on Windows - running",os.name

# class Game:
#         def __init__(   self,
#                         url,
#                         loadingTimeSecs,
#                         spinX,
#                         spinY,
#                         betX,
#                         betY,
#                         clearX,
#                         clearY,
#                         lastNumberX,
#                         lastNumberY,
#                         closeDialogueX,
#                         closeDialogueY):

# Tweakable variables
delay           = 0.75           # Click delay, 0.5 works well in testing mode
startingBalance = 200           # Session starting balance

startingBetSize = 1             # Initial bet
trigger         = 6             # Number of absences before starting to bet
window          = 8             # Number of bets to try (financial liability = startingBetSize^window)
gameLength      = 5           # Bail trigger two: game length
profitBail      = 50            # Bail trigger one: profit size
sessionsToPlay  = 10           # How many sessions we should play before calling it a day

# About the container
refreshX        = 310
refreshY        = 85
    
# About the game http://cache.download.banner.ladbrokes.com/flash/14/casino_Ladbrokes_Vegas/launchcasino.html?connection=casino&game=ro&nolobby=1&preferedmode=real&language=en&#ro
loadingTimeSecs = 2
spinX           = 164
spinY           = 948
clearX          = 125
clearY          = 325
lastNumberX     = 954
lastNumberY     = 217   
closeDialogueX  = 570
closeDialogueY  = 315

betRedX         = 1 #355 for real
betRedY         = 1 #540 for real
betGreenX       = 1
betGreenY       = 1
betBlackX       = 1
betBlackY       = 1

# Options
# European Roulette (0.50 - 250)
# 3D Roulette (0.50 - 250)
# Club Roulette (0.50 - 250)

# PURE FILTH WITHIN
sessionsPlayed  = 0

# Setup a new folder for the logs
if os.name == "nt":
        newPath = r'spinlogs/session-'+str(time.time())
        if not os.path.exists(newPath): os.makedirs(newPath)

elif os.name == "posix":
       print 'to do'

while sessionsPlayed < sessionsToPlay:

        # We're starting a new session, re-initialise the values
        betting             = {}
        betting["mode"]     = False
        betting["colour"]   = "-"
        currentBetSize      = 0
        betPlaced           = 0
        balance             = startingBalance
        startTime           = time.time()
        logFile             = openLogFile(newPath,"csv")
        htmlFile            = openLogFile(newPath,"html")
        htmlFile.write("<table><tr><th>Spin</th><th>Source</th><th>Interpretation</th><th>Bet Size</th><th>Balance</th></tr>")
        totalSpins          = 0

        consecutiveRed      = 0
        longestRed          = 0
        totalRed            = 0

        consecutiveGreen    = 0
        longestGreen        = 0
        totalGreen          = 0

        consecutiveBlack    = 0
        longestBlack        = 0
        totalBlack          = 0

        # Refresh the container and setup the game
        print "Refreshing the container"
        mouseclick(refreshX,refreshY)             # Refresh the container
        print "Waiting for the game to load"
        time.sleep(loadingTimeSecs)               # Wait for the game to load
        print "Closing the dialogue"
        mouseclick(closeDialogueX,closeDialogueY)  # Close the pop-up dialogue

        # Play for our session length or until we reach the desired profit
        while True:

            # Check if it's time to bail
            if ((time.time() > (startTime+(gameLength*60))) or ((balance-startingBalance) >= profitBail)) and betting["mode"] == False:
                break

            # Put money on the table if necessary
            if betting["mode"] == True:

                    # If we just entered, set the starting bet size
                    if currentBetSize == 0:
                            currentBetSize = startingBetSize

                    print "Placing a bet of",currentBetSize,"on",betting["colour"]

                    # The game sleeps for 5 seconds before you can bet
                    time.sleep(3);

                    # Recursively place a bet until matched
                    while betPlaced < currentBetSize:

                            if betting["colour"] == "red":
                                mouseclick(betRedX,betRedY)
                            elif betting["colour"] == "green":
                                mouseclick(betGreenX,betGreenY)
                            elif betting["colour"] == "black":
                                mouseclick(betBlackX,betBlackY)

                            time.sleep(delay)
                            betPlaced += 1

                    balance = balance-currentBetSize
                    betPlaced = 0

            # We can only spin when we see the spin button, so don't proceed until we see it
            spinColour = checkColour(spinX,spinY)

            while True:
                if (spinColour[1] == 153 or spinColour[1] == 196):
                    break
                spinColour = checkColour(spinX,spinY)
                print "Waiting for spin colour... (currently",str(spinColour[1])+")"
                time.sleep(delay)

            # Spin the wheel and wait a second for the screenshot to save
            mouseclick(spinX,spinY)
            totalSpins += 1
            time.sleep(delay)
            colour = checkColour(lastNumberX,lastNumberY)
            snapColour(lastNumberX,lastNumberY)    

            # What was the result?
            if colour[0] > 100:

                totalRed            +=  1
                consecutiveRed      +=  1
                consecutiveBlack    =   0
                consecutiveGreen    =   0

                print (Back.RED+"Red: "+str(consecutiveRed))

                # Have we seen more consecutive reds than ever before?
                if consecutiveRed> longestRed:
                    longestRed = consecutiveRed

                # More than 6 spins? Go to betting mode
                if consecutiveRed > trigger-1:
                    betting["mode"] = True
                    betting["colour"] = "black"
                    currentBetSize = currentBetSize*2

                # If we're in betting mode, we won! So tot up and reset
                if betting["mode"] == True and betting["colour"] == "red":
                    balance = balance+(currentBetSize*2)
                    currentBetSize  = 0
                    betting["mode"] = False

                    # The game sleeps for a few seconds here
                    time.sleep(3);

                # Don't go too deep, set 'window' to control this
                if consecutiveRed > (trigger-1)+window:
                    print "Too stable (",consecutiveRed,"spins since we saw a red). Bailing."
                    balance = balance+(currentBetSize*2)
                    currentBetSize  = 0
                    betting["mode"] = False

                # Clear the table
                mouseclick(clearX, clearY);

            elif colour[1] < 100:

                totalBlack          +=  1
                consecutiveBlack    +=  1
                consecutiveRed      =   0
                consecutiveGreen    =   0

                print "Black:",consecutiveBlack

                # Have we seen more consecutive blacks than ever before=
                if consecutiveBlack > longestBlack:
                    longestBlack = consecutiveBlack

                # More than 6 spins? Go to betting mode
                if consecutiveBlack > trigger-1:
                    betting["mode"] = True
                    betting["colour"] = "red"
                    currentBetSize = currentBetSize*2

                # If we're in betting mode, we won! So tot up and reset
                if betting["mode"] == True and betting["colour"] == "black":
                    balance = balance+(currentBetSize*2)
                    currentBetSize  = 0
                    betting["mode"] = False

                    # The game sleeps for a few seconds here
                    time.sleep(3);

                # Don't go too deep, set 'window' to control this
                if consecutiveBlack > (trigger-1)+window:
                    print "Too stable (",consecutiveBlack,"spins since we saw a black). Bailing."
                    balance = balance+(currentBetSize*2)
                    currentBetSize  = 0
                    betting["mode"] = False

            elif colour[1] > 100:

                consecutiveGreen    +=  1
                consecutiveBlack    = 0
                consecutiveRed      = 0

                print (Back.GREEN+Fore.BLACK+"Green"+str(consecutiveGreen))

                # Have we seen more consecutive reds or blacks than ever before?
                if consecutiveBlack > longestBlack:
                    longestBlack = consecutiveBlack
                if consecutiveRed > longestRed:
                    longestRed = consecutiveRed

                # More than 6 red or black spins? Go to betting mode
                if consecutiveBlack > trigger-1:
                    betting["mode"] = True
                    betting["colour"] = "red"
                    currentBetSize = currentBetSize*2
                elif consecutiveRed > trigger-1:
                    betting["mode"] = True
                    betting["colour"] = "black"
                    currentBetSize = currentBetSize*2

                # We don't bet on green, so if we're in betting mode, keep going

            # Log it
            secondsRemaining = (startTime+(gameLength*60))-time.time()
            print "Balance:",balance,"-",(balance-startingBalance),"profit -",str(datetime.timedelta(seconds=secondsRemaining))[:-7],"remaining"
            logFile.write(str(balance))
            logFile.write("\n")

            # Publish it
            htmlFile.write("<tr><td>"+str(totalSpins)+"</td><td><img src="+str(totalSpins)+".jpg></td><td>"+str(colour)+"</td><td>"+str(currentBetSize)+"</td><td>"+str(balance)+"</td>")
        
        htmlFile.write("</table>")
        logFile.write(str(longestBlack))                       
        print "Sesson complete. Longest black streak",longestBlack

print "Game complete"