<commit_before>class PuzzleApp

  constructor: () ->
    @pz_status = new PuzzleStatus(this)
    @ui_status = new UiStatus(this)
    @events = new EventHandler(this)

    @puzzle_view = new PuzzleView(this)
    @hex_box = new HexBox(this)
    @hex_draw = new HexDraw(this)
    @piece = new PuzzlePiece(this)
    @colors = new ColorRotation
    @indicator = new Indicator(this)
    @grid_model = new PuzzleGridModel(this)
    @mask = new MissingPiecesMask(this)
    @load_status = "none"
    get_photo(this)
    get_puzzle_pattern(this)



class EventHandler

  constructor: (puzzle_app) ->
    @puzzle = puzzle_app
    @pz_status = @puzzle.pz_status
    @ui_status = @puzzle.ui_status


  handle_mousedown: (e) ->
    @canvas = document.getElementById("puzzle-widget")
    dx = @canvas.offsetLeft
    dy = @canvas.offsetTop
    px = e.pageX
    py = e.pageY
    x = px-dx
    y = py-dy

    if @pz_status.finished == true
      @pz_status.start_new_puzzle()
    else
      if @puzzle.piece.in_bounding_box(x,y)
        @ui_status.activate_piece_drag()
        @puzzle.hex_box.get_anchor_to_dragpoint(x,y)
        mouse_hex = @puzzle.grid_model.get_hex(x,y)


  handle_mouseup: (e) ->
    @ui_status.terminate_piece_drag() if @ui_status.drag_active


  handle_mousemove: (e) ->
    if @ui_status.drag_active

      @canvas = document.getElementById("puzzle-widget")
      dx = @canvas.offsetLeft
      dy = @canvas.offsetTop
      px = e.pageX
      py = e.pageY
      x = px-dx
      y = py-dy

      mouse_hex = @puzzle.grid_model.get_hex(x,y)
      mx_a = mouse_hex[0]
      mx_b = mouse_hex[1]
      if mx_a != 99
        if ( mx_a != @ui_status.active_hex[0] || mx_b != @ui_status.active_hex[1] )
          @ui_status.set_active_hex(mx_a,mx_b)
          @puzzle.piece.draw_piece_ab(mx_a,mx_b)
          @puzzle.pz_status.set_piece() if @puzzle.piece.piece_is_anchored(mx_a,mx_b)



class UiStatus

  constructor: (puzzle_app) ->
    @puzzle = puzzle_app


  reset: () ->
    @drag_active = false
    @mouse_on_hex = false
    @active_hex = [99,99]


  set_active_hex: (a,b) ->
    @mouse_on_hex = true
    @active_hex = [a,b]


  disable_active_hex: () ->
    @mouse_on_hex = false
    @active_hex = [99,99]


  activate_piece_drag: () ->
    @drag_active = true


  terminate_piece_drag: () ->
    @drag_active = false



class PuzzleStatus

  constructor: (puzzle_app) ->
    @puzzle = puzzle_app
    @all_pieces = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p"]


  start_new_puzzle: () ->
    @finished = false
    @unset_pieces = @all_pieces[0..15]
    @pieces_in_puzzle = 16
    @pieces_set = 0
    @puzzle.ui_status.reset()
    @start_first_piece()


  set_piece: () ->
    console.log " "
    console.log "set_piece()"
    @puzzle.ui_status.terminate_piece_drag()
    @pieces_set += 1
    @pieces_in_puzzle -= 1
    console.log "   pieces_set = #{@pieces_set}"
    console.log "   pieces_in_puzzle = #{@pieces_in_puzzle}"
    if @pieces_set == 16
      @puzzle_finished()
    else
      @next_piece()


  puzzle_finished: () ->
    @puzzle.puzzle_view.draw_photo()
    @finished = true



  next_piece: () ->
    @puzzle.mask.reset_mask()
    @puzzle.indicator.decrement()
    @unset_pieces.splice(@unset_pieces.indexOf(@sym),1)
    pc = Math.floor(@pieces_in_puzzle*Math.random())
    @sym = @unset_pieces[pc]
    console.log " "
    console.log "next_piece()"
    console.log "   sym = #{@sym}"
    console.log "   pc = #{pc}"
    up = ""
    @unset_pieces.forEach (pcc) ->
      up = up + pcc
    console.log "   @unset_pieces = #{up}"
    @puzzle.piece.construct_piece(@sym)


  start_first_piece: () ->
    @puzzle.colors.new_rotation()
    @puzzle.indicator.start_indicator()
    pc = Math.floor(@pieces_in_puzzle*Math.random())
    @sym = @unset_pieces[pc]
    @puzzle.piece.construct_piece(@sym)



