# characters.py - module for weapon classes
# Copyright (C) 2017-2020  Nguyễn Gia Phong
#
# This file is part of Brutal Maze.
#
# Brutal Maze is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# Brutal Maze is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Brutal Maze.  If not, see <https://www.gnu.org/licenses/>.

__doc__ = 'Brutal Maze module for weapon classes'

from math import cos, sin

from .constants import (BULLET_LIFETIME, SFX_SHOT_ENEMY, SFX_SHOT_HERO,
                        BULLET_SPEED, ENEMY_HP, TANGO, BG_COLOR)
from .misc import regpoly, fill_aapolygon


class Bullet:
    """Object representing a bullet.

    Attributes:
        surface (pygame.Surface): the display to draw on
        x, y (int): coordinates of the center of the bullet (in pixels)
        angle (float): angle of the direction the bullet pointing (in radians)
        color (str): bullet's color name
        fall_time (int): time until the bullet fall down
        sfx_hit (str): sound effect indicating target was hit
    """
    def __init__(self, surface, x, y, angle, color):
        self.surface = surface
        self.x, self.y, self.angle, self.color = x, y, angle, color
        self.fall_time = BULLET_LIFETIME
        if color == 'Aluminium':
            self.sfx_hit = SFX_SHOT_ENEMY
        else:
            self.sfx_hit = SFX_SHOT_HERO

    def update(self, fps, distance):
        """Update the bullet."""
        s = distance * BULLET_SPEED / fps
        self.x += s * cos(self.angle)
        self.y += s * sin(self.angle)
        self.fall_time -= 1000 / fps

    def get_color(self):
        """Return current color of the enemy."""
        value = int((1 - self.fall_time/BULLET_LIFETIME) * ENEMY_HP)
        try:
            return TANGO[self.color][value]
        except IndexError:
            return BG_COLOR

    def draw(self, radius):
        """Draw the bullet."""
        pentagon = regpoly(5, radius, self.angle, self.x, self.y)
        fill_aapolygon(self.surface, pentagon, self.get_color())

    def place(self, x, y):
        """Move the bullet by (x, y) (in pixels)."""
        self.x += x
        self.y += y

    def get_distance(self, x, y):
        """Return the from the center of the bullet to the point (x, y)."""
        return ((self.x-x)**2 + (self.y-y)**2)**0.5


class LockOn:
    """Lock-on device to assist hero's aiming.
    This is used as a mutable object to represent a grid of wall.

    Attributes:
        x, y (int): coordinates of the target (in grids)
        retired (bool): flag indicating if the target is retired
    """
    def __init__(self, x, y, retired=False):
        self.x, self.y = x, y
        self.retired = retired

    def place(self, x, y, isdisplayed):
        """Move the target by (x, y) (in grids)."""
        self.x += x
        self.y += y
        if not isdisplayed(self.x, self.y): self.retired = True
