code:
"""
    01shop.rpy

    This file adds a Shop class and a menu to interact with it.

    Shop requires a name and a dictionary of items. It may also take in a custom depreciation amount, custom buy flavor
    text, custom sell flavor text, and a custom screen variable.
    The dictionary of items is expected to be a dictionary of dictionaries. Each item dictionary in items should include
    a 'cost' and 'description' field.

    Once a shop is created, it is meant to be used with ShopMenu via call. ShopMenu requires the shop, the players
    inventory, and the player's money. The shop menu may be called from whereever you would like.
    Ex:
        call ShopMenu(shopA, inventory, money)

"""

init -900 python in shop:

    #NOTE: Custom exception:
    class ItemError(Exception):
        """Item specified was not found"""
        pass

    # Shop will be an object.
    class Shop():

        # __init__ is a special keyword for the constructor method.
        def __init__ (self, name, items, depreciation = 0.7, **kwargs):
            self._items = items
            self._depreciation = depreciation
            self._buyText = kwargs.pop('buyText', "Choose an item to buy:")
            self._sellText = kwargs.pop('sellText', "Choose an item to sell:")
            self._screen = kwargs.pop('screen', "choice")

        # Public Methods
        def ListItems(self):
            """
            Prints a list of items in the shop and their cost via renpy.say
            """
            shopList = "Item:            Cost:             Description:\n"
            for item in self._items:
                shopList + item + "      " + self._items[item]["cost"] + "      " + self._items[item]["description"] + "\n"
            renpy.say(shopList)

        def BuyMenu(self, pInv, pMoney):
            """
            Displays a menu with all buyable items.

            Parameters:
                pInv (list):        a given inventory as a list
                pMoney (int):       given value to test 'cost' against

            Returns:
                bool: True until player chooses to exit the menu
            """

            # display_menu requires a list of tuples. Storing these in entries.
            entries = []

            # Using the key from _items as the text for the menu button
            for key in self._items.keys():
                item = key + ": " + self._items[key]["cost"]
                entries.append((item, key))

            # Add an option to buy nothing
            entries.append(("Don't buy anything.","exit"))

            # Displays how much money the player has
            renpy.say("You have: " + pMoney)
            # Displays flavor text for the menu
            title = self._buyText
            renpy.say(title, interact=False)
            # Choice holds the result of the player's choice. Allows a screen to be given.
            choice = renpy.display_menu(entries, interact=True, screen=self._screen)

            # Attempts to buy an item. Only returns false if player chooses to exit the menu
            if (choice != "exit"):
                if (_buyItem(pInv, pMoney, choice)):
                    renpy.say("You bought: " + choice)
                    return True
                else:
                    renpy.say("You do not have enough money for that item.")
                    return True
            else:
                return False

        def SellMenu(self, pInv, pMoney, **kwargs):
            """
            Displays a menu with all sellable items.

            Parameters:
                pInv (list):        a given inventory as a list
                pMoney (int):       given value to add the 'cost' to

            Returns:
                bool: True until player chooses to exit the menu
            """

            # display_menu requires a list of tuples. Storing these in entries.
            entries = []
            # Strips duplicates from the player's inventory list
            itemList = list(set(pInv))

            # Displays each item in the player's inventory and its cost
            for item in itemList:
                price = item + ": " + self._items[item]["cost"]*self._depreciation
                entries.append((item, key))

            # Add an option to sell nothing
            entries.append(("Don't sell anything.","exit"))

            # Displays how much money the player has
            renpy.say("You have: " + pMoney)
            # Displays flavor text for the menu
            title = self._sellText
            renpy.say(title, interact=False)
            # Choice holds the result of the player's choice. Allows a screen to be given.
            choice = renpy.display_menu(entries, interact=True, screen=self._screen)

            # Attempts to sell an item. Only returns false if player chooses to exit the menu
            if (choice != "exit"):
                try:
                    _sellItem(pInv, pMoney, choice)
                    renpy.say("You sold a " + choice)
                    return True
                except(ItemError):
                    renpy.say("Item not found!n\Please report this error the developer.")
                    return True
            else:
                return False

        # Private Methods
        def _buyItem(self, pInv, pMoney, item):
            """
            Attempts to buy a selected item.

            Parameters:
                pInv (list):    a given inventory as a list
                pMoney (int):   given value to test 'cost' against
                item (string):  name of the item to attempt

            Returns:
                bool: True if Item was bought
            """
            if (checkMoney(pMoney, item)):
                _takeMoney(pMoney, self._items[item]["cost"])
                _addItem(pInv, item)
                return True
            else:
                return False

        def _sellItem(self, pInv, pMoney, item):
            """
            Sells a given item from the given inventory.

            Parameters:
                pInv:       a given inventory as a list
                pMoney:     a value to add the 'cost' to
                item:       a given item to be removed from the list
            """

            try:
                _removeItem(pInv, item)
                _addMoney(pMoney, self._items[item]["cost"]*self._depreciation)
            except ItemError:
                raise ItemError

        def _removeItem(self, pInv, item):
            """
            Removes a given item from a given inventory.

            Parameters:
                pInv:       a given inventory as a list
                item:       a given item to be removed from the list
            """
            try:
                pInv.remove(item)
            except ValueError:
                raise ItemError

        def _addItem(self, pInv, item):
            """
            Adds a given item to a given inventory.

            Parameters:
                pInv:       a given inventory as a list
                item:       a given item to be added to the list
            """
            pInv.append(item)
            return

        def _checkMoney(self, pMoney, amount):
            """
            Checks if value a is enough to cover value b.
            """
            return (pMoney >= amount)

        def _addMoney(self, pMoney, amount):
            """
            Adds value b to value a
            """
            pMoney += amount
            return

        def _takeMoney(self, pMoney, amount):
            """
            Removes value b from value a.
            """
            pMoney -= amount
            return

menu ShopMenu(shop, pInv, pMoney):
    "Welcome to [shop.name]!\nChoose what you would like to do:"

    "Buy Items":
        while shop.SellMenu(pInv, pMoney):
            pass
        call ShopMenu(shop, pInv, pMoney)

    "Sell Items":
        while shop.BuyMenu(pInv, pMoney):
            pass
        call ShopMenu(shop, pInv, pMoney)

    "Leave":
        return


code:
"""
    01time.rpy
"""