class MissingPiecesMask

  constructor: (puzzle_app) ->
    @puzzle = puzzle_app
    @puzzle_pattern = @puzzle.puzzle_pattern
    @hex_draw = @puzzle.hex_draw


  reset_mask: () ->
    @puzzle.puzzle_view.draw_photo()
    @get_next_color()
    console.log "CALL draw_mask() from reset_mask()"
    @draw_mask()


  get_next_color: () ->
    @color = @puzzle.colors.next_color()


  draw_mask: () ->
    console.log " "
    console.log "draw_mask()"
    console.log "   & & & & @color = #{@color} & & & &"
    grid = @puzzle.grid
    @hex_draw.set_context("canvas")
    zzz = 0 # EXTRA
    for bb in [1..10]
      for aa in [1..24]
        if grid[bb][aa] in @puzzle.pz_status.unset_pieces
          @hex_draw.fill_hex_ab(aa,bb,@color)
          zzz = zzz + 1 # EXTRA
    console.log "   #{zzz} hexes added to mask"



class PuzzlePiece

  constructor: (puzzle_app) ->
    @puzzle = puzzle_app
    @hex_box = @puzzle.hex_box
    @pattern  = new PiecePattern(this)
    @redraw = new PieceRedrawBuffer(this)
    @hexes = []
    @bounding_box = [0,0,0,0,]


  construct_piece: (sym) ->
    @sym = sym
    @hexes = @get_hexes()
    @hex_box.set_hex_box(sym)
    wd_ht = @hex_box.get_box_size()
    @width = wd_ht[0]
    @height = wd_ht[1]
    @redraw.reset_size(@width,@height)
    @pattern.draw_piece_pattern()
    @cut_piece_from_photo()
    @draw_piece_ab(-7,5)


  get_hexes: () ->
    hexes = []
    for bb in [1..10]
      for aa in [1..24]
        hexes.push([aa,bb]) if @puzzle.grid[bb][aa] == @sym
    return hexes


  cut_piece_from_photo: () ->

    @photo_clip = document.createElement('canvas')
    @photo_clip.id = "photo-clip"
    @photo_clip.width = @hex_box.width
    @photo_clip.height = @hex_box.height
    @photo_clip_context = @photo_clip.getContext('2d')
    xx = @hex_box.box_xy[0] - @puzzle.puzzle_view.puzzle_xy[0]
    yy = @hex_box.box_xy[1] - @puzzle.puzzle_view.puzzle_xy[1]
    photo = @puzzle.puzzle_view.photo
    console.log "xx is negative" if xx < 0
    console.log "yy is negative" if yy < 0
    console.log "@hex_box.width is negative" if @hex_box.width < 0
    console.log "@hex_box.height is negative" if @hex_box.height < 0
    @photo_clip_context.drawImage(photo,xx,yy,@hex_box.width,@hex_box.height,0,0,@hex_box.width,@hex_box.height)
    @puzzle.mask.reset_mask()
    context = @pattern.img.getContext('2d')
    context.globalCompositeOperation = 'source-atop'
    context.drawImage(@photo_clip,0,0)
    context.globalCompositeOperation = 'source-over'


  draw_piece_ab: (a,b) ->
    xy = @puzzle.hex_box.get_box_xy_ab(a,b)
    @draw_piece(xy[0],xy[1])
    @last_rendered_xy = xy


  draw_piece: (x,y) ->
    @redraw.apply_redraw()
    @redraw.prepare_next_redraw(x,y)
    context = @puzzle.puzzle_view.context_canvas
    context.drawImage(@pattern.img,x,y)
    @reset_bounding_box(x,y)


  piece_is_anchored: (a,b) ->
    if @hex_box.anchor_hex[0] == a && @hex_box.anchor_hex[1] == b
      return true
    else
      return false


  reset_bounding_box: (x,y) ->
    @left = x
    @right = x + @width
    @top = y
    @bottom = y + @height


  in_bounding_box: (x,y) ->
    if x>@left && x<@right && y>@top && y<@bottom then return true else return false



