# -*- coding:utf-8 -*-
# title           :平行宇宙的地球们
# description     :平行宇宙的地球们
# author          :Python超人
# date            :2023-07-01
# link            :https://gitcode.net/pythoncr/
# python_version  :3.8
# ==============================================================================
import random
import sys

from bodies import Earth
from common.consts import SECONDS_PER_DAY
from sim_scenes.func import ursina_run
from simulators.ursina.entities.sphere_sky import SphereSky


def sim_show():
    """
    使用模拟器（慢）
    @return:
    """
    bodies = []
    num = 2
    r = 30000
    for x in range(-num, num):
        for y in range(-num, num):
            for z in range(-num, num):
                earth = Earth(init_position=[r * x, r * y, r * z],
                              rotation_speed=0,
                              rotate_angle=0,
                              init_velocity=[0, 0, 0], size_scale=1, ignore_mass=True)
                # earth.rotation_speed /= 50  # 地球的转速降低50倍
                bodies.append(earth)

    # 使用 ursina 查看的运行效果
    # 常用快捷键： P：运行和暂停  O：重新开始  I：显示天体轨迹
    # position = 左-右+、上+下-、前+后-
    ursina_run(bodies, SECONDS_PER_DAY,
               position=(0, 0, -r * num * 6), show_grid=False
               )


def ursina_show():
    """
    直接使用 ursina 模拟，无需考虑万有引力（性能高）
    @return:
    """
    from ursina import Ursina, Entity, EditorCamera, camera
    app = Ursina()
    # 黑色背景的宇宙背景
    SphereSky(texture='../../textures/bg_black.png')

    # 控制地球的数量，这里的 num 不代表数量
    num = 5
    num_x = num * 2
    num_y = num
    num_z = num * 2
    # 地球数量 = 2 * num_x * num_y * num_z
    print("地球数量：", 2 * num_x * num_y * num_z)

    # 控制运行的速度
    run_speed = 0.1
    # 控制地球之间的距离
    spacing = 20

    def create_earth(x, y, z, aligned=False):
        """
        在指定的三维坐标上创建地球
        @param x:
        @param y:
        @param z:
        @param aligned: 排列整齐
        @return:
        """
        if aligned:
            xr, yr, zr = 0, 0, 0
        else:
            xr, yr, zr = random.randint(20, 800) / 100, random.randint(20, 800) / 100, random.randint(20, 800) / 100

        earth = Entity(model="sphere", texture='../../textures/earth1.jpg',
                       x=x * spacing * 2 + xr, y=y * spacing + yr, z=z * spacing * 2 + zr, scale=3)
        earth.name = "%s:%s:%s" % (x, y, z)

        def update():
            def inner(s, b):
                if not hasattr(s, "initial_y"):
                    # 随机生成一个地球自转的初始量
                    s.initial_y = random.randint(20, 200) / 100 * run_speed
                # 地球进行自转
                s.rotation_y -= s.initial_y

            return inner(earth, y)

        earth.update = update

    for x in range(-num_x, num_x):
        for y in range(-num_y, num_y):
            for z in range(-num_z, num_z):
                create_earth(x, y, z)

    ed = EditorCamera()
    camera.fov = 80
    ed.position = [0, 0, spacing / 2]

    # 控制摄像机三个维度的移动方向，值为 1 和 -1
    camera.x_d = 1
    camera.y_d = 1
    camera.z_d = 1

    def camera_update():
        # 更新摄像机位置和角度

        # 控制摄像机旋转（以y、z轴进行旋转）
        camera.world_rotation_y += 0.005
        camera.world_rotation_z += 0.001

        # 控制摄像机来回移动（x为左右移动，y为上下移动）
        camera.x += ((random.randint(100, 300) - 100) / 2500 * run_speed) * camera.x_d
        camera.y += ((random.randint(100, 300) - 100) / 5000 * run_speed) * camera.y_d
        # camera.z += ((random.randint(100, 300) - 100) / 3000 * run_speed) * camera.z_d
        range_val = 5
        if camera.x > range_val:
            camera.x_d = -1
        elif camera.x < -range_val:
            camera.x_d = 1
        if camera.y > range_val:
            camera.y_d = -1
        elif camera.y < -range_val:
            camera.y_d = 1
        # if camera.z > range_val:
        #     camera.z_d = -1
        # elif camera.z < -range_val:
        #     camera.z_d = 1

    sys.modules["__main__"].update = camera_update
    app.run()


if __name__ == '__main__':
    """
    平行宇宙的地球们
    """
    # sim_show()
    ursina_show()
