class IMICRTS
  class Building < Component
    def setup
      data.construction_progress ||= 0
      data.construction_goal ||= Entity.get(@parent.name).build_steps

      @text = CyberarmEngine::Text.new("", y: @parent.position.y, z: Float::INFINITY, size: 12)
      data.state = :construct # deconstruct, building, idle
    end

    def draw
      case data.state
      when :construct
        draw_construction unless @text.text.empty?
        @text.text = "Building: #{(construction_progress * 100.0).round}%"
        @text.x = @parent.position.x - @text.width / 2
        @text.draw
      when :deconstruct
      when :building
      when :idle
      else
        raise "Unknown state!"
      end
    end

    def update
      case data.state
      when :construct
        @parent.color.alpha = 255 * construction_progress
        data.state = :idle if construction_complete?
      end
    end

    def construction_complete?
      data.construction_progress >= data.construction_goal
    end

    # WARNING: returns a floating point number, not network safe!
    def construction_progress
      data.construction_progress.to_f / data.construction_goal
    end

    def construction_work(work)
      raise TypeError, "Got a non integer value!" unless work.is_a?(Integer)

      data.construction_progress += work
      data.construction_progress = data.construction_goal if construction_complete?
    end

    def draw_construction
      @fencing ||= get_image(IMICRTS::ASSETS_PATH + "/fencing/fencing.png")
      @fencing_edge ||= get_image(IMICRTS::ASSETS_PATH + "/fencing/fencing_edge.png")

      tiles = []
      each_tile(@parent.position / @parent.director.map.tile_size) do |tile, data, x, y|
        tiles << tile
      end

      tiles.each do |tile|
        # X
        if tiles.find { |t| t.grid_position.x < tile.grid_position.x && t.grid_position.y == tile.grid_position.y} == nil
          @fencing_edge.draw(tile.position.x - 30, tile.position.y, Float::INFINITY)
        end
        if tiles.find { |t| t.grid_position.x > tile.grid_position.x && t.grid_position.y == tile.grid_position.y} == nil
          @fencing_edge.draw(tile.position.x, tile.position.y, Float::INFINITY)
        end
        # Y
        if tiles.find { |t| t.grid_position.x == tile.grid_position.x && t.grid_position.y < tile.grid_position.y} == nil
          @fencing.draw(tile.position.x, tile.position.y - 24, Float::INFINITY)
        end
        if tiles.find { |t| t.grid_position.x == tile.grid_position.x && t.grid_position.y > tile.grid_position.y} == nil
          @fencing.draw(tile.position.x, tile.position.y, Float::INFINITY)
        end
      end
    end

    def each_tile(vector, &block)
      if tile = @parent.director.map.tile_at(vector.x, vector.y)
        ent = Entity.get(@parent.name)
        origin = (tile.grid_position - 2)

        ent.tiles.each_with_index do |array, y|
          array.each_with_index do |space_required, x|
            next unless space_required.is_a?(TrueClass)

            other_tile = @parent.director.map.tile_at(origin.x + x, origin.y + y)
            if other_tile
              block.call(other_tile, space_required, origin.x + x, origin.y + y)
            end
          end
        end
      end
    end
  end
end