# utils.py
"""
    Copyright (C) 2010  Peter Hewitt

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

"""
import os
import sys
import random
import logging
import pygame

import g
import load_save

# constants
RED, BLUE, GREEN = (255, 0, 0), (0, 0, 255), (0, 255, 0)
BLACK, WHITE = (0, 0, 0), (255, 255, 255)
CYAN, ORANGE, CREAM = (0, 255, 255), (255, 165, 0), (255, 255, 192)
YELLOW = (255, 255, 0)
MAGENTA = (255, 0, 255)


def exit():
    save()
    pygame.display.quit()
    pygame.quit()
    sys.exit()


def save():
    directory = ''
    directory = os.environ.get('SUGAR_ACTIVITY_ROOT')
    if directory is None:
        directory = ''
    fname = os.path.join(directory, 'data', 'Letters.dat')
    try:
        f = open(fname, 'w')
    except Exception as e:
        logging.error('Could not open %s: %s' % (fname, e))
        return
    load_save.save(f)
    f.close


def load():
    directory = ''
    directory = os.environ.get('SUGAR_ACTIVITY_ROOT')
    if directory is None:
        directory = ''
    fname = os.path.join(directory, 'data', 'Letters.dat')
    if os.path.exists(fname):
        try:
            f = open(fname, 'r')
        except Exception as e:
            logging.error('Could not open %s: %s' % (fname, e))
            return None
        try:
            load_save.load(f)
        except Exception as e:
            logging.error('load_save failed: %s' % (e))
        f.close


def version_display():
    g.message = g.app + ' ' + g.ver
    g.message += '  ' + str(g.screen.get_width()) + ' x ' + \
        str(g.screen.get_height())
    message(g.screen, g.font1, g.message)


# loads an image (eg pic.png) from the data subdirectory
# converts it for optimum display
# resizes it using the image scaling factor,  g.imgf
#   so it is the right size for the current screen resolution
#   all images are designed for 1200x900
def load_image(file1, alpha=False, subdir=''):  # eg subdir = 'glow'
    data = 'data'
    if subdir != '':
        data = os.path.join('data', subdir)
    fname = os.path.join(data, file1)
    try:
        img = pygame.image.load(fname)
    except:
        print "Peter says: Can't find " + fname
        exit()
    if alpha:
        img = img.convert_alpha()
    else:
        img = img.convert()
    if abs(g.imgf - 1.0) > .1:  # only scale if factor <> 1
        w = img.get_width()
        h = img.get_height()
        try:
            img = pygame.transform.smoothscale(
                img, (int(g.imgf * w), int(g.imgf * h)))
        except:
            img = pygame.transform.scale(
                img, (int(g.imgf * w), int(g.imgf * h)))
    return img


# eg new_list = copy_list(old_list)
def copy_list(l):
    new_list = []
    new_list.extend(l)
    return new_list


def shuffle(lst):
    l1 = lst
    lt = []
    for i in range(len(lst)):
        ln = len(l1)
        r = random.randint(0, ln - 1)
        lt.append(lst[r])
        l1.remove(lst[r])
    return lt


def centre_blit(screen, img, (cx, cy), angle=0):  # rotation is clockwise
    img1 = img
    if angle != 0:
        img1 = pygame.transform.rotate(img, -angle)
    rect = img1.get_rect()
    screen.blit(img1, (cx - rect.width / 2, cy - rect.height / 2))


def text_blit(screen, s, font, (cx, cy), (r, g, b), shadow=True):
    if shadow:
        text = font.render(s, True, (0, 0, 0))
        rect = text.get_rect()
        rect.centerx = cx + 2
        rect.centery = cy + 2
        screen.blit(text, rect)
    text = font.render(s, True, (r, g, b))
    rect = text.get_rect()
    rect.centerx = cx
    rect.centery = cy
    screen.blit(text, rect)
    return rect


