from __future__ import division

import math
import pygame

import vect

        
""" there are 40 pixels per world meter at zoom scale == 1. PPM = pixels per meter"""

        
def screen_pos(world, location):
    """ transforms a world LOCATION to a screen POSITION"""
    temp_position = vect.add(world.PPM,location, -world.PPM, world.screen_location)
    position = vect.add(world.scale, temp_position, 1-world.scale, world.zoom_position)
    c,d = position
    position = int(c), int(world.screen_height-d)
    return position

def world_loc(world, position):
    """ transforms a screen POSITION to a world LOCATION"""
    a,b = position
    temp_location = a, world.screen_height-b
    temp_location2 = vect.add(1/world.scale, temp_location, -1/world.scale+1, world.zoom_position)
    location = vect.add(1/world.PPM,temp_location2, 1, world.screen_location)
    return location

def mouse_scroll(world):
    if pygame.mouse.get_focused() and world.mouse_scroll:
        """this updates the screen LOCATION based upon mouse movement"""
        get_rel = vect.add(-1,world.screen_center,1,pygame.mouse.get_pos())
        
        mousemove = vect.add(2/world.PPM/world.scale, get_rel)
        mousemove = (mousemove[0],-mousemove[1])
        world.screen_location = vect.add(1,world.screen_location, 1, mousemove)
        pygame.mouse.set_pos(world.screen_center)
    
def screen_scroll(world):
    """this updates the screen LOCATION based upon avatar movement"""
    if world.player:
        player_movement = vect.add(1,world.player.location,-1,world.player.old_location)
        world.player.old_location = world.player.location
    else:
        player_movement = (0,0)
    world.screen_location = vect.add(1,world.screen_location, 1, player_movement)
    
    mouse_scroll(world)

def center_screen(object):
    """ fixes the object in the middle of the screen """
    loc = world_loc(object.world, object.world.screen_center)
    #loc = object.world.screen_location
    delta = vect.add(1, object.location, -1, loc)
    object.world.screen_location = vect.add(1, object.world.screen_location, 1, delta)    
    
def scale_images(world):
    for image_data in world.images.keys():
        world.images[image_data].scale_image(world.scale)

def zoom_in(world):
    old_scale = world.scale
    world.zoom_factor = 1/0.80
    zoom_screen(world)
    if world.scale != old_scale:
        scale_images(world)

def zoom_out(world):
    old_scale = world.scale
    world.zoom_factor = 0.80
    zoom_screen(world)
    if world.scale != old_scale:
        scale_images(world)

def zoom_screen(world):
    world.scale = world.scale*world.zoom_factor
    if world.scale > 1:
        world.scale = 1
    if world.scale < 0.09:
        world.scale = 0.09
    world.zoom_factor = 1

def screen_coord(world):
    screen_scroll(world)
    zoom_screen(world)
    find_screen_bounds(world)
    find_screen_center_location(world)
    
def showFPS(time, tempFPS):
    FPS = 50
    if time % 500:
        FPS = tempFPS
    return FPS

def draw_grid(world):
    linesy = []
    linesx = []
    grid_color = (150,150,150)
    for i in xrange(int(world.dimensions[0]/world.grid_size+1)):
        a = screen_pos(world,(world.grid_size*i,0))
        b = screen_pos(world,(world.grid_size*i,world.dimensions[1]))
        newliney = [[a[0],a[1]],[b[0],b[1]]]
        linesy.append(newliney)
        
    for i in xrange(int(world.dimensions[1]/world.grid_size+1)):
        c = screen_pos(world,(0,world.grid_size*i))
        d = screen_pos(world,(world.dimensions[0],world.grid_size*i))
        
        newlinex = [[c[0],c[1]],[d[0],d[1]]]
        linesx.append(newlinex)
    for i in xrange(len(linesy)):
        pygame.draw.line(world.screen,grid_color,linesy[i][0],linesy[i][1])
    for i in xrange(len(linesx)):
        pygame.draw.line(world.screen,grid_color,linesx[i][0],linesx[i][1])
        