# TODO: Better name for 'time' is needed. https://gitgud.io/pervy-rogues/renpy-trainer/-/issues/101#note_253447
init -900 python in trainer:
    """
    By: Kelfistan
    Date: 06/20/2022
    Arbitrary variables for in game timer for trainer games filled with period, intervals, and action points
    Creates pacing for the game and other game mechanics
    """

    # Stock time periods based on real life. but you can set the time periods to whatever meaning calendar you want
    year = 0
    week = 0
    month = 0
    MONTHS = ["jan", "feb", "mar","apr","may","jun","jul","aug","sep","oct","nov","dec"]
    DAYS = ["mon", "tue", "wed", "thu","fri","sat","sun"]
    TIME_OF_DAY = ["morning", "afternoon", "evening", "night"]

    DEFAULT_NMBR_OF_ACTIONS = 100

    today = 0
    current_tod = 0 # current time of day
    current_actions = 100

    def current_time_of_day():
        """ Getter method for time_of_day"""
        global TIME_OF_DAY
        global current_tod
        return TIME_OF_DAY[current_tod % len(TIME_OF_DAY)]

    def actions_left():
        """ Getter method for the time increments used"""
        global current_actions
        return current_actions

    def current_day():
        """ Getter methods for your calendric day"""
        global today
        global DAYS
        return DAYS[today % len(DAYS)]

    def advance_time(day = 0, time_of_day = 0, actions = 0):
        """ Used for changing the time periods; preferably one variable at a time - see below methods """
        if day > 0:
            advance_day(day)
        if time_of_day >0:
            advance_TOD(time_of_day)
        if actions > 0:
            advance_actions(actions)

    def advance_actions(actions):
        """ method to increment actions; proceeds to increment others periods of time with a cascading effect"""
        global current_actions
        current_actions = current_actions - actions
        if current_actions <= 0:
            advance_TOD(1)

    def advance_TOD(time_of_day):
        """ method to increment time of day; has a cascading effect with incrementing date"""
        global current_tod
        global current_actions
        if (current_tod % len(TIME_OF_DAY) == len(TIME_OF_DAY) - 1):
            advance_day(1)
        else:
            current_tod = current_tod + time_of_day
            current_actions = DEFAULT_NMBR_OF_ACTIONS

    def advance_day(day):
        """ method to increment the date and reset all the necessary variable for start of day """
        global today
        global current_tod
        global current_actions
        today = today + day
        current_tod = 0
        current_actions = DEFAULT_NMBR_OF_ACTIONS

repo_name: Kelfistan/renpy

license: unknown


code:
"""
    01traits.rpy
"""
init offset = -1000

python early in trainer:

    trainer = {}
    trainer.traits={}

    class Trait(object):
        """ Traits are great a way for customization of characters """
        def __init__(self, name, description = None, attributes = None, **properties):
            self.name
            self.description = description
            self.attributes = attributes

    """
        trait #starts a block { Foo:
            "Some Description"

            attribute { Bar:
                min 100
                max 750
                bonus 350
                modifier 0.85
            }

            attribute { Baz:
                min 200
                modifier 1.20
            }
        }
        ('Foo', "Some Description", attributes = [{'attr' = 'Bar', 'min' = 100}])
    """

    def execute_trait(parsed_trait):
        '''
            Stores trait in trainer.traits
        '''
        if parsed_trait['name'] not in trainer.traits:
            trainer.traits[parsed_trait['name']] = Trait(*parsed_trait)
        else:
            config.log("(%t) is already parsed!" % parsed_trait['name'])
        return

    def lint_trait():
        # TODO: Check whether certain params are allowed
        pass

    def parse_trait_attribute(ll):
        '''
        Parses an Attribute block of a character trait.
        '''
        attr = {}
        attr['attr'] = ll.require(ll.name)
        ll.require(":")
        ll.expect_eol()

        while ll.advance():
            if ll.keyword("bonus"):
                attr['bonus'] = ll.float()

            elif ll.keyword("max"):
                attr['max'] = ll.integer()

            elif ll.keyword("min"):
                attr['min'] = ll.integer()

            elif ll.keyword("modifier"):
                attr['mod'] = ll.float()

            else:
                break

        return attr

    def parse_trait(l):
        '''
        Parses a Trainer Character Trait.
        '''
        attributes = []

        # Requires format: `trait foo:`
        name = l.require(l.name)
        l.require(":")
        l.expect_eol()

        description = l.string()
        if description is not None:
            l.expect_eol()
        l.advance()

        ll = l.subblock_lexer()
        ll.advance()

        while not ll.eob:
        # Checks all attribute subblocks.
            if ll.keyword('attribute'):
                attributes.append(parse_trait_attribute(ll))
                ll.advance()

        return (name, description, attributes)

    renpy.register_statement("trait", parse = parse_trait, execute = execute_trait, lint = lint_trait, block = True)


code:
python early:
    config.name = "Renpy_Trainer"
    config.version = "1.0"

init -500 python:
    import os
    import sys
    import logging

    # absolute path to the game directory, which is formatted according
    # to the conventions of the local OS
    gamedir = os.path.normpath(config.gamedir)

    # required to make the above work with with RenPy:
    config.reject_backslash = False

    # setting the window on center
    # useful if game is launched in the window mode
    os.environ['SDL_VIDEO_CENTERED'] = '1'

    # sys.setdefaultencoding('utf-8')

    # Game may bug out on saving, in such case, comment should be removed
    # config.use_cpickle = False

    # enable logging via the 'logging' module
    logging.basicConfig(level=logging.DEBUG, format='%(levelname)-8s %(name)-15s %(message)s')
    # renpy_log = logging.getLogger(" ".join([config.name, config.version]))
    renpy_log = logging.getLogger()
    logging_file = logging.FileHandler(os.path.join(gamedir, "renpy_log.txt"))
    logging_file.setLevel(logging.DEBUG)
    renpy_log.addHandler(logging_file)
    renpy_log.critical("\n--- launch game ---")
    fm = logging.Formatter('%(levelname)-8s %(name)-15s %(message)s')
    logging_file.setFormatter(fm)
    del fm
    renpy_log.info(" ".join([config.name, config.version]) + " Game directory: %s" % gamedir)

label error:
    "HELLO THERE"
    "An ERROR HAS OCCURRED"
    "RETURNING TO UNIVERSITY SQUARE"
    jump university_square

label no_event_label(label_name):
    "Sorry, but there is no label with that name"
    "Please check [label_name]"
    "Check if you have a label or just misspelled it"
    "This is return to the previous label now"
    $ renpy.log("Sorry, but there is no label with that name")
    $ renpy.log(f"Please check {label_name}")
    $ renpy.log("Check if you have a label or just misspelled it")
    $ renpy.log("This is return to the previous label now")
    return


code:
style trainer_wardrobe_frame:
    background Solid("#cec7c7a0")
    ypadding 10
    xpadding 20

style trainer_rgb_frame:
    background Solid("#cec7c7a0")
    xpadding 20

style trainer_location_frame:
    background Solid("#cec7c7a0")

style trainer_game_choices_frame:
    # maximum (500, 450)
    xmaximum 500
    background Solid("#ffffffb5")

style trainer_game_choices_viewport:
    spacing 10

"""

    SCREEN BASE LOCATIONS

    ALL ANCHORS ARE SET TO (0.0, 1.0) -- Bottom Left Point

"""

define wardrobe_align_pos = (0.085, 0.8)
define rgb_align_pos = (0.4, 0.2)
define location_align_pos = (0.8, 0.1)

# define game_choices_pos = (0.085, 0.8)
# define prime_actor_pos = (0.4, 0.8)
# define second_actor_pos = (0.7, 0.4)
# define bg_actor_pos = (0.3, 0.35)
define character_love_pos = (0.0, 0.0)
define character_lust_pos = (0.0, 0.2)
define character_obedience_pos = (0.0, 0.4)
define character_inhibition_pos = (0.0, 0.6)
define change_relationship_pos = (0.2, 0.0)
define change_own_petname_pos = (0.5, 0.0)
define change_mc_petname_pos = (0.5, 0.5)
define bio_pos = (0.0, 0.8)
define last_phrase_pos = (0.5, 0.8)
# define move_to_pos = (0.0, 0.0)
# define locations_contains_pos = (0.0, 0.4)
# define characters_pos = (0.4, 0.0)
# define party_pos = (0.4, 0.2)
# define location_pos = (0.4, 0.25)