class PiecePattern

  constructor: (piece) ->
    @piece = piece
    @puzzle = @piece.puzzle
    @hex_box = @puzzle.hex_box
    @hex_draw = @puzzle.hex_draw
    @img = document.createElement('canvas')
    @img.id = "piece-mask"
    @piece_mask_context = @img.getContext('2d')


  draw_piece_pattern: () ->
    @img.width = @hex_box.width
    @img.height = @hex_box.height
    @hexes = @piece.hexes
    context = @img.getContext('2d')
    anchor_a = @hex_box.anchor_hex[0]
    anchor_b = @hex_box.anchor_hex[1]
    anchor_x = 0
    if @hex_box.corner_fit == "high" then anchor_y = 0 else anchor_y = 10
    for hx in @hexes
      aa = hx[0]
      bb = hx[1]
      xx = (aa - anchor_a) * 14
      yy = anchor_y + (bb - anchor_b) * 20
      if aa%2 != anchor_a%2
        if anchor_a%2 == 0 then yy = yy+10 else yy = yy-10
      @hex_draw.set_context2(@img)
      @hex_draw.fill_hex_xy(xx,yy,"#000000")



class PieceRedrawBuffer

  constructor: (piece) ->
    @piece = piece
    @puzzle = @piece.puzzle
    @view = @puzzle.puzzle_view

    @redraw_image = document.createElement('canvas')
    @redraw_image.width = 30
    @redraw_image.height = 30
    @redraw_x = 0
    @redraw_y = 0

  reset_size: (x,y) ->
    @width = x
    @height = y
    @redraw_image.width = @width
    @redraw_image.height = @height


  apply_redraw: () ->
    canvas = document.getElementById("puzzle-widget")
    context = canvas.getContext('2d')
    context.drawImage(@redraw_image,@redraw_x,@redraw_y)


  prepare_next_redraw: (x,y) ->
    ctx = @redraw_image.getContext('2d')
    ctx.clearRect(0,0,@width,@height)
    ht = @height
    if y < 0
      ht = ht + y
      y = 0
    wd = @width
    if x < 0
      wd = wd + x
      x = 0
    ctx.drawImage(@view.canvas,x,y,wd,ht,0,0,wd,ht)
    @redraw_x = x
    @redraw_y =y

<commit_msg>draws the puzzle piece and cycles through the puzzle<commit_after>class PuzzleApp

  constructor: () ->
    @pz_status = new PuzzleStatus(this)
    @ui_status = new UiStatus(this)
    @events = new EventHandler(this)

    @puzzle_view = new PuzzleView(this)
    @hex_box = new HexBox(this)
    @hex_draw = new HexDraw(this)
    @piece = new PuzzlePiece(this)
    @colors = new ColorRotation
    @indicator = new Indicator(this)
    @grid_model = new PuzzleGridModel(this)
    @mask = new MissingPiecesMask(this)
    @load_status = "none"
    get_photo(this)
    get_puzzle_pattern(this)



class EventHandler

  constructor: (puzzle_app) ->
    @puzzle = puzzle_app
    @pz_status = @puzzle.pz_status
    @ui_status = @puzzle.ui_status


  handle_mousedown: (e) ->
    @canvas = document.getElementById("puzzle-widget")
    dx = @canvas.offsetLeft
    dy = @canvas.offsetTop
    px = e.pageX
    py = e.pageY
    x = px-dx
    y = py-dy

    if @pz_status.finished == true
      @pz_status.start_new_puzzle()
    else
      if @puzzle.piece.in_bounding_box(x,y)
        @ui_status.activate_piece_drag()
        @puzzle.hex_box.get_anchor_to_dragpoint(x,y)
        mouse_hex = @puzzle.grid_model.get_hex(x,y)


  handle_mouseup: (e) ->
    @ui_status.terminate_piece_drag() if @ui_status.drag_active


  handle_mousemove: (e) ->
    if @ui_status.drag_active

      @canvas = document.getElementById("puzzle-widget")
      dx = @canvas.offsetLeft
      dy = @canvas.offsetTop
      px = e.pageX
      py = e.pageY
      x = px-dx
      y = py-dy

      mouse_hex = @puzzle.grid_model.get_hex(x,y)
      mx_a = mouse_hex[0]
      mx_b = mouse_hex[1]
      if mx_a != 99
        if ( mx_a != @ui_status.active_hex[0] || mx_b != @ui_status.active_hex[1] )
          @ui_status.set_active_hex(mx_a,mx_b)
          @puzzle.piece.draw_piece_ab(mx_a,mx_b)
          @puzzle.pz_status.set_piece() if @puzzle.piece.piece_is_anchored(mx_a,mx_b)



