<commit_before>module Fontaine
class Canvas
  attr_accessor :id
  attr_accessor :width
  attr_accessor :height
  attr_accessor :alt
  attr_accessor :html_options
  attr_accessor :settings
  attr_accessor :ws
  attr_accessor :last_response
  attr_accessor :attributes
  
  
  def initialize(id, width, height, alt = "", html_options = {})
    @id = id
    @width = width
    @height = height
    @alt = alt
    @html_options = html_options
    @attributes = {
      :fill_style => '#000000', 
      :stroke_style => '#000000',
      :shadow_color => '#000000',
      :shadow_blur => 0,
      :shadow_offset_x => 0,
      :shadow_offset_y => 0,
      :line_cap => 'butt',
      :line_join => 'miter',
      :line_width => '1',
      :miter_limit => '10',
      :font => '10px sans-serif',
      :text_align => 'start',
      :text_baseline => 'alphabetic',
      :global_alpha => 1.0,
      :global_composite_operation => 'source-over'
      
      }
  end
  
  def start(request, settings, host = 'localhost', port = 4567, &block)  
    @settings = settings 
    
    
    request.websocket do |ws|
      
      ws.onopen do
        block.call
        @ws = ws
        @ws.send("register ##{id}")
        @settings.sockets << ws
        
      end
      ws.onmessage do |msg|
        #puts("recieved message: #{msg}")
        #EM.next_tick { process_message(msg)}
        process_message(msg)
      end
      ws.onclose do
        @settings.sockets.delete(ws)
      end
    end
    
  end
  
  def process_message(s_message)
    a_message = s_message.split(' ')
    command = a_message[0] #the first part of the message is the command
    params = a_message[1..(a_message.length-1)] #get the rest of the message
    params = Hash[*params] if command != "response"#convert the array to a hash if applicable
    respond_to(command, params)
  end
  
  def respond_to(s_command, params = {})
    case s_command
    when "mousedown"
      trigger_on_mousedown(params["x"], params["y"], params["button"])
    when "mouseup"
      trigger_on_mouseup(params["x"], params["y"], params["button"])
    when "mouseover"
      trigger_on_mouseover(params["x"], params["y"]) 
    when "mouseout"
      trigger_on_mouseout(params["x"], params["y"]) 
    when "mousemove"
      trigger_on_mousemove(params["x"], params["y"])
    when "touchstart"
      trigger_on_touchstart(params["x"], params["y"], params["id"])  
    when "touchmove"
      trigger_on_touchstart(params["x"], params["y"], params["id"])
    when "touchend"
      trigger_on_touchstart(params["x"], params["y"], params["id"])               
    when "keyup"
      trigger_on_keyup(params["key_code"])    
    when "keydown"
      trigger_on_keydown(params["key_code"])
    when "keypress"
      trigger_on_keypress(params["which"])
    when "click"
      trigger_on_click(params["x"], params["y"], params["button"])      
    when "response"
      @last_response =  params.flatten[0].to_s
      trigger_on_response(@last_response)
    else
      puts "unimplemented method #{s_command}"
    end
  end
  
  def display    
    options = ""
    @html_options.each_pair do  |key, value| 
      options << "#{key}=\"#{value}\" "
    end
    return "<canvas id=\"#{@id}\" width=\"#{@width}\" height=\"#{@height}\" #{options}>#{@alt}</canvas>"
  end

  def fill_style(style="", &blk)
    if style.is_a? String
      send_msg "fillStyle #{style}"
    else
      send_msg "fillStyleObject #{style.id}"
    end
    
    # return @last_response
    return @attributes[fill_style]
    
  end
  
  def stroke_style(style="")
    if style.is_a? String
      send_msg "strokeStyle #{style}"
    else
      send_msg "strokeStyleObject #{style.id}"
    end
    # return @last_response
    return @attributes[stroke_style]
  end
  
  def create_linear_gradient(x0, y0, x1, y1, id)
    send_msg("createLinearGradient #{x0} #{y0} #{x1} #{y1} #{id}")
    return Gradient.new(id, self)<commit_msg>Fixed stack level too deep error by changing stroke_style and fill_style to symbols where appropriate<commit_after>module Fontaine