screen ui_testing2():

    #use game_choices(game_choices_pos)
    #use prime_actor(prime_actor_pos)
    #use second_actor(second_actor_pos)
    #use bg_actor(bg_actor_pos)
    use character_love(character_love_pos)
    use character_lust(character_lust_pos)
    use character_obedience(character_obedience_pos)
    use character_inhibition(character_inhibition_pos)
    use change_relationship(change_relationship_pos)
    use change_own_petname(change_own_petname_pos)
    use change_mc_petname(change_mc_petname_pos)
    use bio(bio_pos)
    use last_phrase(last_phrase_pos)
    #use move_to(move_to_pos)
    #use locations_contains(locations_contains_pos)
    #use characters(characters_pos)
    #use party(party_pos)
    #use location(location_pos)
### 5 last screens above are for party system test

screen game_choices(align_pos):
    style_prefix "trainer_game_choices"

    frame align align_pos:
        use vertical_menu(
            _type = "text",
            commands = ["Talk to Rogue", "Go somewhere", "Wait", "Tan", "Date"],
            show_scroll = None,
            size = (350, 300))

screen prime_actor(align_pos):
    frame pos align_pos anchor (0.0, 1.0) maximum (500, 500):
        hbox:
            vbox:
                window background Frame("speech_bubble.png",10,10)
                textbutton "test1" action Jump("test_start") background Frame("xmen_background.png") xfill True
                textbutton "test2" action Jump("test_start") background Frame("xmen_background.png") xfill True
                textbutton "test3" action Jump("test_start") background Frame("xmen_background.png") xfill True
            add "rogue_sprite.png" #background Solid("#FFFFF")
            add "rogue_sprite.png"
            add "rogue_sprite.png"

screen second_actor(align_pos):
    pass

screen bg_actor(align_pos):
    pass

'''
Relationship test screens below
'''

screen character_love(align_pos):
    frame pos align_pos maximum (500, 500):
        vbox:
            textbutton "Set to 0" action SetField(rogue, "love", 0)
            textbutton "Set to 100" action SetField(rogue, "love", 100)
            textbutton "Set to 200" action SetField(rogue, "love", 200)
            text "Love = [rogue.love]"

screen character_lust(align_pos):
    frame pos align_pos maximum (500, 500):
        vbox:
            textbutton "Set to 0" action SetField(rogue, "lust", 0)
            textbutton "Set to 100" action SetField(rogue, "lust", 100)
            textbutton "Set to 200" action SetField(rogue, "lust", 200)
            text "Lust = [rogue.lust]"

screen character_obedience(align_pos):
    frame pos align_pos maximum (500, 500):
        vbox:
            textbutton "Set to 0" action SetField(rogue, "obedience", 0)
            textbutton "Set to 100" action SetField(rogue, "obedience", 100)
            textbutton "Set to 200" action SetField(rogue, "obedience", 200)
            text "Obedience = [rogue.obedience]"

screen character_inhibition(align_pos):
    frame pos align_pos maximum (500, 500):
        vbox:
            textbutton "Set to 0" action SetField(rogue, "inhibition", 0)
            textbutton "Set to 100" action SetField(rogue, "inhibition", 100)
            textbutton "Set to 200" action SetField(rogue, "inhibition", 200)
            text "Inhibition = [rogue.inhibition]"

screen change_relationship(align_pos):
    frame pos align_pos maximum (1500, 500):
        vbox:
            textbutton "Be my girlfriend" action Function(trainer.change_relationship, rogue, mc, "girlfriend")
            textbutton "Be my wife" action Function(trainer.change_relationship, rogue, mc, "wife")
            textbutton "Be my sex friend" action Function(trainer.change_relationship, rogue, mc, "sex friend")
            textbutton "Be my slave" action Function(trainer.change_relationship, rogue, mc, "slave")

screen change_own_petname(align_pos):
    frame pos align_pos maximum (1500, 500):
        vbox:
            textbutton "I want to call you by your name" action Function(trainer.reset_own_petname, rogue, mc)
            textbutton "I want to call you honey" action Function(trainer.change_own_petname, rogue, mc, "honey")
            textbutton "I want to call you baby girl" action Function(trainer.change_own_petname, rogue, mc, "baby girl")
            textbutton "I want to call you whore" action Function(trainer.change_own_petname, rogue, mc, "whore")
            textbutton "I want to call you slave" action Function(trainer.change_own_petname, rogue, mc, "slave")

screen change_mc_petname(align_pos):
    frame pos align_pos maximum (1500, 500):
        vbox:
            textbutton "I want you to call me by my name" action Function(trainer.reset_others_petname, rogue, mc)
            textbutton "I want you to call me daddy" action Function(trainer.change_others_petname, rogue, mc, "daddy")
            textbutton "I want you to call me sir" action Function(trainer.change_others_petname, rogue, mc, "sir")
            textbutton "I want you to call me master" action Function(trainer.change_others_petname, rogue, mc, "master")

screen bio(align_pos):
    frame pos align_pos maximum (1500, 500):
        vbox:
            text "My name is [rogue._real_name]"
            text "I call you {}".format(trainer.give_contains(rogue.relationships, mc)["petname"])
            text "You call me {}".format(trainer.give_contains(mc.relationships, rogue)["petname"])
            if trainer.give_contains(rogue.relationships, mc)["relationship"] != "":
                text "Im am your {}".format(trainer.give_contains(rogue.relationships, mc)["relationship"])

screen last_phrase(align_pos):
    frame pos align_pos maximum (500, 500):
        vbox:
            text "Rogue says:"
            text "[last_phrase_text]"

'''
Party test screens below
'''

screen move_to(align_pos):
    frame pos align_pos maximum (800, 500):
        vbox:
            textbutton "Move to [my_room.name]" action Function(trainer.move_party_to_room, my_room, "mc_text")
            textbutton "Move to [rogue_room.name]" action Function(trainer.move_party_to_room, rogue_room, "rogue_text")
            textbutton "Move to [emma_room.name]" action Function(trainer.move_party_to_room, emma_room, "emma_text")
            textbutton "Move to [kitty_room.name]" action Function(trainer.move_party_to_room, kitty_room, "kitty_text")
            textbutton "Move to [university_square.name]" action Function(trainer.move_party_to_room, university_square, "square_text")

screen locations_contains(align_pos):
    frame pos align_pos maximum (1920, 500):
        vbox:
            text "[my_room.name]: " + mc_text
            null height 20
            text "[rogue_room.name]: " + rogue_text
            null height 20
            text "[emma_room.name]: " + emma_text
            null height 20
            text "[kitty_room.name]: " + kitty_text
            null height 20
            text "[university_square.name]: " + square_text

