# THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

# Name:           jsAlign.rb 1.02
# Author:         Jan Sandstrom   www.pixero.com
# Date:           6 Aug 2007
# Changes:	Added functionality to also work on groups/components.
# Description:		Use for aligning edges or groups/components.
#                		If using custom value with groups also use Align Group's: Max, Min or Center.
# Issues:			1. If used on edges with faces, the faces will be triagulated. 
#			Since the script in "vertex mode" moves each vertice at a time, SketchUp's autofold feature will trangulate all non planar faces.
#			I've tried to find a way of auto erasing all edges created by autofold but havens succeded. 
#			If you know how to fix it please let me know.
#			2. The script doesnt work well with faces when working/editing inside groups/components.

require 'sketchup.rb'


class Sketchup::Selection 
def vertices 
	selverts = []; 
	self.each {|e| 
		selverts.push e.vertices if (e.respond_to?(:vertices)); 
	} 
	return selverts.flatten.uniq; 
end ;  # method vertices
end ;  # class Sketchup::Selection 


#class AutofoldWatch < Sketchup::EntitiesObserver
#	def onElementAdded(element)
#		autofoldEdges = [];
#		if element.typename == "Edge" and element.valid?
#			autofoldEdges.push(element)
#		end#if
#		return autofoldEdges;
#	end#def
#end


def jsAlign 
	model = Sketchup.active_model
	entities = model.active_entities
	sel = model.selection
	
	if sel.empty?
     		UI.beep
     		UI.messagebox("Nothing Selected!")
     		return nil
  	end#if
  	
  	### Get all edges in selection
	
	edges=[]
	for e in sel
  		if e.typename=="Edge" and e.valid?
    			edges.push(e)
  		end#if
	end#for
  	
  	
  	### Dialog

	@axis = "Z" if not @axis
	@base = "Center" if not @base
	@customvalue = 0.mm if not defined? @customvalue  and model.options["UnitsOptions"]["LengthUnit"]>1
  	@groupbase = "Center" if not @groupbase

	enums = ["X" '|' "Y" '|' "Z", "Max" '|' "Center" '|' "Min" '|' "Custom", "", "Max" '|' "Center" '|' "Min"]
	prompts = ["Align axis: ", "Align to: ", "Custom value: ", "Align group's: "]
	values = [@axis, @base, @customvalue, @groupbase]
	results = inputbox (prompts, values, enums, "Align Settings")
	axis, base, customvalue, groupbase = results
	@axis, @base, @customvalue, @groupbase = axis, base, customvalue, groupbase
	
  	
  	### Align
  		
	selverts = Sketchup.active_model.selection.vertices; 

	bb = Geom::BoundingBox.new;
	Sketchup.active_model.selection.each {|e| bb.add(e.bounds); } 
		
		

	if (@base == "Max")
		basepoint = Geom::Point3d.new (bb.max);
	end#if
	if (@base == "Center")
		basepoint = Geom::Point3d.new (bb.center);
	end#if
	if (@base == "Min")
		basepoint = Geom::Point3d.new (bb.min);
	end#if
	if (@base == "Custom")
		basepoint = Geom::Point3d.new ([customvalue, customvalue, customvalue]);
	end#if
	
	#@af = Sketchup.active_model.entities.add_observer(AutofoldWatch.new) ###Observer added


		# Aligning groups
		Sketchup.active_model.selection.each {|e|
		if (e.kind_of? Sketchup::Group) or (e.kind_of? Sketchup::ComponentInstance) 
		 		
		# point = Geom::Point3d.new (e.bounds.center);

		if (@base == "Max")
			point = Geom::Point3d.new (e.bounds.max);
		end#if
		if (@base == "Center")
			point = Geom::Point3d.new (e.bounds.center);
		end#if
		if (@base == "Min")
			point = Geom::Point3d.new (e.bounds.min);
		end#if
		if (@base == "Custom") #Align the group's: max, min or center. (Just for groups/components.)
			if (@groupbase == "Max")
				point = Geom::Point3d.new (e.bounds.max);
			end#if
			if (@groupbase == "Center")
				point = Geom::Point3d.new (e.bounds.center);
			end#if
			if (@groupbase == "Min")
				point = Geom::Point3d.new (e.bounds.min);
			end#if
		end#if

		
		if (@axis == "X")
			dist = Geom::Point3d.new [basepoint.x-point.x, 0, 0];
		end#if
		if (@axis == "Y")
			dist = Geom::Point3d.new [0, basepoint.y-point.y, 0];
		end#if
		if (@axis == "Z")
			dist = Geom::Point3d.new [0, 0, basepoint.z-point.z];
		end#if
		
				
		t = Geom::Transformation.new (dist);
		Sketchup.active_model.entities.transform_entities(t, e);
			
		
	end #if 
	}

	# Aligning edges
	selverts.each {|v| 
	
		point = Geom::Point3d.new [v.position.x, v.position.y, v.position.z];
		
		if (@axis == "X")
			dist = Geom::Point3d.new [basepoint.x-point.x, 0, 0];
		end#if
		if (@axis == "Y")
			dist = Geom::Point3d.new [0, basepoint.y-point.y, 0];
		end#if
		if (@axis == "Z")
			dist = Geom::Point3d.new [0, 0, basepoint.z-point.z];
		end#if
		
				
		t = Geom::Transformation.new (dist);
		Sketchup.active_model.entities.transform_entities(t, v);

	}
	
	#autofoldEdges.erase! ###Erase edges created by autofold
	#Sketchup.active_model.entities.remove_observer @af ###Observer removed

end #jsAlign

############################################################
if( not file_loaded?("jsAlign.rb") )
    UI.menu("Plugins").add_separator
    UI.menu("Plugins").add_item("JS Align") { jsAlign  }
end

file_loaded("jsAlign.rb")