class Canvas
  attr_accessor :id
  attr_accessor :width
  attr_accessor :height
  attr_accessor :alt
  attr_accessor :html_options
  attr_accessor :settings
  attr_accessor :ws
  attr_accessor :last_response
  attr_accessor :attributes
  
  
  def initialize(id, width, height, alt = "", html_options = {})
    @id = id
    @width = width
    @height = height
    @alt = alt
    @html_options = html_options
    @attributes = {
      :fill_style => "#000000", 
      :stroke_style => '#000000',
      :shadow_color => '#000000',
      :shadow_blur => 0,
      :shadow_offset_x => 0,
      :shadow_offset_y => 0,
      :line_cap => 'butt',
      :line_join => 'miter',
      :line_width => '1',
      :miter_limit => '10',
      :font => '10px sans-serif',
      :text_align => 'start',
      :text_baseline => 'alphabetic',
      :global_alpha => 1.0,
      :global_composite_operation => 'source-over'
      
      }
  end
  
  def start(request, settings, host = 'localhost', port = 4567, &block)  
    @settings = settings 
    
    
    request.websocket do |ws|
      block.call
      ws.onopen do
        
        @ws = ws
        @ws.send("register ##{id}")
        @settings.sockets << ws
        
        
        
      end
      ws.onmessage do |msg|
        #puts("recieved message: #{msg}")
        #EM.next_tick { process_message(msg)}
        process_message(msg)
      end
      ws.onclose do
        @settings.sockets.delete(ws)
      end
    end
    
  end
  
  def process_message(s_message)
    a_message = s_message.split(' ')
    command = a_message[0] #the first part of the message is the command
    params = a_message[1..(a_message.length-1)] #get the rest of the message
    params = Hash[*params] if command != "response"#convert the array to a hash if applicable
    respond_to(command, params)
  end
  
  def respond_to(s_command, params = {})
    case s_command
    when "mousedown"
      trigger_on_mousedown(params["x"], params["y"], params["button"])
    when "mouseup"
      trigger_on_mouseup(params["x"], params["y"], params["button"])
    when "mouseover"
      trigger_on_mouseover(params["x"], params["y"]) 
    when "mouseout"
      trigger_on_mouseout(params["x"], params["y"]) 
    when "mousemove"
      trigger_on_mousemove(params["x"], params["y"])
    when "touchstart"
      trigger_on_touchstart(params["x"], params["y"], params["id"])  
    when "touchmove"
      trigger_on_touchstart(params["x"], params["y"], params["id"])
    when "touchend"
      trigger_on_touchstart(params["x"], params["y"], params["id"])               
    when "keyup"
      trigger_on_keyup(params["key_code"])    
    when "keydown"
      trigger_on_keydown(params["key_code"])
    when "keypress"
      trigger_on_keypress(params["which"])
    when "click"
      trigger_on_click(params["x"], params["y"], params["button"])      
    when "response"
      @last_response =  params.flatten[0].to_s
      trigger_on_response(@last_response)
    else
      puts "unimplemented method #{s_command}"
    end
  end
  
  def display    
    options = ""
    @html_options.each_pair do  |key, value| 
      options << "#{key}=\"#{value}\" "
    end
    return "<canvas id=\"#{@id}\" width=\"#{@width}\" height=\"#{@height}\" #{options}>#{@alt}</canvas>"
  end

  def fill_style(style="", &blk)
    if style.is_a? String
      send_msg "fillStyle #{style}"
    else
      send_msg "fillStyleObject #{style.id}"
    end
    
    # return @last_response
    return @attributes[:fill_style]
    
  end
  
  def stroke_style(style="")
    if style.is_a? String
      send_msg "strokeStyle #{style}"
    else
      send_msg "strokeStyleObject #{style.id}"
    end
    # return @last_response
    return @attributes[:stroke_style]
  end
  
  def create_linear_gradient(x0, y0, x1, y1, id)
    send_msg("createLinearGradient #{x0} #{y0} #{x1} #{y1} #{id}")
    return Gradient.new(id, self)
{'fraction_non_alphanumeric': 0.1391610148203969, 'fraction_numerical': 0.01105249937201708, 'mean_word_length': 2.8118717089516516, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 37, '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': '317651', 'n_tokens_mistral': 2707, 'n_tokens_neox': 2637, 'n_words': 583}