screen characters(align_pos):
    frame pos align_pos maximum (500, 500):
        vbox:
            hbox:
                text "[rogue._real_name]"
                null width 20
                textbutton "+" action Function(add_to_party, rogue)
                null width 20
                textbutton "-" action Function(remove_from_party, rogue)
            null height 10
            hbox:
                text "[emma._real_name]"
                null width 20
                textbutton "+" action Function(add_to_party, emma)
                null width 20
                textbutton "-" action Function(remove_from_party, emma)
            null height 10
            hbox:
                text "[kitty._real_name]"
                null width 20
                textbutton "+" action Function(add_to_party, kitty)
                null width 20
                textbutton "-" action Function(remove_from_party, kitty)

screen party(align_pos):
    frame pos align_pos maximum (1000, 500):
        text "My party: " + party_text

screen location(align_pos):
    frame pos align_pos maximum (500, 500):
        text "Current location is: " + current_location.name

# screen character_info(align_pos):
#     frame pos align_pos anchor (0.0, 1.0) maximum (500, 500):
#         hbox:
#             vbox:
#                 window background Frame("speech_bubble.png",10,10)
#                 textbutton "test1" action Jump("test_start") background Frame("xmen_background.png") xfill True
#                 textbutton "test2" action Jump("test_start") background Frame("xmen_background.png") xfill True
#                 textbutton "test3" action Jump("test_start") background Frame("xmen_background.png") xfill True
#             add "rogue_sprite.png" #background Solid("#FFFFF")
#             add "rogue_sprite.png"
#             add "rogue_sprite.png"

screen ui_testing():

    use wardrobe_menu(wardrobe_align_pos)

    use location_menu(location_align_pos)

    use rgb_menu(rgb_align_pos)

screen wardrobe_menu(align_pos = (0,0)):

    style_prefix "trainer_wardrobe"

    frame align align_pos:
        has vbox:

            hbox xalign 1.0:
                textbutton "Colour" action Jump("test_start")
                textbutton "Wardrobe" action Jump("test_start")
                textbutton "Outfits" action Jump("test_start")

            hbox xalign 1.0:
                textbutton "Preset" action Jump("test_start") background Frame("button_background.png")
                textbutton "Save" action Jump("test_start") background Frame("button_background.png")
                textbutton "Load" action Jump("test_start") background Frame("button_background.png")

            viewport maximum (203*6, 190*2):

                draggable True
                mousewheel True
                scrollbars "horizontal"

                hbox:
                    use vertical_menu(commands = (1,2,3,546,657,32))
                    use vertical_menu(commands = (1,2,3,546,657,32))
                    use vertical_menu(commands = (1,2,3,546,657,32))
                    use vertical_menu(commands = (1,2,3,546,657,32))
                    use vertical_menu(commands = (1,2,3,546,657,32))
                    use vertical_menu(commands = (1,2,3,546,657,32))
                    use vertical_menu(commands = (1,2,3,546,657,32))
                    use vertical_menu(commands = (1,2,3,546,657,32))
                    use vertical_menu(commands = (1,2,3,546,657,32))

screen location_menu(align_pos = (0,0)):
    style_prefix "trainer_location"

    use movable_frame(align_pos):
        vbox:
            text "Location Menu"
            use vertical_menu("text", commands = ["Room", "Heaven", "Hell"], size = (300,200), show_scroll = None)

screen rgb_menu(align_pos = (0,0)):
    style_prefix "trainer_rgb"
    frame align align_pos:

        has vbox

        text "RGB" align (0.5,0.5)
        hbox ymaximum 250 spacing 5:
            vbox:
                text [str(random_ass_val1)]
                vbar value VariableValue("random_ass_val1", 20) thumb "vscrollbar.png" base_bar "scroll3_gradient.png"
            vbox:
                text [str(random_ass_val2)]
                vbar value VariableValue("random_ass_val2", 20) thumb "vscrollbar.png" base_bar "scroll3_gradient.png"
            vbox:
                text [str(random_ass_val3)]
                vbar value VariableValue("random_ass_val3", 20) thumb "vscrollbar.png" base_bar "scroll3_gradient.png"


code:
"""
This script overrides 'label start' to run the testing suite.
"""

#NOTE: from Kakimito: uncomment first 4 lines and comment everything else in screen ui_testing2 if you want everything back like in 185-UI

init -1 python:

    not_initiated = True
    #TODO: move character declaration to other file. maybe trainer_options.rpy
    square_text = ""
    mc = Character("MC (me)",kind = trn)
    mc_text = ""
    rogue = Character("Rogue",kind = trn)
    rogue_room = trainer.Location("Rogue's Room", ["Girl's Dormitory"])
    rogue_text = ""
    emma = Character("Emma",kind = trn)
    emma_room = trainer.Location("Emma's Room", ["Girl's Dormitory"])
    emma_text = ""
    kitty = Character("Kitty",kind = trn)
    kitty_room = trainer.Location("Kitty's Room", ["Girl's Dormitory"])
    kitty_text = ""

    my_party = [mc]
    party_text = ""
    current_location = my_room
    previous_text = str("mc_text")

    def refresh_room(room, text_var):
        names_list = []
        for x in range(len(room.people)):
            names_list.append(room.people[x]._real_name)
        setattr(store, text_var, ", ".join(names_list))

    def set_defaults():
        if store.not_initiated:
            for x in store.my_party:
                store.current_location.add_person(x)
            refresh_room(store.my_room, "mc_text")
            rogue_room.add_person(rogue)
            refresh_room(store.rogue_room, "rogue_text")
            emma_room.add_person(emma)
            refresh_room(store.emma_room, "emma_text")
            kitty_room.add_person(kitty)
            refresh_room(store.kitty_room, "kitty_text")
            refresh_room(store.university_square, "square_text")
            refresh_party()
            store.not_initiated = False

    def refresh_party():
        names_list = []
        for x in range(len(my_party)):
            names_list.append(my_party[x]._real_name)
        store.party_text = ", ".join(names_list)

    def add_to_party(person):
        if person in store.current_location.people:
            if person not in my_party:
                my_party.append(person)
                refresh_party()

    def remove_from_party(person):
        if person in my_party:
            my_party.remove(person)
            refresh_party()

    characters_list = [mc,rogue,emma,kitty]
    def initialize_relationships():
        for char in characters_list:
            for other_char in characters_list:
                if char != other_char:
                    char.relationships.append([other_char,{"relationship":"","petname":other_char._real_name}])

init -1:
    # label_overrides redirects a label: https://www.renpy.org/doc/html/config.html?highlight=override#var-config.label_overrides
    $ config.label_overrides["start"] = "test_start"

    $ test = DynamicEntry("Test Menu", kind="menu")
    # Add testing menus:
    $ trainer.menu_list.append(DynamicEntry(name="Image Test", label="imageTest", kind="entry", parents=[test]))
    $ trainer.menu_list.append(DynamicEntry(name="Location Test", label="university_square", kind="entry", parents=[test]))
    $ trainer.menu_list.append(DynamicEntry(name="Game Menu Test", label="game_menu", kind="entry", parents=[test]))

define layered = Character("Layered Test")
image university_square = Frame("backgrounds/university_square_day.jpg", 1280, 1024)
define random_ass_val1 = 0
define random_ass_val2 = 0
define random_ass_val3 = 0

#NOTE: Do not change test_start. Add to 'test_menus' or change test variable.
label test_start:
    $ initialize_relationships()
    $ set_defaults()
    "Label test_start"
    jump test_menu