class UiStatus

  constructor: (puzzle_app) ->
    @puzzle = puzzle_app


  reset: () ->
    @drag_active = false
    @mouse_on_hex = false
    @active_hex = [99,99]


  set_active_hex: (a,b) ->
    @mouse_on_hex = true
    @active_hex = [a,b]


  disable_active_hex: () ->
    @mouse_on_hex = false
    @active_hex = [99,99]


  activate_piece_drag: () ->
    @drag_active = true


  terminate_piece_drag: () ->
    @drag_active = false



class PuzzleStatus

  constructor: (puzzle_app) ->
    @puzzle = puzzle_app
    @all_pieces = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p"]


  start_new_puzzle: () ->
    @finished = false
    @unset_pieces = @all_pieces[0..15]
    @pieces_in_puzzle = 16
    @pieces_set = 0
    @puzzle.ui_status.reset()
    @start_first_piece()


  set_piece: () ->
    console.log " "
    console.log "set_piece()"
    @puzzle.ui_status.terminate_piece_drag()
    @pieces_set += 1
    @pieces_in_puzzle -= 1
    console.log "   pieces_set = #{@pieces_set}"
    console.log "   pieces_in_puzzle = #{@pieces_in_puzzle}"
    if @pieces_set == 16
      @puzzle_finished()
    else
      @next_piece()


  puzzle_finished: () ->
    @puzzle.puzzle_view.draw_photo()
    @finished = true



  next_piece: () ->
    @puzzle.mask.reset_mask()
    @puzzle.indicator.decrement()
    @unset_pieces.splice(@unset_pieces.indexOf(@sym),1)
    pc = Math.floor(@pieces_in_puzzle*Math.random())
    @sym = @unset_pieces[pc]
    console.log " "
    console.log "next_piece()"
    console.log "   sym = #{@sym}"
    console.log "   pc = #{pc}"
    up = ""
    @unset_pieces.forEach (pcc) ->
      up = up + pcc
    console.log "   @unset_pieces = #{up}"
    @puzzle.piece.construct_piece(@sym)


  start_first_piece: () ->
    @puzzle.colors.new_rotation()
    @puzzle.indicator.start_indicator()
    pc = Math.floor(@pieces_in_puzzle*Math.random())
    @sym = @unset_pieces[pc]
    @puzzle.piece.construct_piece(@sym)



class MissingPiecesMask

  constructor: (puzzle_app) ->
    @puzzle = puzzle_app
    @puzzle_pattern = @puzzle.puzzle_pattern
    @hex_draw = @puzzle.hex_draw


  reset_mask: () ->
    @puzzle.puzzle_view.draw_photo()
    @get_next_color()
    console.log "CALL draw_mask() from reset_mask()"
    @draw_mask()


  get_next_color: () ->
    @color = @puzzle.colors.next_color()


  draw_mask: () ->
    console.log " "
    console.log "draw_mask()"
    console.log "   & & & & @color = #{@color} & & & &"
    grid = @puzzle.grid
    @hex_draw.set_context("canvas")
    zzz = 0 # EXTRA
    for bb in [1..10]
      for aa in [1..24]
        if grid[bb][aa] in @puzzle.pz_status.unset_pieces
          @hex_draw.fill_hex_ab(aa,bb,@color)
          zzz = zzz + 1 # EXTRA
    console.log "   #{zzz} hexes added to mask"



