"""Game weapon charge classes."""


import logging
import curses

from xoinvader import application
from xoinvader.common import Settings, get_json_config
from xoinvader.render import Renderable
from xoinvader.utils import Point, Surface


CONFIG = get_json_config(Settings.path.config.charges)
LOG = logging.getLogger(__name__)


# pylint: disable=too-many-arguments
class WeaponCharge(Renderable):
    """Weapon charge representation.

    Separate renderable object that updates and renders as others
    in main loop. Must register/deregister itself via state's
    add/remove methods.
    """

    def __init__(self, pos, image, damage=0, radius=0, dx=0, dy=0):
        self._pos = pos
        self._image = image
        self._type = self.__class__.__name__
        application.get_current().state.add(self)

        self._damage = damage
        self._radius = radius
        # TODO: [object-movement]
        # Generalize update to support dx
        self._dx = dx
        self._dy = dy

    def get_render_data(self):
        return ([self._pos], self._image.get_image())

    def remove_obsolete(self, pos):
        LOG.debug("%s remove obsolete.", self._type)
        application.get_current().state.remove(self)

    def update(self):
        """Update coords."""

        self._pos += Point(self._dx, self._dy)


# TODO: Implement hitscan behaviour
# pylint: disable=useless-super-delegation
class Hitscan(WeaponCharge):
    """Hitscan weapon charge hits target immediately.

    Can pierce enemies?
    """

    def __init__(self, pos, image, **kwargs):
        super(Hitscan, self).__init__(pos, image, **kwargs)


class Projectile(WeaponCharge):
    """Projectile weapon has generic physics of movement."""

    def __init__(self, pos, image, **kwargs):
        super(Projectile, self).__init__(pos, image, **kwargs)


# TODO: write template documentation for charges and weapons
class BasicPlasmaCannon(Projectile):
    """Small damage, no radius."""

    def __init__(self, pos):
        super(BasicPlasmaCannon, self).__init__(
            pos, Surface(["^"], style=[[curses.A_BOLD]]),
            **CONFIG[self.__class__.__name__])


class EBasicPlasmaCannon(Projectile):
    """Enemy plasma cannon."""

    def __init__(self, pos):
        super(EBasicPlasmaCannon, self).__init__(
            pos, Surface([":"], style=[[curses.A_BOLD]]),
            **CONFIG[self.__class__.__name__])


class BasicLaserCharge(Projectile):
    """Laser. Quite fast but cannot pierce enemies."""

    def __init__(self, pos):
        super(BasicLaserCharge, self).__init__(
            pos, Surface(["|"], style=[[curses.A_BOLD]]),
            **CONFIG[self.__class__.__name__])


class BasicUnguidedMissile(Projectile):
    """Unguided missile with medium damage and small radius."""

    def __init__(self, pos):
        super(BasicUnguidedMissile, self).__init__(
            pos, Surface([
                "^",
                "|",
                "*"
            ], style=[[curses.A_BOLD] for _ in range(3)]),
            **CONFIG[self.__class__.__name__])

@@ -997,179 +997,610 @@
     
-def get_render_data(self):%0A        return (%5Bself._pos%5D, self._image.get_image())%0A%0A    def remove_obsolete(self, pos):%0A        LOG.debug(%22%25s remove obsolete.%22, self._type)%0A
+    # Set to True means that object in destroying phase%0A        # and will ignore remove_obsolete signal%0A        self._destroy = False%0A%0A    def get_render_data(self):%0A        return (%5Bself._pos%5D, self._image.get_image())%0A%0A    def remove_obsolete(self, pos):%0A        border = Settings.layout.field.border%0A        pos = self._pos%5Bint%5D%0A        if (%0A                pos.x %3E self._image.width + border.x or%0A                pos.x + self._image.width %3C 0 or%0A                int(pos.y) %3E self._image.height + border.y or%0A                int(pos.y) + self._image.height %3C 0%0A        ) and not self._destroy:%0A    
     
@@ -1643,24 +1643,57 @@
 remove(self)
+%0A            self._destroy = True
 %0A%0A    def up

fix excess State.remove calls