label test_menu(dynamic_entry=test):
    "test_menu"
    # call screen trainer_choice(dynamic_entry)
    scene university_square
    # call screen ui_testing()
    call screen ui_testing2()

    jump test_menu

label imageTest:
    show layered

    "This is the layeredimage system test."

    # Base layered
    layered bare "I should be bare."
    layered "I should even be bare down there!"
    show layered -bare
    layered none "Not any more though."
    show layered -none
    layered "I prefer to wear gloves even when naked."
    # show layered up <- this didnt work
    layered "If this worked, the test should end now and return you to the menu."

    jump game_menu

# TODO: REWRITE THIS PIECE OF SHIT MENU!
label testing_menu(interactable):
    python:
        global event_handler
        menu_options = []
        interactable_tag = ""
        # TODO: Get definitive tag name
        try:
            interactable_tag = interactable.label
        except AttributeError:
            interactable_tag = interactable.get_name()
        # Updates current events belonging to interactable object and pulls any interactable menu events
        # event_handler.update_events(interactable_tag)
        # menu_options.extend(event_handler.get_interact_events("all"))
        # menu_options.extend(event_handler.get_interact_events(interactable_tag))
        # Extends menu based on whether in a location or interacting with an actor
        if isinstance(interactable, Location):
            menu_options.extend(location_menu(interactable))
            previous_location = current_location
            current_location = interactable_tag
        elif isinstance(interactable, Actor):
            menu_options.extend(character_menu(interactable))
        # Shows current time and day
    python in game_clock:
        curr_time = current_time_of_day()
        curr_actions = actions_left()
        day = current_day()
        renpy.say("", f'Day: {day}, t.o.d {curr_time}, actions left {str(curr_actions)}.')

    # Plays any events that triggered with entering a location or talking to a character
    # $ event_handler.play_triggered_events()
    # Shows the list of menu items layed out via prior processes; decision is the menu choice
    $ decision = renpy.display_menu(menu_options)

    ################### Take Action #############################
    if decision[1] == "event":
        $ play_event(decision[0])
    elif decision[1] == "talk_to" or decision[1] == "sex":
        $ renpy_log.debug("TALK TO DECISION")
        call game_menu(decision[0])
    elif decision[1] == "location":
        $ renpy_log.debug("LOCATION DECISION")
        $ game_clock.advance_time(actions = 5)
        jump expression decision[0]
    else:
        jump error
    ##############################################################

    # Finished event and default back to the interactable again
    $ renpy.jump(current_location)


code:
label add_location_events:
    add event wait:
        interactable
        event_tags all
        trigger "True"
        incr_time 23

    add event talk:
        interactable
        event_tags all
        trigger "True"
        button_text "Text/Talk"

    add event list_to_lecture:
        interactable
        event_tags classroom
        button_text "Take the morning class"
        trigger "show_time == 'day'"
        incr_time 10

    add event list_to_lecture_evening:
        interactable
        event_tags classroom
        button_text "Take the afternoon class"
        trigger "show_time == 'evening'"
        incr_time 50

    add event some_other_event:
        interactable
        event_tags university_square
        trigger "True"
        incr_time 25

    add event train:
        interactable
        event_tags danger_room
        trigger "show_time !== 'night'"
        incr_time 6
    return

label wait:
    "You wait awhile but you get bored and leave"
    return

label talk:
    "You want to talk to...."
    menu:
        "Rogue":
            "Hello Sugar"
        "Kitty":
            "Like Hi"
        "Emma":
            "Good morning Love"
    return

label list_to_lecture:
    "You listen to the morning lecture"
    "*************Show random list of random lecture dialogue here!**********"
    # random_lecture = renpy.random.choice(morning_lectures)
    return

label list_to_lecture_evening:
    "You listen to the evening lecture"
    "*************Show random list of random lecture dialogue here!**********"
    # random_lecture = renpy.random.choic(afternoon_lectures)
    return

label train:
    "You start training"
    "*************Show random list of random training dialogue here!**********"
    # random_training_dialogue = renpy.random.choice(training dialogue)
    return

label some_other_event:
    "YOUR THE BEST WHATEVER NEVER GONNA BE THE VERY BEST!"
    return


code:
label test_flags:
    # Call renpy.call(test_flags) in renpy console
    $print(trainer.add_flag(rogue, "AAAAAAAAAAAa"))
    $print(trainer.add_flag(rogue, "b"))
    $print(trainer.is_flag_present(rogue, 1))
    $print(trainer.is_flag_present(rogue, "b"))


code:
label test_inventory:
    # Use renpy.call(test_inventory) in renpy console
    $renpy.log(trainer.add_items(rogue, ['item1', 'item2']))
    $renpy.log(trainer.get_items(rogue))
    $renpy.log(trainer.add_items(my_room, 'item3'))
    $renpy.log(trainer.move_items(my_room, rogue, 'item3'))
    $renpy.log(trainer.remove_items(rogue, ['item1', 'item2', 'item4']))
    $renpy.log(trainer.has_items(rogue, ['item1']))
    $renpy.log(trainer.has_items(rogue, ['item3']))
    $renpy.log(trainer.get_items(rogue))


code:
# Image system based on LayeredImage()

# Attempting to define a layeredImage here.
# TODO: Transition this to a statement equivalannt.
# TODO: Tie into Girl().
layeredimage layered:
    #image_format "character/test/{image}.png"

    # body > head (eyes > mouth > eyebrows > hair) > breasts > pubes > arms
    attribute body null
    group body if_any "bare" auto variant "bare":
        anchor (0.0,0.0)
        zoom 0.75
        attribute none default

    group body if_not "bare" auto variant "hairy":
        anchor (0.0,0.0)
        zoom 0.75
        attribute none default

    group head auto prefix "head":
        anchor (0.0,0.0)
        zoom 0.75
        attribute base default

    group brows auto prefix "brows":
        anchor (0.0,0.0)
        zoom 0.75
        attribute normal default

    group eyes auto prefix "eyes":
        anchor (0.0,0.0)
        zoom 0.75
        attribute normal default

    group mouth auto prefix "mouth":
        anchor (0.0,0.0)
        zoom 0.75
        attribute normal default

    group hair auto:
        anchor (0.0,0.0)
        zoom 0.75
        attribute normal default

#    attribute pubic null #IDEA: May not work, possible bug
#    group pubic auto

    attribute arms null
    group arms if_any "up" auto variant "up":
        anchor (0.0,0.0)
        zoom 0.75
        attribute collargloves default

    group arms if_not "up" auto variant "normal":
        anchor (0.0,0.0)
        zoom 0.75
        attribute collargloves default

    # Chest layer must happen after arms to avoid bad overlapping.
    group chest auto:
        anchor (0.0,0.0)
        zoom 0.75
        attribute none default

    # bra > panty > inner > lower > dress > outer > neck > wrist
#    group bra auto

    group panty auto

    group lower auto variant "down"

    group lower auto variant "wet"

    group hose auto

    group inner auto

    group inner auto variant "up"

    group bottom auto

    group bottom auto variant "down"

    attribute dress null  #IDEA: See above
    group dress auto

    group outer auto

    group outer auto variant "up"

