# Path: MTG/gameobject.py
# class Characteristics():
# class GameObject():
#     def __init__(self,
#                  name='',
#                  mana_cost='',
#                  color=[],
#                  types=[],
#                  subtype=[],
#                  supertype=[],
#                  text='',
#                  abilities=[],
#                  power=None,
#                  toughness=None,
#                  loyalty=None):
#     def __repr__(self):
#     def satisfy(self, criteria):
#     def __init__(self, characteristics=None,
#                  controller=None, owner=None, zone=None, 
#                  previousState=None):
#     def __repr__(self):
#     def __str__(self):
#     def __eq__(x, y):
#     def __hash__(self):
#     def owner(self):
#     def game(self):
#     def is_permanent(self):
#     def is_spell(self):
#     def name(self):
#     def raw_manacost(self):
#     def manacost(self):
#     def is_land(self):
#     def is_basic_land(self):
#     def is_creature(self):
#     def is_instant(self):
#     def is_sorcery(self):
#     def is_artifact(self):
#     def is_enchantment(self):
#     def is_aura(self):
#     def is_equipment(self):
#     def power(self):
#     def toughness(self):
#     def has_ability(self, ability):
#     def share_color(self, other):
#     def has_color(self, color):
#     def is_color(self, color):
#     def is_monocolored(self):
#     def is_multicolored(self):
#     def is_colorless(self):
#     def has_subtype(self, subtype):
#     def exile(self):
#     def targets(self):
#     def target_legality(self):
#     def has_valid_target(self):
#     def choose_targets(self):
#     def change_zone(self, target_zone, from_top=0, shuffle=True,
#                     status_mod=None, modi_func=None):
# 
# Path: MTG/zone.py
# class ZoneType(Enum):
# class Zone():
# class Battlefield(Zone):
# class Stack(Zone):
# class Hand(Zone):
# class Graveyard(Zone):
# class Exile(Zone):
# class Library(Zone):
#     LIBRARY = 0
#     HAND = 1
#     BATTLEFIELD = 2
#     GRAVEYARD = 3
#     STACK = 4
#     EXILE = 5
# def str_to_zone_type(z):
#     def __init__(self, controller=None, elements: list=None):
#     def __repr__(self):
#     def __str__(self):
#     def __len__(self):
#     def __bool__(self):
#     def __getitem__(self, pos):
#     def isEmpty(self):
#     def add(self, obj):
#     def remove(self, obj):
#     def filter(self, characteristics=None, filter_func=None):
#     def count(self, characteristics=None, filter_func=None):
#     def get_card_by_name(self, name):
#     def pop(self, pos=-1):
#     def clear(self):
#     def add(self, obj, status_mod=None, modi_func=None):
#     def shuffle(self):
#     def __init__(self, controller=None, elements: list=None):
#     def add(self, obj, from_top=0, shuffle=True):
#     def remove(self, obj, shuffle=False):


import inspect
from MTG import gameobject
from MTG import zone

class Play(gameobject.GameObject):
    """
    Represents an ability or spell on the stack.

    Spells: card = original card
    Abilities: source = card that owns this ability
    """

    # TODO: unify this with gameObject init (particularly with targetting)
    def __init__(self, apply_func, apply_condition=lambda: True, 
                 card=None, source=None, name=None,
                 targets_chosen=None, target_criterias=None, is_mana_ability=False):
        
        # TODO: okay this is really ugly and bug-prone.
        # Think about how to fix this initialization.
        if card:
            controller = card.controller
        elif source:
            controller = source.controller
        else:
            controller = None


# Path: MTG/gameobject.py
# class Characteristics():
# class GameObject():
#     def __init__(self,
#                  name='',
#                  mana_cost='',
#                  color=[],
#                  types=[],
#                  subtype=[],
#                  supertype=[],
#                  text='',
#                  abilities=[],
#                  power=None,
#                  toughness=None,
#                  loyalty=None):
#     def __repr__(self):
#     def satisfy(self, criteria):
#     def __init__(self, characteristics=None,
#                  controller=None, owner=None, zone=None, 
#                  previousState=None):
#     def __repr__(self):
#     def __str__(self):
#     def __eq__(x, y):
#     def __hash__(self):
#     def owner(self):
#     def game(self):
#     def is_permanent(self):
#     def is_spell(self):
#     def name(self):
#     def raw_manacost(self):
#     def manacost(self):
#     def is_land(self):
#     def is_basic_land(self):
#     def is_creature(self):
#     def is_instant(self):
#     def is_sorcery(self):
#     def is_artifact(self):
#     def is_enchantment(self):
#     def is_aura(self):
#     def is_equipment(self):
#     def power(self):
#     def toughness(self):
#     def has_ability(self, ability):
#     def share_color(self, other):
#     def has_color(self, color):
#     def is_color(self, color):
#     def is_monocolored(self):
#     def is_multicolored(self):
#     def is_colorless(self):
#     def has_subtype(self, subtype):
#     def exile(self):
#     def targets(self):
#     def target_legality(self):
#     def has_valid_target(self):
#     def choose_targets(self):
#     def change_zone(self, target_zone, from_top=0, shuffle=True,
#                     status_mod=None, modi_func=None):
# 
# Path: MTG/zone.py
# class ZoneType(Enum):
# class Zone():
# class Battlefield(Zone):
# class Stack(Zone):
# class Hand(Zone):
# class Graveyard(Zone):
# class Exile(Zone):
# class Library(Zone):
#     LIBRARY = 0
#     HAND = 1
#     BATTLEFIELD = 2
#     GRAVEYARD = 3
#     STACK = 4
#     EXILE = 5
# def str_to_zone_type(z):
#     def __init__(self, controller=None, elements: list=None):
#     def __repr__(self):
#     def __str__(self):
#     def __len__(self):
#     def __bool__(self):
#     def __getitem__(self, pos):
#     def isEmpty(self):
#     def add(self, obj):
#     def remove(self, obj):
#     def filter(self, characteristics=None, filter_func=None):
#     def count(self, characteristics=None, filter_func=None):
#     def get_card_by_name(self, name):
#     def pop(self, pos=-1):
#     def clear(self):
#     def add(self, obj, status_mod=None, modi_func=None):
#     def shuffle(self):
#     def __init__(self, controller=None, elements: list=None):
#     def add(self, obj, from_top=0, shuffle=True):
#     def remove(self, obj, shuffle=False):


# Path: MTG/play.py
import inspect
from MTG import gameobject
from MTG import zone


class Play(gameobject.GameObject):
    """
    Represents an ability or spell on the stack.

    Spells: card = original card
    Abilities: source = card that owns this ability
    """

    # TODO: unify this with gameObject init (particularly with targetting)
    def __init__(self, apply_func, apply_condition=lambda: True, 
                 card=None, source=None, name=None,
                 targets_chosen=None, target_criterias=None, is_mana_ability=False):
        
        # TODO: okay this is really ugly and bug-prone.
        # Think about how to fix this initialization.
        if card:
            controller = card.controller
        elif source:
            controller = source.controller
        else:
            controller = None


        super().__init__(zone=controller.stack if controller else None,