# -*- coding: utf-8 -*-
"""船（白いさざなみ）と航空路線（ネイビーを明るくした青）を、ネイビー→青→白の一つの階調でまとめる。"""
import sys, os
import numpy as np, pandas as pd
sys.path.insert(0, '/home/claude/forest'); sys.path.insert(0, '/home/claude/quakes'); sys.path.insert(0, '/home/claude/transport')
import forest1 as F, sylvania as S, q1 as Q
from PIL import Image, ImageDraw
from scipy import ndimage
import flights as FL
OUT = '/home/claude/transport/out'
NAVY = np.array(F.r.col(12, 270, 16), np.float32); LANDC = np.array(F.r.col(18, 268, 14), np.float32)
WHITE = np.array([247, 247, 250], np.float32)
BLUE = np.array(F.r.col(62, 262, 34), np.float32)     # ネイビーの明度を上げ、彩度も少し足した青
G = np.load('/home/claude/transport/data/ship_0p02.npy'); SHIP = np.zeros((9000, 18000), np.float32); SHIP[250:8750, :] = G[:, :18000]
BBOX = (-180, -90, 180, 90); SIZE = (1350, 675); SS = 3

def ramp(t):
    """0=ネイビー, 0.6=青, 1=白。Lab で折れ線補間。"""
    t = np.clip(np.asarray(t, np.float32), 0, 1)[..., None]
    a, b, c = S.to_lab(NAVY), S.to_lab(BLUE), S.to_lab(WHITE)
    lab = np.where(t < 0.6, a + (b - a) * (t / 0.6), b + (c - b) * ((t - 0.6) / 0.4))
    flat = lab.reshape(-1, 3); rgb = np.array([S.from_lab(v) for v in flat], np.float32)
    return rgb.reshape(lab.shape)

def scene(lon0):
    sc = F.Scene(BBOX, (SIZE[0]*SS, SIZE[1]*SS), proj='pc', pad=0.0, lon0=lon0)
    lon, lat, ok = sc.lonlat_grid()
    land = F.sample(Q.land_grid_all().astype(np.float32), lon, lat, ok) > 0.5
    return sc, lon, lat, ok, land

def ships_layer(lon, lat, ok, land, floor=1000, lo_t=0.55, hi_t=1.0, ref_log10=7.5, nearest=True):
    """さざなみ: 0.02° の粒をそのまま最近傍で拾い、log で白へ。"""
    v = np.where(SHIP >= floor, SHIP, 0); v = np.clip(np.log1p(v) / np.log1p(10**ref_log10), 0, 1).astype(np.float32)
    lon2 = (lon % 360) - 180; vv = np.roll(v, -v.shape[1]//2, axis=1)
    fr = F.sample(vv, lon2, lat, ok) if nearest else F.sample_bilinear(vv, lon2, lat, ok)
    fr = np.where(land, 0, fr)
    t = np.where(fr > 0, lo_t + (hi_t - lo_t) * fr, 0)       # 階調の位置
    a = np.where(fr > 0, np.clip(fr * 1.6, 0, 1), 0)         # 弱い所は透ける
    return t, a

def flights_layer(sc, lon0, cls, t_by_cls):
    W, H = sc.W, sc.H; layers = []
    def px(la, lo):
        lo = ((lo - lon0 + 180) % 360) - 180
        return (lo*111320.0 - sc.cx)/sc.s + W/2, H/2 - (la*111320.0 - sc.cy)/sc.s
    for (lo_, hi_, wpx, al), tt in zip(cls, t_by_cls):
        sel = FL.pairs[(FL.pairs.n >= lo_) & (FL.pairs.n < hi_)]
        cv = Image.new('L', (W, H), 0); d = ImageDraw.Draw(cv)
        for a, b in zip(sel.a, sel.b):
            g = FL.gc(FL.pos.at[a,'lat'], FL.pos.at[a,'lon'], FL.pos.at[b,'lat'], FL.pos.at[b,'lon'])
            if g is None: continue
            x, y = px(g[0], g[1]); pts = list(zip(x, y)); run = [pts[0]]
            for p0, p1 in zip(pts[:-1], pts[1:]):
                if abs(p1[0]-p0[0]) > W/2:
                    if len(run) > 1: d.line(run, fill=255, width=max(1, int(round(wpx*SS))))
                    run = [p1]
                else: run.append(p1)
            if len(run) > 1: d.line(run, fill=255, width=max(1, int(round(wpx*SS))))
        layers.append((np.array(cv).astype(np.float32)/255*al, tt))
    return layers

def build(name, lon0=0.0, ships=True, flights=True, cls=None, t_by_cls=None, ship_kw={}):
    sc, lon, lat, ok, land = scene(lon0); W, H = sc.W, sc.H
    out = np.zeros((H, W, 3), np.float32); out[:] = NAVY; out[land] = LANDC
    if flights:
        cls = cls or [(1,2,0.35,0.35),(2,4,0.5,0.5),(4,8,0.7,0.7),(8,999,1.0,0.85)]
        t_by_cls = t_by_cls or [0.35, 0.42, 0.5, 0.6]
        for a, tt in flights_layer(sc, lon0, cls, t_by_cls):
            col = ramp(np.array([tt]))[0]; out = out*(1-a[...,None]) + col*a[...,None]
    if ships:
        t, a = ships_layer(lon, lat, ok, land, **ship_kw)
        col = ramp(t); out = out*(1-a[...,None]) + col*a[...,None]
    im = Image.fromarray(np.clip(out,0,255).astype(np.uint8)).resize(SIZE, Image.LANCZOS)
    im.save(f'{OUT}/{name}.png'); print(name, flush=True); return im

if __name__ == '__main__':
    ims = [build('C1', flights=False),            # 船だけ（白いさざなみ）
           build('C2', ships=False),              # 航空だけ（青）
           build('C3'),                           # 両方
           build('C4', lon0=160)]                 # 両方、太平洋を中央に
    s = Image.new('RGB', (1350, 685*4), (200,200,200))
    for i, im in enumerate(ims): s.paste(im, (0, i*685))
    s.save(f'{OUT}/Csheet.png')
