import {eq_vect, eq_color, resolve_color, get_turtle_color, set_turtle_color, turtle_radius, turtle_angle, turn_to_rad, turtle_init, command_to_state, background_color, rotate, last} from "./turtle_geometry.js"

function states_to_call (prev, curr) {
  const calls = []
  // whose state should we use?
  // pen states will only differ on more than one property
  // if we use `loadstate`
  // my sense is `prev`, but that may change
  if (prev.pendown && !eq_vect(prev.position, curr.position)) {
    calls.push(["line", prev.position[0], prev.position[1], curr.position[0], curr.position[1]])
  }
  if (!eq_color(curr.pencolor, prev.pencolor)) {
    calls.push(["stroke", ...resolve_color(curr.pencolor)])
  }
  if (curr.penwidth !== prev.penwidth) {
    calls.push(["strokeWeight", curr.penwidth])
  }
  return calls
}

function p5_call_root () {
  return [
    ["background", ...resolve_color(background_color)],
    ["push"],
    ["rotate", Math.PI],
    ["scale", -1, 1],
    ["stroke", ...resolve_color(turtle_init.pencolor)],
  ]
}

function p5_render_turtle (state, calls) {
  if (!state.visible) return
  calls.push(["push"])
  const [r, g, b, a] = get_turtle_color()
  calls.push(["fill", r, g, b, a])
  const {heading, pencolor, position: [x, y], pendown, penwidth} = state
  const origin = [0, turtle_radius]
  const [x1, y1] = origin
  const [x2, y2] = rotate(origin, turtle_angle)
  const [x3, y3] = rotate(origin, -turtle_angle)
  calls.push(["translate", x, y])
  // need negative turtle rotation with the other p5 translations
  calls.push(["rotate", -turn_to_rad(heading)])
  calls.push(["noStroke"])
  calls.push(["beginShape"])
  calls.push(["vertex", x1, y1])
  calls.push(["vertex", x2, y2])
  calls.push(["vertex", x3, y3])
  calls.push(["endShape"])
  calls.push(["strokeWeight", penwidth])
  calls.push(["stroke", ...resolve_color(pencolor)])
  if (pendown) calls.push(["line", 0, 0, x1, y1])
  calls.push(["pop"])
  return calls
}

export function p5 (commands) {
  const all_states = {}
  for (const command of commands) {
    const [turtle_id, _, this_command] = command
    let stack = all_states[turtle_id]
    if (!stack) {
      const new_stack = [turtle_init]
      all_states[turtle_id] = new_stack
      stack = new_stack
    }
    let prev_state = last(all_states[turtle_id])
    const new_state = command_to_state(prev_state, this_command)
    all_states[turtle_id].push(new_state)
  }
  const [r, g, b, _] = resolve_color(background_color)  
  if ((r + g + b)/3 > 128) set_turtle_color([0, 0, 0, 150])
  const p5_calls = [...p5_call_root()]
  for (const states of Object.values(all_states)) {
    // console.log(states)
    for (let i = 1; i < states.length; ++i) {
      const prev = states[i - 1]
      const curr = states[i]
      const calls = states_to_call(prev, curr)
      for (const call of calls) {
        p5_calls.push(call)
      }
    }
    p5_calls[0] = ["background", ...resolve_color(background_color)]
    p5_render_turtle(states[states.length - 1], p5_calls)
  }
  p5_calls.push(["pop"])
  return p5_calls
}


