export const turtle_init = {
  position: [0, 0],
  heading: 0,
  pendown: true,
  pencolor: "white",
  penwidth: 1,
  visible: true
}

export const turtle_radius = 20

export const turtle_angle = 0.385

let turtle_color = [255, 255, 255, 150]

export function get_turtle_color () {
  return turtle_color
}

export function set_turtle_color (new_color) {
  turtle_color = new_color
}

export const colors = {
	black: [0, 0, 0, 255],
	silver: [192, 192, 192, 255],
	gray: [128, 128, 128, 255],
	grey: [128, 128, 128, 255],
	white: [255, 255, 255, 255],
	maroon: [128, 0, 0, 255],
	red: [255, 0, 0, 255],
	purple: [128, 0, 128, 255],
	fuchsia: [255, 0, 255, 255],
	green: [0, 128, 0, 255],
	lime: [0, 255, 0, 255],
	olive: [128, 128, 0, 255],
	yellow: [255, 255, 0, 255],
	navy: [0, 0, 128, 255],
	blue: [0, 0, 255, 255],
	teal: [0, 128, 128, 255],
	aqua: [0, 255, 255, 255],
}

export function resolve_color (color) {
  if (typeof color === 'string') return colors[color]
  if (typeof color === 'number') return [color, color, color, 255]
  if (Array.isArray(color)) return color
  return [0, 0, 0, 255] // default to black?
}

export let background_color = "black"

export function add (v1, v2) {
  const [x1, y1] = v1
  const [x2, y2] = v2
  return [x1 + x2, y1 + y2]
}

export function mult (vector, scalar) {
  const [x, y] = vector
  return [x * scalar, y * scalar]
}

export function unit_of (heading) {
  const turns = -heading + 0.25
  const radians = turn_to_rad(turns)
  return [Math.cos(radians), Math.sin(radians)]
}

export function command_to_state (prev_state, curr_command) {
  const [verb] = curr_command
  switch (verb) {
    case "goto": {
      const [_, x, y] = curr_command
      return {...prev_state, position: [x, y]}
    }
    case "home": {
      return {...prev_state, position: [0, 0], heading: 0}
    }
    case "right": {
      const [_, angle] = curr_command
      const {heading} = prev_state
      return {...prev_state, heading: heading + angle}
    }
    case "left": {
      const [_, angle] = curr_command
      const {heading} = prev_state
      return {...prev_state, heading: heading - angle}
    }
    case "forward": {
      const [_, steps] = curr_command
      const {heading, position} = prev_state
      const unit = unit_of(heading)
      const move = mult(unit, steps)
      return {...prev_state, position: add(position, move)}
    }
    case "back": {
      const [_, steps] = curr_command
      const {heading, position} = prev_state
      const unit = unit_of(heading)
      const move = mult(unit, -steps)
      return {...prev_state, position: add(position, move)}
    }
    case "penup": {
      return {...prev_state, pendown: false}
    }
    case "pendown": {
      return {...prev_state, pendown: true}
    }
    case "penwidth": {
      const [_, width] = curr_command
      return {...prev_state, penwidth: width}
    }
    case "pencolor": {
      const [_, color] = curr_command
      return {...prev_state, pencolor: color}
    }
    case "setheading": {
      const [_, heading] = curr_command
      return {...prev_state, heading: heading}
    }
    case "loadstate": {
      // console.log("LOADSTATE: ", curr_command)
      const [_, [x, y], heading, visible, pendown, penwidth, pencolor] = curr_command
      return {position: [x, y], heading, visible, pendown, penwidth, pencolor}
    }
    case "show": {
      return {...prev_state, visible: true}
    }
    case "hide": {
      return {...prev_state, visible: false}
    }
    case "background": {
      background_color = curr_command[1]
      return prev_state
    }
  }
}

export function eq_vect (v1, v2) {
  const [x1, y1] = v1
  const [x2, y2] = v2
  return (x1 === x2) && (y1 === y2)
}

export function eq_color (c1, c2) {
  if (c1 === c2) return true
  const res1 = resolve_color(c1)
  const res2 = resolve_color(c2)
  for (let i = 0; i < res1.length; ++i) {
    if (res1[i] !== res2[i]) return false
  }
  return true
}

export function rotate (vector, heading) {
  const radians = turn_to_rad(heading)
  const [x, y] = vector
  return [
    (x * Math.cos (radians)) - (y * Math.sin (radians)),
    (x * Math.sin (radians)) + (y * Math.cos (radians))
  ]
}

export function turn_to_rad (heading) {
  return (heading % 1) * 2 * Math.PI
}

export function turn_to_deg (heading) {
  return (heading % 1) * 360
}

export function last (arr) {
  return arr[arr.length - 1]
}