def text_blit1(screen, s, font, (x, y), (r, g, b), shadow=True):
    if shadow:
        text = font.render(s, True, (0, 0, 0))
        rect = text.get_rect()
        rect.x = x + 2
        rect.y = y + 2
        screen.blit(text, rect)
    text = font.render(s, True, (r, g, b))
    rect = text.get_rect()
    rect.x = x
    rect.y = y
    screen.blit(text, rect)


# m is the message
# d is the # of pixels in the border around the text
# (cx, cy)  =  coords centre - (0, 0) means use screen centre
def message(screen, font, m, (cx, cy)=(0, 0), d=20):
    if m != '':
        if pygame.font:
            text = font.render(m, True, (255, 255, 255))
            shadow = font.render(m, True, (0, 0, 0))
            rect = text.get_rect()
            if cx == 0:
                cx = screen.get_width() / 2
            if cy == 0:
                cy = screen.get_height() / 2
            rect.centerx = cx
            rect.centery = cy
            bgd = pygame.Surface((rect.width + 2 * d, rect.height + 2 * d))
            bgd.fill((0, 255, 255))
            bgd.set_alpha(128)
            screen.blit(bgd, (rect.left - d, rect.top - d))
            screen.blit(
                shadow, (rect.x + 2, rect.y + 2, rect.width, rect.height))
            screen.blit(text, rect)


def mouse_on_img(img, (x, y)):  # x, y = top left
    w = img.get_width()
    h = img.get_height()
    mx, my = g.pos
    if mx < x:
        return False
    if mx > (x + w):
        return False
    if my < y:
        return False
    if my > (y + h):
        return False
    try:  # in case out of range
        col = img.get_at((int(mx - x), int(my - y)))
    except:
        return False
    if col[3] < 10:
        return False
    return True


def mouse_on_img1(img, (cx, cy)):
    xy = centre_to_top_left(img, (cx, cy))
    return mouse_on_img(img, xy)


def mouse_on_img_rect(img, (cx, cy)):
    w2 = img.get_width() / 2
    h2 = img.get_height() / 2
    x1 = cx - w2
    y1 = cy - h2
    x2 = cx + w2
    y2 = cy + h2
    return mouse_in(x1, y1, x2, y2)


def mouse_in(x1, y1, x2, y2):
    mx, my = g.pos
    if x1 > mx:
        return False
    if x2 < mx:
        return False
    if y1 > my:
        return False
    if y2 < my:
        return False
    return True


def mouse_in_rect(rect):  # x, y, w, h
    return mouse_in(rect[0], rect[1], rect[0] + rect[2], rect[1] + rect[3])


def display_score():
    if pygame.font:
        text = g.font2.render(str(g.score), True, ORANGE, BLUE)
        w = text.get_width()
        h = text.get_height()
        x = g.sx(5.7)
        y = g.sy(18.8)
        d = g.sy(.3)
        pygame.draw.rect(g.screen, BLUE,
                         (x - d - g.sy(.05), y - d, w + 2 * d, h + 2 * d))
        g.screen.blit(text, (x, y))
        centre_blit(g.screen, g.sparkle,
                    (x - d + g.sy(.05), y + h / 2 - g.sy(.2)))


def display_number(n, (cx, cy), font, colour=BLACK, bgd=None,
                   outline_font=None):
    if pygame.font:
        if bgd is None:
            text = font.render(str(n), True, colour)
        else:
            text = font.render(str(n), True, colour, bgd)
        if outline_font is not None:
            outline = outline_font.render(str(n), True, BLACK)
            centre_blit(g.screen, outline, (cx, cy))
        centre_blit(g.screen, text, (cx, cy))


def display_number1(n, (x, cy), font, colour=BLACK):
    if pygame.font:
        text = font.render(str(n), True, colour)
        y = cy - text.get_height() / 2
        g.screen.blit(text, (x, y))


def top_left_to_centre(img, (x, y)):
    cx = x + img.get_width() / 2
    cy = y + img.get_height() / 2
    return (cx, cy)


def centre_to_top_left(img, (cx, cy)):
    x = cx - img.get_width() / 2
    y = cy - img.get_height() / 2
    return (x, y)