#IDEA: Check about separating arms and accessories.
    #group neck auto

    #group wrist auto

    group overlay auto multiple

    group overlay auto variant "pussy" multiple

    group overlay auto variant "face" multiple


code:
# define location_list = ["My Room", "Girl's Dormitory", "University Square", "Classroom", "The Danger Room", "The Showers", "The Pool", "Xavier's Study"]
# # Should location objects be the same as the labels?
init -2 python:
    from store.trainer import Location

    my_room = Location("My Room", ["Classroom", "University Square", "Classroom", "The Showers"])
    classroom = Location("Classroom", ["University Square", "The Pool"])
    university_square = Location("University Square", ["The Pool", "Classroom" ], day_cycle=True, variant = ["halloween"])
    the_pool = Location("The Pool", ["University Square", "Classroom"], day_cycle=True)
    the_danger_room = Location("The Danger Room", ["University Square"])
    the_showers = Location("The Showers", ["University Square"])
    xaviers_study = Location("Xavier's Study", ["University Square"])
    girls_dormitory = Location("Girl's Dormitory", ["University Square"])

    previous_location = "university_square"
    current_location = "university_square"
    variable_not_in_flag = True
    travel_mode = False
    show_time = "day"

label change_time:
    $ print("Playing event!?")
    $ global show_time
    if show_time == "night":
        $ show_time = "day"
        return
    if show_time == "evening":
        $ show_time = "night"
        return
    if show_time == "day":
        $ show_time = "evening"
        return

label my_room:
    scene expression "bg university_square_{}".format(show_time)
    "You are in your room. What would you like to do?"
    call game_menu(my_room)

label university_square:
    #TODO: Must fix background image sizing to match screen size --BGs must be at the top of the label block!
    # scene expression "bg university_square_{}".format(time_of_day)
    scene expression "bg university_square_{}".format(show_time)
    "You are in the University Square. What would you like to do?"
    call game_menu(university_square)

label classroom:
    scene expression "bg university_square_{}".format(show_time)
    "You sit down at the desk. What would you like to do?"
    call game_menu(classroom)

label the_pool:
    scene expression "bg the_pool_{}".format(show_time)
    "You're at the pool. What would you like to do?"
    call game_menu(the_pool)

label the_danger_room:
    "This is the Danger room. What would you like to do?"
    call game_menu(the_danger_room)

label the_showers:
    "You're in the showers. What would you like to do?"
    call game_menu(the_showers)

label xaviers_study:
    "You're at the door. What would you like to do?"
    call game_menu(xaviers_study)

# TODO: Fix multiple personnel room to be flexible
# label girls_dormitory:
#     "Which room would you would to go to?"
#     call game_menu(girls_dormitory)


code:
################################################################################
## Initialization
################################################################################

## The init offset statement causes the initialization statements in this file
## to run before init statements in any other file.
init offset = -2

## Calling gui.init resets the styles to sensible default values, and sets the
## width and height of the game.
init python:
    gui.init(1920, 1080)

################################################################################
## GUI Configuration Variables
################################################################################

## Colors ######################################################################
##
## The colors of text in the interface.

## An accent color used throughout the interface to label and highlight text.
define gui.accent_color = '#66cc00'

## The color used for a text button when it is neither selected nor hovered.
define gui.idle_color = '#888888'

## The small color is used for small text, which needs to be brighter/darker to
## achieve the same effect.
define gui.idle_small_color = '#aaaaaa'

## The color that is used for buttons and bars that are hovered.
define gui.hover_color = '#a3e066'

## The color used for a text button when it is selected but not focused. A
## button is selected if it is the current screen or preference value.
define gui.selected_color = '#ffffff'

## The color used for a text button when it cannot be selected.
define gui.insensitive_color = '#8888887f'

## Colors used for the portions of bars that are not filled in. These are not
## used directly, but are used when re-generating bar image files.
define gui.muted_color = '#285100'
define gui.hover_muted_color = '#3d7a00'

## The colors used for dialogue and menu choice text.
define gui.text_color = '#ffffff'
define gui.interface_text_color = '#ffffff'

## Fonts and Font Sizes ########################################################

## The font used for in-game text.
define gui.text_font = "CRIMFBRG.ttf"

## The font used for character names.
define gui.name_text_font = "CRIMFBRG.ttf"

## The font used for out-of-game text.
define gui.interface_text_font = "CRIMFBRG.ttf"

## The size of normal dialogue text.
define gui.text_size = 33

## The size of character names.
define gui.name_text_size = 45

## The size of text in the game's user interface.
define gui.interface_text_size = 33

## The size of labels in the game's user interface.
define gui.label_text_size = 36

## The size of text on the notify screen.
define gui.notify_text_size = 24

## The size of the game's title.
define gui.title_text_size = 75

## Main and Game Menus #########################################################

## The images used for the main and game menus.
define gui.main_menu_background = "gui/main_menu.png"
define gui.game_menu_background = "gui/game_menu.png"

## Dialogue ####################################################################
##
## These variables control how dialogue is displayed on the screen one line at a
## time.

## The height of the textbox containing dialogue.
define gui.textbox_height = 278

## The placement of the textbox vertically on the screen. 0.0 is the top, 0.5 is
## center, and 1.0 is the bottom.
define gui.textbox_yalign = 1.0

## The placement of the speaking character's name, relative to the textbox.
## These can be a whole number of pixels from the left or top, or 0.5 to center.
define gui.name_xpos = 360
define gui.name_ypos = 0

## The horizontal alignment of the character's name. This can be 0.0 for left-
## aligned, 0.5 for centered, and 1.0 for right-aligned.
define gui.name_xalign = 0.0

## The width, height, and borders of the box containing the character's name, or
## None to automatically size it.
define gui.namebox_width = None
define gui.namebox_height = None

## The borders of the box containing the character's name, in left, top, right,
## bottom order.
define gui.namebox_borders = Borders(5, 5, 5, 5)

## If True, the background of the namebox will be tiled, if False, the
## background of the namebox will be scaled.
define gui.namebox_tile = False

## The placement of dialogue relative to the textbox. These can be a whole
## number of pixels relative to the left or top side of the textbox, or 0.5 to
## center.
define gui.dialogue_xpos = 402
define gui.dialogue_ypos = 75

## The maximum width of dialogue text, in pixels.
define gui.dialogue_width = 1116

## The horizontal alignment of the dialogue text. This can be 0.0 for left-
## aligned, 0.5 for centered, and 1.0 for right-aligned.
define gui.dialogue_text_xalign = 0.0

## Buttons #####################################################################
##
## These variables, along with the image files in gui/button, control aspects of
## how buttons are displayed.

## The width and height of a button, in pixels. If None, Ren'Py computes a size.
define gui.button_width = None
define gui.button_height = None

## The borders on each side of the button, in left, top, right, bottom order.
define gui.button_borders = Borders(6, 6, 6, 6)

## If True, the background image will be tiled. If False, the background image
## will be linearly scaled.
define gui.button_tile = False

## The font used by the button.
define gui.button_text_font = gui.interface_text_font

## The size of the text used by the button.
define gui.button_text_size = gui.interface_text_size

