# Eneroth Cylindrical Coordinates

# Copyright Julia Christina Eneroth, eneroth3@gmail.com

module EneCylCoords

  def self.vertices(entities)
  
    entities.map { |e| e.vertices if e.respond_to?(:vertices) }.flatten.uniq
  
  end
  
  def self.convert_coords(p, lenth_as_full_turn)
  
      r = p.x
      a = Math::PI*2*p.y/lenth_as_full_turn
      x = Math.cos(a)*r
      y = Math.sin(a)*r
      z = p.z
      
      Geom::Point3d.new x, y, z
      
  end
  
  def self.move_vertices(entities, lenth_as_full_turn = 1.m)
  
    existing_entities = entities.to_a
    
    # Find all vertices in raw geometry.
    vertices = self.vertices entities
    
    # Explode curves so vertices can move independently.
    entities.each { |e| e.explode_curve if e.is_a?(Sketchup::Edge) }
    
    # Move vertices.
    vectors = vertices.map do |v|
      p_old = v.position
      p_new = self.convert_coords p_old, lenth_as_full_turn
      p_new - p_old
    end
    
    entities.transform_by_vectors vertices, vectors
    
    # Remove newly created edges if they are flat, otherwise soften them.
    new_entities = entities.to_a - existing_entities
    new_entities.each do |e|
      next if e.deleted?
      next unless e.is_a? Sketchup::Edge
      next unless e.faces.length == 2
      # Use classify_point instead of normal vector to see if face is co-planar
      # since it's more precise.
      planar = !e.faces[1].vertices.any? do |v|
				e.faces[0].classify_point(v.position) == Sketchup::Face::PointNotOnPlane
			end
      planar ? e.erase! : e.soft = e.smooth = true
    end

    # Remove edges that got 0 length and faces with 0 area.
    # FIXME: Doesn't remove all. The validity check still finds edges with same vertex in both ends.
    entities.each do |e|
      next if e.deleted?
      if e.is_a? Sketchup::Edge
        next unless e.start.position == e.end.position
      elsif e.is_a? Sketchup::Face
        next unless e.area == 0
      end
      e.erase!
    end
    
  end
  
  # Menu bar.
  UI.menu("Plugins").add_item("#{NAME}...") do
  
    model = Sketchup.active_model
    selection = model.selection
      
    if selection.length != 1 || ![Sketchup::Group, Sketchup::ComponentInstance].include?(selection.first.class)
      UI.messagebox "Select a group or component and try again."
      next
    end
    
    prompts  = ["Length corresponding to full circle"]
    defaults = [1.m.to_s]
    input = UI.inputbox prompts, defaults, "Change coordinate system"
    if input
      lenth_as_full_turn = input[0].to_l
      instance = selection.first
      entities = instance.entities
      model.start_operation "Convert Coordinates", true
      instance.name += "" if instance.is_a?(Sketchup::Group)# Make group uniq.
      self.move_vertices entities, lenth_as_full_turn
      model.commit_operation
    end
  
  end

end# Module