# -*- coding: utf-8 -*-




def run_simulation( simulation, configuration, controller ):
    simulation.input[0x3e80] = configuration
    t = 0
    for ports in simulation:
        port_values = [simulation.port[p] for p in range(0,5)]
        score, fuel_remaining, x, y, target_orbit_radius = port_values

        if controller:
            values = controller(t, *port_values)
            if values:
                for input_port, value in values.items():
                    simulation.input[input_port] = value
        if score:
            print "Score: ", score
            return score
        t += 1


# ============== pygame visualiser

import pygame
class Visualiser(object):
    def __init__(visualiser, size):
        pygame.init()

        screen = pygame.display.set_mode(size)
        surface = pygame.Surface(size).convert()
        satellite = pygame.Surface((3, 3)).convert()
        fire = pygame.Surface((3, 3)).convert()
        smoke = pygame.Surface((3, 3)).convert()
        trail = [None for i in xrange(10)]

        visualiser.__dict__.update(
            size = size,
            screen = screen,
            surface = surface,
            satellite = satellite,
            fire = fire,
            smoke = smoke,
            trail = trail,
        )

        pygame.draw.circle(visualiser.screen, (0,0,255), (250, 250), 160)

        satellite.fill((255, 0, 0))
        fire.fill((250, 150, 0))
        smoke.fill((50, 50, 0))

        def visualise(t, score, fuel_remaining, x, y, target_orbit_radius):
            if t % 10:
                return

            thrust = trail[-1]
            if thrust:
                screen.blit(fire, thrust)

            end_of_trail = trail.pop(0)
            if end_of_trail:
                screen.blit(smoke, end_of_trail)

            pos = (250 + (x/40000), (y/40000) + 250)
            trail.append(pos)

            screen.blit(satellite, pos)
            pygame.display.flip()

        visualiser.visualise = visualise

    def log(visualiser, t, score, fuel_remaining, x, y, target_orbit_radius):
        print "%s : [ Fuel: %s | X: %s | Y: %s | target = %s ]" % ( t, fuel_remaining, x, y, target_orbit_radius )



class Chimpanzee(object):
    def __init__(chimp, *instructions):
        chimp.visualiser = Visualiser((500, 500))
        flight_plan = instructions.__iter__()
        chimp.flight_plan = flight_plan
        chimp.next_instruction_time, values = flight_plan.next()

    def __call__(chimp, t, score, fuel_remaining, x, y, target_orbit_radius):
        chimp.visualiser.visualise(t, score, fuel_remaining, x, y, target_orbit_radius)
        chimp.visualiser.log(t, score, fuel_remaining, x, y, target_orbit_radius)

        if t == chimp.next_instruction_time:
            try:
                time, values = chimp.flight_plan.next()
                chimp.next_instruction_time = time
                return values
            except StopIteration:
                chimp.__call__ = lambda *a,**k: None
                return None

X = 0x2
Y = 0x3
"""
from cpp import virtualmachine
simulation = virtualmachine()
simulation.load('binaries/bin1.obf')
"""
import translated_binaries.bin1
run_simulation( translated_binaries.bin1.OrbitalVirtualMachine(), 1002,
    Chimpanzee(
        (0, {Y:-1000.0}),
        (10, {Y:0.0}),
    )
)



