# This file is part of ROBOTGAME
#
# ROBOTGAME 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.
#
# ROBOTGAME 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# ROBOTGAME.  If not, see <http://www.gnu.org/licenses/>.
#
# ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
#
#                          block.py
#                     --------------------
#       date created : Tue Aug 7 2012
#          copyright : (C) 2012 Sakse Dalum
#      maintained by : Sakse Dalum <don_s@hongabar.org>

"""
A generic block. And other block derivatives.
"""

import pygame

import worldobject
import copy

class Block(worldobject.WorldObject):
    def __init__(self, level, x, y, img_str='block1',
                 movable=False, visible=True):
        self.__dict__.update(locals())
        worldobject.WorldObject.__init__(self, level, x, y,
                                         movable=movable, visible=visible)

        self.load()

        # self.orig_alphas = {
        #     'normal':
        #         pygame.surfarray.array_alpha(self.level.imgs[self.img_str]),
        #     'lifted':
        #         pygame.surfarray.array_alpha(
        #         self.level.imgs[self.img_str + '_lifted'])}

        # self.orig_alpha = self.orig_alphas['normal']

    def load(self):
        if not isinstance(self.img_str, str):
            self.img_str = self.level.reverse_imgs[self.img_str]

        self.img = self.level.imgs[self.img_str]

    # def update_alpha(self):
    #     be_opaque = not (self.y + self.z >= self.level.player.move_y
    #                      + self.level.player.move_z)
    #     if be_opaque and not self.is_currently_opaque:
    #         self.is_currently_opaque = True
    #         self.set_alpha(1)
    #     elif not be_opaque and self.is_currently_opaque:
    #         self.is_currently_opaque = False
    #         self.set_alpha(0.5)

    def use(self, obj):
        if self.movable:
            if obj == self.holder:
                obj.holding = None
                self.holder = None
                if hasattr(self, 'img_str'):
                    self.img = self.level.imgs[self.img_str]
                    # self.orig_alpha = self.orig_alphas['normal']
            else:
                obj.holding = self
                self.holder = obj
                if hasattr(self, 'img_str'):
                    self.img = self.level.imgs[self.img_str + '_lifted']
                    # self.orig_alpha = self.orig_alphas['lifted']

    def draw(self, window):
        if self.visible:
            window.blit(self.img, (self.x - 32 - self.level.camera_x,
                                   self.y - self.img.get_size()[1] + 24
                                   - self.level.camera_y))

class InvisBlock(Block):
    def __init__(self, level, x, y):
        self.__dict__.update(locals())
        worldobject.WorldObject.__init__(self, level, x, y, visible=False)


class ArrowBlock(Block):
    def __init__(self, level, x, y, direction, movable=True, is_up=True):
        self.__dict__.update(locals())
        worldobject.WorldObject.__init__(self, level, x, y,
                                         direction=direction, movable=movable)

        self.frame = 0
        self.anim_speed = 15
        self.setting = False

        if direction == (1, 0):
            self.anim = 'arrow_right'
        if direction == (-1, 0):
            self.anim = 'arrow_left'
        if direction == (0, -1):
            self.anim = 'arrow_up'
        if direction == (0, 1):
            self.anim = 'arrow_down'

    def activate(self, setting):
        self.movable = True
        if not self.share_tile(worldobject.WorldObject):
            self.is_up = not setting
        self.movable = False

    def update(self, e, t, dt):
        # Update the animation
        if not self.is_up:
            self.frame = min(self.frame + self.anim_speed * dt,
                             len(self.level.imgs[self.anim]) - 1)
        else:
            self.frame = max(self.frame - self.anim_speed * dt,
                             0)

        if self.frame == len(self.level.imgs[self.anim]) - 1:
            self.movable = self.blocking = False
            self.z = -48
            if self.holder:
                self.holder.holding = None
                self.holder = None
        else:
            self.movable = self.blocking = True
            self.z = 0

        worldobject.WorldObject.update(self, e, t, dt)

    def draw(self, window):
        self.img = self.level.imgs[self.anim][int(self.frame)]
        Block.draw(self, window)

class RisingBlock(Block):
    def __init__(self, level, x, y, movable=False, is_up=True):
        self.__dict__.update(locals())
        worldobject.WorldObject.__init__(self, level, x, y, movable=movable)

        self.frame = 0
        self.anim_speed = 15
        self.setting = [0, 0]

        self.init_setting = self.setting

        self.anim = 'arrow_right'

    def set_init_pos(self):
        worldobject.WorldObject.set_init_pos(self)
        self.init_setting = [self.setting[0], self.setting[1]]

    def reset_pos(self):
        worldobject.WorldObject.reset_pos(self)
        self.setting = [self.init_setting[0], self.init_setting[1]]
        self.is_up = self.setting[1] == self.setting[0]

    def activate(self, setting):
        if setting in [2, 3]:
            self.setting[1] = setting - 2
        else:
            self.setting[0] = setting
        if not self.share_tile(worldobject.WorldObject):
            self.is_up = self.setting[1] == self.setting[0]

    def update(self, e, t, dt):
        # Update the animation
        if not self.is_up:
            self.frame = min(self.frame + self.anim_speed * dt,
                             len(self.level.imgs[self.anim]) - 1)
        else:
            self.frame = max(self.frame - self.anim_speed * dt,
                             0)

        if self.frame == len(self.level.imgs[self.anim]) - 1:
            self.blocking = False
            self.z = -48
        else:
            self.blocking = True
            self.z = 0

        worldobject.WorldObject.update(self, e, t, dt)

    def draw(self, window):
        self.img = self.level.imgs[self.anim][int(self.frame)]
        Block.draw(self, window)


class ActionBlock(Block):
    def __init__(self, level, x, y, action=None, movable=True):
        self.__dict__.update(locals())
        Block.__init__(
            self, level, x, y, 'block1', movable=movable)
        self._last_pos = None

    def update(self, e, t, dt):
        if (self.x, self.y) != self._last_pos and not self.is_moving:
            self.action(self)
            self._last_pos = self.x, self.y

        worldobject.WorldObject.update(self, e, t, dt)

class ColorWell(Block):
    def __init__(self, level, x, y, img_str='well'):
        self.__dict__.update(locals())
        worldobject.WorldObject.__init__(
            self, level, x, y, movable=False)

        Block.load(self)

        self.col_img = pygame.Surface((32, 32))

    def set_colour(self, r, g, b):
        self.well_colour = r * 255, g * 255, b * 255
        self.col_img.fill(self.well_colour)

    def draw(self, window):
        if self.visible:
            window.blit(self.col_img, (self.x - self.level.camera_x + 16,
                                   self.y - self.img.get_size()[1] + 52
                                   - self.level.camera_y))
        Block.draw(self, window)
