include, plotscr.hsd
include, scancode.hsi

global variable(1, mouse)
global variable(2, playing)
global variable(3, test layer)
global variable(4, dragging)
global variable(5, drag x off)
global variable(6, drag y off)
global variable(7, info layer)
global variable(8, clip rect)

plotscript, collision tester, begin
  suspend player
  create test slices
  create mouse cursor
  playing := true
  $2="C:Clip mouse"
  show string at(2, 220, 190)
  while(playing) do(
    if(keyval(1) >> 1) then(playing := false)
    if(keyval(key:c) >> 1) then(toggle clipping)
    update mouse
    update dragging
    update rects
    wait(1)
  )
  game over
end

script, update mouse, begin
  set slice screen x(mouse, mouse pixel x)
  set slice screen y(mouse, mouse pixel y)
  if(mouse click(left button) || mouse click(right button) || mouse click(middle button)) then(
    start dragging
  )
  if((mouse button(left button) || mouse button(right button) || mouse button(middle button)) == false) then(
    dragging := false
    y sort children(test layer)
  )
  $3=""
  if(mouse click(left button)) then ($3+" LEFT")
  if(mouse button(left button)) then ($3+" left")
  if(mouse click(middle button)) then ($3+" MID")
  if(mouse button(middle button)) then ($3+" mid")
  if(mouse click(right button)) then ($3+" RIGHT")
  if(mouse button(right button)) then ($3+" right")
  # Currently undocumented
  if(mouse click(3)) then ($3+" UP")
  if(mouse button(3)) then ($3+" up")
  if(mouse click(4)) then ($3+" DOWN")
  if(mouse button(4)) then ($3+" down")
  show string at(3, 212, 180)
end

script, start dragging, begin
  if (dragging) then(exit script)
  variable(sl)
  sl := first child(test layer)
  while(sl) do(
    if(slice collide point(sl, slice x(mouse), slice y(mouse))) then(
      dragging := sl
    )
    sl := next sibling(sl)
  )
  if(dragging) then(
    drag x off := slice screen x(dragging) -- slice x(mouse)
    drag y off := slice screen y(dragging) -- slice y(mouse)
    slice to front(dragging)
  )
end

script, update rects, begin
  variable(sl)
  if(dragging) then(
    $0="no collision with rect"
  )else(
    $0="no collision with mouse"
  )
  sl := first child(test layer)
  #these do not look at descendants
  while(sl) do(
    if(dragging) then(
      if(sl <> dragging) then(
        if(slice collide(sl, dragging)) then($0="collision with rect")
      )
    )else(
      if(slice collide point(sl, slice screen x(mouse), slice screen y(mouse))) then($0="collision with mouse")
    )
    sl := next sibling(sl)
  )

  free slice children(info layer)
  variable(i, numeral)
  i := 0

  #these tests do look at descendants (but not of dragging)
  if(dragging) then(
    $1=""
    while(sl := find colliding slice(test layer, dragging, i)) do(
      numeral := create text
      $31=""
      append number(31, i)
      set slice text(numeral, 31)
      set parent(numeral, info layer)
      set slice x(numeral, slice screen x(sl) -- 4)
      set slice y(numeral, slice screen y(sl) -- 4)
      i += 1
    )
  )else(
    $1=""
    append number(1, slice at pixel(test layer, slice screen x(mouse), slice screen y(mouse), get count))
    $1+" slices under the mouse"
    while(sl := slice at pixel(test layer, slice screen x(mouse), slice screen y(mouse), i)) do(
      numeral := create text
      $31=""
      append number(31, i)
      set slice text(numeral, 31)
      set parent(numeral, info layer)
      set slice x(numeral, slice screen x(sl) -- 4)
      set slice y(numeral, slice screen y(sl) -- 4)
      i += 1
    )

  )
end

script, create test slices, begin
  variable(i, j, sl, ch)
  test layer := create container(320, 200)
  for(i,0,9) do(
    sl := create rect(random(32, 80), random(32, 80), random(0, 14))
    set parent(sl, test layer)
    set rect border(sl, -1)
    realign slice(sl, edge:center, edge:center, edge:center, edge:center)
    set slice screen x(sl, random(0,319))
    set slice screen y(sl, random(0,200))
    clamp slice(sl, test layer)
    for(j, 1, random(0,1) * random(0,2)) do(
      ch := create rect(random(10, 40), random(10, 40), random(0, 14))
      set parent(ch, sl)
      set rect border(ch, -1)
      set rect trans(ch, trans:fuzzy)
      set slice x(ch, random(-50,50))
      set slice y(ch, random(-50,50))
      realign slice(ch, edge:center, edge:center, edge:center, edge:center)
    )
  )
  y sort children(test layer)

  info layer := create container(320, 200)
end

script, create mouse cursor, begin
  init mouse
  mouse := create container(9, 9)
  set horiz anchor(mouse, edge:center)
  set vert anchor(mouse, edge:center)
  variable(sl)
  sl := create rect(1, 9)
  set parent(sl, mouse)
  set rect border(sl, -1)
  center slice(sl)
  sl := create rect(9, 1)
  set parent(sl, mouse)
  set rect border(sl, -1)
  center slice(sl)
  show string at(0, 0, 180)
  show string at(1, 0, 190)
end

script, update dragging, begin
  if(dragging) then(
    set slice screen x(dragging, slice screen x(mouse) + drag x off)
    set slice screen y(dragging, slice screen y(mouse) + drag y off)
    clamp slice(dragging, sprite layer)
  )
end

script, toggle clipping, begin
  if(clip rect) then(
    mouse region
    free slice(clip rect)
    clip rect := 0
  ) else(
    clip rect := create rect(random(200, 380), random(140, 260), 14)
    set rect border(clip rect, -1)
    slice to back(clip rect)
set parent(clip rect, lookupslice(sl:maplayer0))
    put slice(clip rect, random(-50, 50), random(-30, 30))
    mouse region(slice x(clip rect), slice edge x(clip rect, edge:right) -- 1, slice y(clip rect), slice edge y(clip rect, edge:bottom) -- 1)
    trace value(slice x(clip rect), slice edge x(clip rect, edge:right) -- 1, slice y(clip rect), slice edge y(clip rect, edge:bottom) -- 1)
  )
end