## The color of button text in various states.
define gui.button_text_idle_color = gui.idle_color
define gui.button_text_hover_color = gui.hover_color
define gui.button_text_selected_color = gui.selected_color
define gui.button_text_insensitive_color = gui.insensitive_color

## The horizontal alignment of the button text. (0.0 is left, 0.5 is center, 1.0
## is right).
define gui.button_text_xalign = 0.0

## These variables override settings for different kinds of buttons. Please see
## the gui documentation for the kinds of buttons available, and what each is
## used for.
##
## These customizations are used by the default interface:

define gui.radio_button_borders = Borders(27, 6, 6, 6)

define gui.check_button_borders = Borders(27, 6, 6, 6)

define gui.confirm_button_text_xalign = 0.5

define gui.page_button_borders = Borders(15, 6, 15, 6)

define gui.quick_button_borders = Borders(15, 6, 15, 0)
define gui.quick_button_text_size = 21
define gui.quick_button_text_idle_color = gui.idle_small_color
define gui.quick_button_text_selected_color = gui.accent_color

## You can also add your own customizations, by adding properly-named variables.
## For example, you can uncomment the following line to set the width of a
## navigation button.

# define gui.navigation_button_width = 250

## Choice Buttons ##############################################################
##
## Choice buttons are used in the in-game menus.

define gui.choice_button_width = 1185
define gui.choice_button_height = None
define gui.choice_button_tile = False
define gui.choice_button_borders = Borders(150, 8, 150, 8)
define gui.choice_button_text_font = gui.text_font
define gui.choice_button_text_size = gui.text_size
define gui.choice_button_text_xalign = 0.5
define gui.choice_button_text_idle_color = "#cccccc"
define gui.choice_button_text_hover_color = "#ffffff"
define gui.choice_button_text_insensitive_color = "#444444"

## File Slot Buttons ###########################################################
##
## A file slot button is a special kind of button. It contains a thumbnail
## image, and text describing the contents of the save slot. A save slot uses
## image files in gui/button, like the other kinds of buttons.

## The save slot button.
define gui.slot_button_width = 414
define gui.slot_button_height = 309
define gui.slot_button_borders = Borders(15, 15, 15, 15)
define gui.slot_button_text_size = 21
define gui.slot_button_text_xalign = 0.5
define gui.slot_button_text_idle_color = gui.idle_small_color
define gui.slot_button_text_selected_idle_color = gui.selected_color
define gui.slot_button_text_selected_hover_color = gui.hover_color

## The width and height of thumbnails used by the save slots.
define config.thumbnail_width = 384
define config.thumbnail_height = 216

## The number of columns and rows in the grid of save slots.
define gui.file_slot_cols = 3
define gui.file_slot_rows = 2

## Positioning and Spacing #####################################################
##
## These variables control the positioning and spacing of various user interface
## elements.

## The position of the left side of the navigation buttons, relative to the left
## side of the screen.
define gui.navigation_xpos = 60

## The vertical position of the skip indicator.
define gui.skip_ypos = 15

## The vertical position of the notify screen.
define gui.notify_ypos = 68

## The spacing between menu choices.
define gui.choice_spacing = 33

## Buttons in the navigation section of the main and game menus.
define gui.navigation_spacing = 6

## Controls the amount of spacing between preferences.
define gui.pref_spacing = 15

## Controls the amount of spacing between preference buttons.
define gui.pref_button_spacing = 0

## The spacing between file page buttons.
define gui.page_spacing = 0

## The spacing between file slots.
define gui.slot_spacing = 15

## The position of the main menu text.
define gui.main_menu_text_xalign = 1.0

## Frames ######################################################################
##
## These variables control the look of frames that can contain user interface
## components when an overlay or window is not present.

## Generic frames.
define gui.frame_borders = Borders(6, 6, 6, 6)

## The frame that is used as part of the confirm screen.
define gui.confirm_frame_borders = Borders(60, 60, 60, 60)

## The frame that is used as part of the skip screen.
define gui.skip_frame_borders = Borders(24, 8, 75, 8)

## The frame that is used as part of the notify screen.
define gui.notify_frame_borders = Borders(24, 8, 60, 8)

## Should frame backgrounds be tiled?
define gui.frame_tile = False

## Bars, Scrollbars, and Sliders ###############################################
##
## These control the look and size of bars, scrollbars, and sliders.
##
## The default GUI only uses sliders and vertical scrollbars. All of the other
## bars are only used in creator-written screens.

## The height of horizontal bars, scrollbars, and sliders. The width of vertical
## bars, scrollbars, and sliders.
define gui.bar_size = 38
define gui.scrollbar_size = 18
define gui.slider_size = 38

## True if bar images should be tiled. False if they should be linearly scaled.
define gui.bar_tile = False
define gui.scrollbar_tile = False
define gui.slider_tile = False

## Horizontal borders.
define gui.bar_borders = Borders(6, 6, 6, 6)
define gui.scrollbar_borders = Borders(6, 6, 6, 6)
define gui.slider_borders = Borders(6, 6, 6, 6)

## Vertical borders.
define gui.vbar_borders = Borders(6, 6, 6, 6)
define gui.vscrollbar_borders = Borders(6, 6, 6, 6)
define gui.vslider_borders = Borders(6, 6, 6, 6)

## What to do with unscrollable scrollbars in the gui. "hide" hides them, while
## None shows them.
define gui.unscrollable = "hide"

## History #####################################################################
##
## The history screen displays dialogue that the player has already dismissed.

## The number of blocks of dialogue history Ren'Py will keep.
define config.history_length = 250

## The height of a history screen entry, or None to make the height variable at
## the cost of performance.
define gui.history_height = 210

## The position, width, and alignment of the label giving the name of the
## speaking character.
define gui.history_name_xpos = 233
define gui.history_name_ypos = 0
define gui.history_name_width = 233
define gui.history_name_xalign = 1.0

## The position, width, and alignment of the dialogue text.
define gui.history_text_xpos = 255
define gui.history_text_ypos = 3
define gui.history_text_width = 1110
define gui.history_text_xalign = 0.0

## NVL-Mode ####################################################################
##
## The NVL-mode screen displays the dialogue spoken by NVL-mode characters.

## The borders of the background of the NVL-mode background window.
define gui.nvl_borders = Borders(0, 15, 0, 30)

## The maximum number of NVL-mode entries Ren'Py will display. When more entries
## than this are to be show, the oldest entry will be removed.
define gui.nvl_list_length = 6

## The height of an NVL-mode entry. Set this to None to have the entries
## dynamically adjust height.
define gui.nvl_height = 173

## The spacing between NVL-mode entries when gui.nvl_height is None, and between
## NVL-mode entries and an NVL-mode menu.
define gui.nvl_spacing = 15

## The position, width, and alignment of the label giving the name of the
## speaking character.
define gui.nvl_name_xpos = 645
define gui.nvl_name_ypos = 0
define gui.nvl_name_width = 225
define gui.nvl_name_xalign = 1.0

## The position, width, and alignment of the dialogue text.
define gui.nvl_text_xpos = 675
define gui.nvl_text_ypos = 12
define gui.nvl_text_width = 885
define gui.nvl_text_xalign = 0.0

