# Core SVG data for the trident specification sheet.
#
# This class should never need to be called directly.
# @private
class USPSFlags::Core::TridentSpec
def initialize(fly: 24, unit: "in")
@trident_config = USPSFlags.configuration.trident
configure_sizes(fly)
configure_labels(unit)
end
def svg
svg = spec_header
box_left = (USPSFlags::Config::BASE_FLY*27/32)/2
box_right = (USPSFlags::Config::BASE_FLY*37/32)/2
box_top = USPSFlags::Config::BASE_HOIST/4
box_bottom = USPSFlags::Config::BASE_HOIST*3/4
svg << short_trident(box_top, box_bottom, box_left, box_right)
box_top = USPSFlags::Config::BASE_HOIST*3/16
box_bottom = USPSFlags::Config::BASE_HOIST*13/16
svg << delta_trident(box_top, box_bottom, box_left, box_right)
box_top = USPSFlags::Config::BASE_HOIST/8
box_bottom = USPSFlags::Config::BASE_HOIST*7/8
svg << circle_trident(box_top, box_bottom, box_left, box_right)
svg << long_trident(box_top, box_bottom, box_left, box_right)
svg
end
private
def configure_sizes(fly)
@fly = Rational(fly)
get_hoist_from_fly(@fly)
configure_hoist_fraction
configure_fly_fraction
end
def get_hoist_from_fly(fly)
hoist = (fly*Rational(2,3))
@hoist = if hoist == hoist.to_i
hoist.to_i
else
hoist
end
end
def configure_hoist_fraction
@hoist_fraction = ""
if @hoist == @hoist.to_i
@hoist = @hoist.to_i
else
@hoist, @hoist_fraction = @hoist.to_simplified_a
end
end
def configure_fly_fraction
@fly_fraction = ""
if @fly == @fly.to_i
@fly = @fly.to_i
else
@fly, @fly_fraction = @fly.to_simplified_a
end
end
def configure_labels(unit)
@label_font_size = if Math.sqrt(@fly) > 24
USPSFlags::Config::BASE_FLY * Math.log(24, Math.sqrt(@fly)) / 60
else
USPSFlags::Config::BASE_FLY / 60
end
@unit_text = unit.nil? ? "" : "#{unit}"
@unit = unit
configure_barb_label
end
def configure_barb_label
barb_label = Rational(@trident_config[:main_point_barb]) * @fly / USPSFlags::Config::BASE_FLY
@barb_label = if barb_label == barb_label.to_i
"#{barb_label.to_i}#{@unit_text}"
else
"#{barb_label.to_simplified_s}#{@unit_text}"
end
end
def spec_header
<<~SVG
#{USPSFlags::Core.field}
United States Power Squadrons®
Officer Flag Trident Specification
All measurements are relative to a field with
fly of #{@fly} #{@fly_fraction} #{@unit_text} and hoist of #{@hoist} #{@hoist_fraction} #{@unit_text}.
Measurements not specified are the same as on the short trident.
SVG
end
def short_trident(box_top, box_bottom, box_left, box_right)
<<~SVG
#{trident_heading(:s)}
#{USPSFlags::Core::Trident.new(:s).svg}
#{USPSFlags::Helpers::SpecArrows.vertical(box_right+@trident_config[:bar_width], box_top, box_top+@trident_config[:bar_width], box_right, box_right, fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.vertical(box_right+@trident_config[:bar_width], box_top+@trident_config[:bar_width], box_top+@trident_config[:bar_width]*2+@trident_config[:point_height]+@trident_config[:side_spike_height], nil, box_right, fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.vertical(box_right+@trident_config[:bar_width], box_top+@trident_config[:bar_width]*2+@trident_config[:point_height]+@trident_config[:side_spike_height], box_top+@trident_config[:bar_width]*3+@trident_config[:point_height]+@trident_config[:side_spike_height], nil, @trident_config[:center_point]+@trident_config[:hash_width]/2, fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.vertical(box_right+@trident_config[:bar_width], box_top+@trident_config[:bar_width]*3+@trident_config[:point_height]+@trident_config[:side_spike_height], box_top+@trident_config[:bar_width]*4+@trident_config[:point_height]+@trident_config[:side_spike_height], nil, @trident_config[:center_point]+@trident_config[:hash_width]/2, fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.vertical(box_right+@trident_config[:bar_width], box_top+@trident_config[:bar_width]*4+@trident_config[:point_height]+@trident_config[:side_spike_height], box_bottom, nil, box_right, fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.vertical(box_left-@trident_config[:bar_width]*5.25, box_top, box_bottom, box_left, box_left, fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.vertical(box_left-@trident_config[:bar_width]*0.75, box_top, box_top+@trident_config[:point_height], nil, @trident_config[:center_point]-@trident_config[:bar_width], label_offset: -USPSFlags::Config::BASE_FLY/26, label_offset_y: -USPSFlags::Config::BASE_FLY/100, label_align: "middle", fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.vertical(box_left-@trident_config[:bar_width]*1.5, box_top+@trident_config[:bar_width], box_top+@trident_config[:bar_width]+@trident_config[:point_height], box_left, box_left+@trident_config[:bar_width], label_offset: -USPSFlags::Config::BASE_FLY/24, label_align: "middle", fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.horizontal(box_bottom+@trident_config[:bar_width], @trident_config[:center_point]-@trident_config[:bar_width]/2, @trident_config[:center_point]+@trident_config[:bar_width]/2, box_bottom, box_bottom, fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.horizontal(box_bottom+@trident_config[:bar_width]*2.5, @trident_config[:center_point]-@trident_config[:hash_width]/2, @trident_config[:center_point]+@trident_config[:hash_width]/2, box_top+@trident_config[:bar_width]*4+@trident_config[:point_height]+@trident_config[:side_spike_height], box_top+@trident_config[:bar_width]*4+@trident_config[:point_height]+@trident_config[:side_spike_height], fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.horizontal(box_bottom+@trident_config[:bar_width]*4, box_left, box_right, box_bottom, box_bottom, fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.horizontal(box_top-@trident_config[:bar_width], box_left, box_left+@trident_config[:bar_width]*3/2, box_top, box_top+@trident_config[:bar_width]+@trident_config[:point_height], label_offset: -USPSFlags::Config::BASE_FLY/60, fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.horizontal(box_top-@trident_config[:bar_width]*2.5, @trident_config[:center_point]-@trident_config[:bar_width], @trident_config[:center_point]+@trident_config[:bar_width], box_top+@trident_config[:point_height], box_top+@trident_config[:point_height], label_offset: -USPSFlags::Config::BASE_FLY/60, fly: @fly, unit: @unit)}
#{@barb_label}
SVG
end
def delta_trident(box_top, box_bottom, box_left, box_right)
<<~SVG
#{trident_heading(:d)}
#{USPSFlags::Core::Trident.new(:d).svg}
#{USPSFlags::Helpers::SpecArrows.vertical(box_right+@trident_config[:bar_width], box_bottom-@trident_config[:delta_from_bottom]-@trident_config[:bar_width]-@trident_config[:delta_gap_height], box_bottom-@trident_config[:delta_from_bottom]-@trident_config[:bar_width], @trident_config[:center_point], @trident_config[:center_point]+@trident_config[:delta_gap_width], fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.vertical(box_right+@trident_config[:bar_width], box_bottom-@trident_config[:delta_from_bottom]-@trident_config[:bar_width], box_bottom-@trident_config[:delta_from_bottom], nil, box_right, fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.vertical(box_right+@trident_config[:bar_width], box_bottom-@trident_config[:delta_from_bottom], box_bottom, nil, box_right, fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.vertical(box_left-@trident_config[:bar_width]*1.5, box_top, box_bottom, box_left, box_left, label_offset: -USPSFlags::Config::BASE_FLY/30, label_offset_y: -USPSFlags::Config::BASE_FLY*2/11, label_align: "middle", fly: @fly, unit: @unit)}
SVG
end
def circle_trident(box_top, box_bottom, box_left, box_right)
<<~SVG
#{trident_heading(:stf)}
#{USPSFlags::Core::Trident.new(:stf).svg}
#{long_trident_boundary_box(box_top, box_left, box_right)}
#{USPSFlags::Helpers::SpecArrows.vertical(box_right+@trident_config[:bar_width], box_top+@trident_config[:crossbar_from_top]+@trident_config[:bar_width]*2, box_top+@trident_config[:crossbar_from_top]+@trident_config[:width], @trident_config[:center_point], @trident_config[:center_point], fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.vertical(box_right+@trident_config[:bar_width], box_top+@trident_config[:crossbar_from_top]+@trident_config[:width], box_top+@trident_config[:crossbar_from_top]+@trident_config[:bar_width]+@trident_config[:width], nil, @trident_config[:center_point]+@trident_config[:bar_width]/2, fly: @fly, unit: @unit)}
#{USPSFlags::Helpers::SpecArrows.vertical(box_right+@trident_config[:bar_width], box_top+@trident_config[:crossbar_from_top]+@trident_config[:bar_width]+@trident_config[:width], box_bottom, nil, box_right, fly: @fly, unit: @unit)}
#{long_trident_left_arrow(box_top, box_bottom, box_left, box_right)}
SVG
end
def long_trident(box_top, box_bottom, box_left, box_right)
<<~SVG
#{trident_heading(:n)}
#{USPSFlags::Core::Trident.new(:n).svg}
#{long_trident_boundary_box(box_top, box_left, box_right)}
#{USPSFlags::Helpers::SpecArrows.vertical(box_right+@trident_config[:bar_width], box_top+@trident_config[:crossbar_from_top]+@trident_config[:bar_width]*3, box_bottom, @trident_config[:center_point]+@trident_config[:hash_width]/2, box_right, fly: @fly, unit: @unit)}
#{long_trident_left_arrow(box_top, box_bottom, box_left, box_right)}
SVG
end
def trident_heading(type_sym)
type, description = case type_sym
when :s
["Short", "Squadron Officers"]
when :d
["Delta", "District Officers"]
when :stf
["Circle", "Staff Commanders Only"]
when :n
["Long", "National Officers"]
end
<<~SVG
#{type}
#{description}
SVG
end
def long_trident_boundary_box(box_top, box_left, box_right)
<<~SVG
SVG
end
def long_trident_left_arrow(box_top, box_bottom, box_left, box_right)
<<~SVG
#{USPSFlags::Helpers::SpecArrows.vertical(box_left-@trident_config[:bar_width]*1.5, box_top, box_bottom, box_left, box_left, label_offset: -USPSFlags::Config::BASE_FLY/30, label_offset_y: -USPSFlags::Config::BASE_FLY/4.5, label_align: "middle", fly: @fly, unit: @unit)}
SVG
end
end