"""Tutorial 07 — Building a Forest Scene

50m × 50m autumn forest, 5 leaf colors, 60 trees, ortho + perspective imaging."""

import less
import numpy as np

# ── Create a scene ──────────────────────────────────────��────────
scene = less.Scene()
scene.size = 50.0

scene.terrain = less.Terrain(property=less.Lambertian(reflectance=0.08))
scene.illumination = less.Illumination(source=less.Sun(zenith=40, azimuth=150), atmosphere=less.NoAtmosphere())

# ── 5 Autumn Leaf Colors ─────────────────────────────────────────
autumn_colors = {
    "golden_yellow": less.Prospect(cab=10, car=20, canth=0,  cbrown=0.15, cw=0.012, cm=0.009, N=1.8),
    "orange":        less.Prospect(cab=3,  car=12, canth=8,  cbrown=0.25, cw=0.010, cm=0.008, N=1.7),
    "red":           less.Prospect(cab=2,  car=5,  canth=30, cbrown=0.15, cw=0.011, cm=0.009, N=1.8),
    "dark_red":      less.Prospect(cab=1,  car=3,  canth=40, cbrown=0.35, cw=0.009, cm=0.010, N=2.0),
    "yellow_green":  less.Prospect(cab=20, car=15, canth=0,  cbrown=0.05, cw=0.013, cm=0.009, N=1.7),
}

mesh_path = less.examples.asset_path("FREX.obj")
rng = np.random.RandomState(42)

for color_name, leaf_prop in autumn_colors.items():
    tree = less.Object(f"ash_{color_name}", mesh=mesh_path)
    tree.set_property("leaves", leaf_prop)
    tree.set_property("stem_branch", less.Lambertian(reflectance=0.06))

    n = 12 + rng.randint(-2, 3)
    px = rng.uniform(2, 48, n)
    py = rng.uniform(2, 48, n)
    positions = np.column_stack([px, py, np.zeros(n)])
    scales    = rng.uniform(0.6, 1.5, n)
    rotations = rng.uniform(0, 360, n)
    scene.add(tree, positions=positions, scales=scales, rotations=rotations)
lai = scene.measure(less.LAIMeasurement())
print(f"Scene LAI = {lai:.2f}")

lai_detail = scene.measure(less.LAIMeasurement(group_by='component'))
print(f"  Leaves: {lai_detail.get('leaves', 0):.2f}")
print(f"  Stems and branches: {lai_detail.get('stem_branch', 0):.2f}")

# ── Orthophoto RGB ─────────────────────────────────────────────
sensor_ortho = less.OpticalImager(
    less.Orthographic(image_size=512),
    bands=[630, 532, 465],
    quality=128,
)
image = scene.simulate(sensor_ortho)
image.save("07_autumn_forest_nadir.png")

# ──Perspective camera────────────────────────────────────────────
sensor_persp = less.OpticalImager(
    less.Perspective(
        resolution=1024, fov=35,
        position=(25, 60, 45),
        target=(25, 25, 6),
    ),
    bands=[630, 532, 465],
    quality=128,
)
image_persp = scene.simulate(sensor_persp)
image_persp.save("07_autumn_forest_perspective.png")

print("Tutorial 07 Complete!")
