"""
Mountains Random Walk

Idea and algorithm from:
https://hackernoon.com/a-procedural-landscape-experiment-4efe1826906f

If Python and arcadeplus are installed, this example can be run from the command line with:
python -m arcadeplus.examples.mountains_random_walk
"""

# Library imports
import arcadeplus
import random

SCREEN_WIDTH = 1200
SCREEN_HEIGHT = 700
SCREEN_TITLE = "Mountains Random Walk Example"


def create_mountain_range(height_min, height_max, color_start, color_end):

    shape_list = arcadeplus.ShapeElementList()

    step_max = 1.5
    step_change = 0.5

    height = random.random() * height_max
    slope = (random.random() * step_max * 2) - step_max

    line_point_list = []
    line_color_list = []

    for x in range(SCREEN_WIDTH):
        height += slope
        slope += (random.random() * step_change * 2) - step_change

        if slope > step_max:
            slope = step_max
        elif slope < -step_max:
            slope = -step_max

        if height > height_max:
            height = height_max
            slope *= -1
        elif height < height_min:
            height = height_min
            slope *= -1

        line_point_list.extend(((x, height), (x, 0)))
        line_color_list.extend((color_start, color_end))

    lines = arcadeplus.create_lines_with_colors(line_point_list, line_color_list)
    shape_list.append(lines)

    return shape_list


def create_line_strip():
    shape_list = arcadeplus.ShapeElementList()

    colors = (
        arcadeplus.color.RED,
        arcadeplus.color.BLACK,
        arcadeplus.color.GREEN,
        arcadeplus.color.BLACK,
        arcadeplus.color.BLUE,
        arcadeplus.color.BLACK
    )
    line_strip = arcadeplus.create_lines_with_colors(
        ([10, 10], [500, 10],
         [10, 250], [500, 250],
         [10, 500], [500, 500]),
        colors,
        line_width=4)

    shape_list.append(line_strip)

    return shape_list


class MyGame(arcadeplus.Window):
    """
    Main application class.
    """

    def __init__(self, width, height, title):
        super().__init__(width, height, title)

        self.mountains = None

        arcadeplus.set_background_color(arcadeplus.color.WHITE)

    def setup(self):
        """
        This, and any function with the arcadeplus.decorator.init decorator,
        is run automatically on start-up.
        """

        self.mountains = []

        background = arcadeplus.ShapeElementList()

        points = (0, 0), (SCREEN_WIDTH, 0), (SCREEN_WIDTH, SCREEN_HEIGHT), (0, SCREEN_HEIGHT)
        colors = (arcadeplus.color.SKY_BLUE, arcadeplus.color.SKY_BLUE, arcadeplus.color.BLUE, arcadeplus.color.BLUE)
        rect = arcadeplus.create_rectangles_filled_with_colors(points, colors)

        background.append(rect)
        self.mountains.append(background)

        for i in range(1, 4):
            color_start = (i * 10, i * 30, i * 10)
            color_end = (i * 20, i * 40, i * 20)
            min_y = 0 + 70 * (3 - i)
            max_y = 120 + 70 * (3 - i)
            mountain_range = create_mountain_range(min_y, max_y, color_start, color_end)
            self.mountains.append(mountain_range)

    def on_draw(self):
        """
        This is called every time we need to update our screen. About 60
        times per second.

        Just draw things in this function, don't update where they are.
        """
        # Call our drawing functions.

        arcadeplus.start_render()
        for mountain_range in self.mountains:
            mountain_range.draw()


def main():
    """ Main method """
    window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
    window.setup()
    arcadeplus.run()


if __name__ == "__main__":
    main()