class PuzzlePiece

  constructor: (puzzle_app) ->
    @puzzle = puzzle_app
    @hex_box = @puzzle.hex_box
    @pattern  = new PiecePattern(this)
    @redraw = new PieceRedrawBuffer(this)
    @hexes = []
    @bounding_box = [0,0,0,0,]


  construct_piece: (sym) ->
    @sym = sym
    @hexes = @get_hexes()
    @hex_box.set_hex_box(sym)
    wd_ht = @hex_box.get_box_size()
    @width = wd_ht[0]
    @height = wd_ht[1]
    @redraw.reset_size(@width,@height)
    @pattern.draw_piece_pattern()
    @cut_piece_from_photo()
    @draw_piece_ab(-7,5)


  get_hexes: () ->
    hexes = []
    for bb in [1..10]
      for aa in [1..24]
        hexes.push([aa,bb]) if @puzzle.grid[bb][aa] == @sym
    return hexes


  cut_piece_from_photo: () ->

    @photo_clip = document.createElement('canvas')
    @photo_clip.id = "photo-clip"
    @photo_clip.width = @hex_box.width
    @photo_clip.height = @hex_box.height
    @photo_clip_context = @photo_clip.getContext('2d')
    xx = @hex_box.box_xy[0] - @puzzle.puzzle_view.puzzle_xy[0]
    yy = @hex_box.box_xy[1] - @puzzle.puzzle_view.puzzle_xy[1]
    photo = @puzzle.puzzle_view.photo
    console.log "xx is negative" if xx < 0
    console.log "yy is negative" if yy < 0
    console.log "@hex_box.width is negative" if @hex_box.width < 0
    console.log "@hex_box.height is negative" if @hex_box.height < 0
    @photo_clip_context.drawImage(photo,xx,yy,@hex_box.width,@hex_box.height,0,0,@hex_box.width,@hex_box.height)
    @puzzle.mask.reset_mask()
    context = @pattern.img.getContext('2d')
    context.globalCompositeOperation = 'source-atop'
    context.drawImage(@photo_clip,0,0)
    context.globalCompositeOperation = 'source-over'


  draw_piece_ab: (a,b) ->
    xy = @puzzle.hex_box.get_box_xy_ab(a,b)
    @draw_piece(xy[0],xy[1])
    @last_rendered_xy = xy


  draw_piece: (x,y) ->
    @redraw.apply_redraw()
    @redraw.prepare_next_redraw(x,y)
    canvas = document.getElementById("puzzle-widget")
    context = canvas.getContext('2d')
    context.drawImage(@pattern.img,x,y)
    @reset_bounding_box(x,y)


  piece_is_anchored: (a,b) ->
    if @hex_box.anchor_hex[0] == a && @hex_box.anchor_hex[1] == b
      return true
    else
      return false


  reset_bounding_box: (x,y) ->
    @left = x
    @right = x + @width
    @top = y
    @bottom = y + @height


  in_bounding_box: (x,y) ->
    if x>@left && x<@right && y>@top && y<@bottom then return true else return false



class PiecePattern

  constructor: (piece) ->
    @piece = piece
    @puzzle = @piece.puzzle
    @hex_box = @puzzle.hex_box
    @hex_draw = @puzzle.hex_draw
    @img = document.createElement('canvas')
    @img.id = "piece-mask"
    @piece_mask_context = @img.getContext('2d')


  draw_piece_pattern: () ->
    @img.width = @hex_box.width
    @img.height = @hex_box.height
    @hexes = @piece.hexes
    context = @img.getContext('2d')
    anchor_a = @hex_box.anchor_hex[0]
    anchor_b = @hex_box.anchor_hex[1]
    anchor_x = 0
    if @hex_box.corner_fit == "high" then anchor_y = 0 else anchor_y = 10
    for hx in @hexes
      aa = hx[0]
      bb = hx[1]
      xx = (aa - anchor_a) * 14
      yy = anchor_y + (bb - anchor_b) * 20
      if aa%2 != anchor_a%2
        if anchor_a%2 == 0 then yy = yy+10 else yy = yy-10
      @hex_draw.set_context2(@img)
      @hex_draw.fill_hex_xy(xx,yy,"#000000")



class PieceRedrawBuffer

  constructor: (piece) ->
    @piece = piece
    @puzzle = @piece.puzzle
    @view = @puzzle.puzzle_view
    @canvas = document.getElementById("puzzle-widget")
    @redraw_image = document.createElement('canvas')
    @redraw_image.width = 30
    @redraw_image.height = 30
    @redraw_x = 0
    @redraw_y = 0

  reset_size: (x,y) ->
    @width = x
    @height = y
    @redraw_image.width = @width
    @redraw_image.height = @height


  apply_redraw: () ->
    canvas = document.getElementById("puzzle-widget")
    context = canvas.getContext('2d')
    context.drawImage(@redraw_image,@redraw_x,@redraw_y)


  prepare_next_redraw: (x,y) ->
    ctx = @redraw_image.getContext('2d')
    ctx.clearRect(0,0,@width,@height)
    ht = @height
    if y < 0
      ht = ht + y
      y = 0
    wd = @width
    if x < 0
      wd = wd + x
      x = 0
    ctx.drawImage(@canvas,x,y,wd,ht,0,0,wd,ht)
    @redraw_x = x
    @redraw_y =y


{'fraction_non_alphanumeric': 0.14495031718407905, 'fraction_numerical': 0.01240666928647617, 'mean_word_length': 2.8844308765808986, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '726113', 'n_tokens_mistral': 7349, 'n_tokens_neox': 6867, 'n_words': 1178}