def draw_indicators(world):
    #screen_location = world_loc(world, world.screen_center)
    if world.draw_sprite_paths:
        for sim in world.spriteGroups[-1]:
            draw_screen_edge_indicator(world, sim)

def draw_screen_edge_indicator(world, sim):
##    onscreen = if (sim.position[0] < 0 or sim.position[0] > world.screen_width
##        or sim.position[1] < 0 or sim.position[1] > world.screen_height)
        
    if sim.indicator_color:
        dist = vect.distance_to(sim.location, world.screen_center_location)
        if dist > 1:
            sim_angle = vect.angle_to(sim.location, world.screen_center_location)
            distance = vect.distance_to(sim.location, world.screen_center_location)*world.PPM*world.scale
            radius1 = math.hypot(1,math.tan(sim_angle))*world.screen_width/2
            radius2 = math.hypot(1, math.tan(math.pi/2-sim_angle))*world.screen_height/2
            radius = min(radius1, radius2)
            radius_max = radius-20 #puts the start point 20pixels from edge of screen
            radius_min = radius-20+20*min(distance/radius-1,1) #puts the end points away from start point dependant on where the object is relative to edge of screen
            indicator_position_max = int(radius_max*math.cos(sim_angle)+world.screen_width/2), int(world.screen_height/2-radius_max*math.sin(sim_angle))
            indicator_position_min = int(radius_min*math.cos(sim_angle)+world.screen_width/2), int(world.screen_height/2-radius_min*math.sin(sim_angle))
            pygame.draw.line(world.screen, sim.indicator_color, indicator_position_min, indicator_position_max, 2)
            pygame.draw.circle(world.screen, sim.indicator_color, indicator_position_max, 4)
                
def find_screen_bounds(world):
    delta = 20 # 20 pixels, kludge at variable zooms, but not a problem at the moment
    min = world_loc(world, (-delta,world.screen_height+delta))
    max = world_loc(world, (world.screen_width+delta,-delta))
    world.screen_bounds = (min, max)
    
def find_screen_center_location(world):
    world.screen_center_location = world_loc(world, world.screen_center)

def draw_grid_count(world):
    for square in world.grid.squares.values():
        location = square.posX, square.posY
        position = ui.screen_pos(world, location)
        world.square_text = simobject.TextBox(world, position, 10,1)
        world.square_text.location = location
        world.square_text.text = ""
        world.spriteGroups[1000].add(world.square_text)
        print len(world.hudSprites)

def loc_on_screen(world, location):
    min, max = world.screen_bounds
    x,y = location
    # assume offscreen
    #value = False
    if min[0] < x < max[0]:
        if min[1] < y < max[1]:
            return True
    return False
    
def pos_on_screen(world, pos):
    x,y = pos
    value = 0
    scale = world.PPM*world.scale/2
    dx = world.grid.square_width*scale
    dy = world.grid.square_height*scale
    if -dx < x < world.screen_width+dx and -dy < y < world.screen_height+dy:
        value = 1
    return value

class timer(object):
    def __init__(self, world, sim = None, max_time = None, name = None):
        self.name = name
        self.world = world
        
        self.max_time = max_time
        self.time = max_time
        
        """ add timer to world so it can be easily updated """
        self.world.timers.add(self)
        """ add timer to sim so it can easily be removed when sim is removed """
        if sim:
            self.sim = sim        
            self.sim.timers.add(self)
        
    def update(self):
        if self.time>0:
            self.time -= self.world.dt
        if self.time < 0:
            self.time = 0
            
    def check(self):
        if not self.time:
            return True
        else:
            return False
    
    def get(self):
        return self.time
    
    def set(self, time_remaining = None):
        if time_remaining == None:
            self.time = self.max_time
        else:
            self.time = time_remaining
    
    def remove(self):
        self.world.timers.remove(self)
        self.kill()
        