## The position, width, and alignment of nvl_thought text (the text said by the
## nvl_narrator character.)
define gui.nvl_thought_xpos = 360
define gui.nvl_thought_ypos = 0
define gui.nvl_thought_width = 1170
define gui.nvl_thought_xalign = 0.0

## The position of nvl menu_buttons.
define gui.nvl_button_xpos = 675
define gui.nvl_button_xalign = 0.0

## Localization ################################################################

## This controls where a line break is permitted. The default is suitable
## for most languages. A list of available values can be found at https://
## www.renpy.org/doc/html/style_properties.html#style-property-language

define gui.language = "unicode"

################################################################################
## Mobile devices
################################################################################

init python:

    ## This increases the size of the quick buttons to make them easier to touch
    ## on tablets and phones.
    @gui.variant
    def touch():

        gui.quick_button_borders = Borders(60, 21, 60, 0)

    ## This changes the size and spacing of various GUI elements to ensure they
    ## are easily visible on phones.
    @gui.variant
    def small():

        ## Font sizes.
        gui.text_size = 45
        gui.name_text_size = 54
        gui.notify_text_size = 38
        gui.interface_text_size = 45
        gui.button_text_size = 45
        gui.label_text_size = 51

        ## Adjust the location of the textbox.
        gui.textbox_height = 360
        gui.name_xpos = 120
        gui.dialogue_xpos = 135
        gui.dialogue_width = 1650

        ## Change the size and spacing of various things.
        gui.slider_size = 54

        gui.choice_button_width = 1860
        gui.choice_button_text_size = 45

        gui.navigation_spacing = 30
        gui.pref_button_spacing = 15

        gui.history_height = 285
        gui.history_text_width = 1035

        gui.quick_button_text_size = 30

        ## File button layout.
        gui.file_slot_cols = 2
        gui.file_slot_rows = 2

        ## NVL-mode.
        gui.nvl_height = 255

        gui.nvl_name_width = 458
        gui.nvl_name_xpos = 488

        gui.nvl_text_width = 1373
        gui.nvl_text_xpos = 518
        gui.nvl_text_ypos = 8

        gui.nvl_thought_width = 1860
        gui.nvl_thought_xpos = 30

        gui.nvl_button_width = 1860
        gui.nvl_button_xpos = 30


code:
## This file contains options that can be changed to customize your game.
##
## Lines beginning with two '#' marks are comments, and you shouldn't uncomment
## them. Lines beginning with a single '#' mark are commented-out code, and you
## may want to uncomment them when appropriate.

## Basics ######################################################################

## A human-readable name of the game. This is used to set the default window
## title, and shows up in the interface and error reports.
##
## The _() surrounding the string marks it as eligible for translation.

define config.name = _("renpy-trainer")

## Determines if the title given above is shown on the main menu screen. Set
## this to False to hide the title.

define gui.show_name = True

## The version of the game.

define config.version = "0.1"

## Text that is placed on the game's about screen. Place the text between the
## triple-quotes, and leave a blank line between paragraphs.

define gui.about = _p("""
""")

## A short name for the game used for executables and directories in the built
## distribution. This must be ASCII-only, and must not contain spaces, colons,
## or semicolons.

define build.name = "renpy-trainer"

## Sounds and music ############################################################

## These three variables control, among other things, which mixers are shown
## to the player by default. Setting one of these to False will hide the
## appropriate mixer.

define config.has_sound = True
define config.has_music = True
define config.has_voice = True

## To allow the user to play a test sound on the sound or voice channel,
## uncomment a line below and use it to set a sample sound to play.

# define config.sample_sound = "sample-sound.ogg"
# define config.sample_voice = "sample-voice.ogg"

## Uncomment the following line to set an audio file that will be played while
## the player is at the main menu. This file will continue playing into the
## game, until it is stopped or another file is played.

# define config.main_menu_music = "main-menu-theme.ogg"

## Transitions #################################################################
##
## These variables set transitions that are used when certain events occur.
## Each variable should be set to a transition, or None to indicate that no
## transition should be used.

## Entering or exiting the game menu.

define config.enter_transition = dissolve
define config.exit_transition = dissolve

## Between screens of the game menu.

define config.intra_transition = dissolve

## A transition that is used after a game has been loaded.

define config.after_load_transition = None

## Used when entering the main menu after the game has ended.

define config.end_game_transition = None

## A variable to set the transition used when the game starts does not exist.
## Instead, use a with statement after showing the initial scene.

## Window management ###########################################################
##
## This controls when the dialogue window is displayed. If "show", it is always
## displayed. If "hide", it is only displayed when dialogue is present. If
## "auto", the window is hidden before scene statements and shown again once
## dialogue is displayed.
##
## After the game has started, this can be changed with the "window show",
## "window hide", and "window auto" statements.

define config.window = "hide"

## Transitions used to show and hide the dialogue window

define config.window_show_transition = Dissolve(.2)
define config.window_hide_transition = Dissolve(.2)

## Preference defaults #########################################################

## Controls the default text speed. The default, 0, is infinite, while any other
## number is the number of characters per second to type out.

default preferences.text_cps = 0

## The default auto-forward delay. Larger numbers lead to longer waits, with 0
## to 30 being the valid range.

default preferences.afm_time = 15

## Save directory ##############################################################
##
## Controls the platform-specific place Ren'Py will place the save files for
## this game. The save files will be placed in:
##
## Windows: %APPDATA\RenPy\<config.save_directory>
##
## Macintosh: $HOME/Library/RenPy/<config.save_directory>
##
## Linux: $HOME/.renpy/<config.save_directory>
##
## This generally should not be changed, and if it is, should always be a
## literal string, not an expression.

define config.save_directory = "renpy-trainer"

## Icon ########################################################################
##
## The icon displayed on the taskbar or dock.

define config.window_icon = "gui/window_icon.png"

## Build configuration #########################################################
##
## This section controls how Ren'Py turns your project into distribution files.

init python:

    ## The following functions take file patterns. File patterns are case-
    ## insensitive, and matched against the path relative to the base directory,
    ## with and without a leading /. If multiple patterns match, the first is
    ## used.
    ##
    ## In a pattern:
    ##
    ## / is the directory separator.
    ##
    ## * matches all characters, except the directory separator.
    ##
    ## ** matches all characters, including the directory separator.
    ##
    ## For example, "*.txt" matches txt files in the base directory, "game/
    ## **.ogg" matches ogg files in the game directory or any of its
    ## subdirectories, and "**.psd" matches psd files anywhere in the project.

    ## Classify files as None to exclude them from the built distributions.

    build.classify('**~', None)
    build.classify('**.bak', None)
    build.classify('**/.**', None)
    build.classify('**/#**', None)
    build.classify('**/thumbs.db', None)

    ## To archive files, classify them as 'archive'.

    # build.classify('game/**.png', 'archive')
    # build.classify('game/**.jpg', 'archive')

    ## Files matching documentation patterns are duplicated in a mac app build,
    ## so they appear in both the app and the zip file.

    build.documentation('*.html')
    build.documentation('*.txt')

## A Google Play license key is required to download expansion files and perform
## in-app purchases. It can be found on the "Services & APIs" page of the Google
## Play developer console.

# define build.google_play_key = "..."

## The username and project name associated with an itch.io project, separated
## by a slash.

# define build.itch_project = "renpytom/test-project"