# copyright= 'Huynh Duong Phuong Vi @ 2013-2014'
# suforyou.vn@gmail.com
module S4U::S4u_Select
		def self.select_edge(mode)    
			model = Sketchup.active_model
			selection = model.selection 
			entities=model.active_entities
			@axis=2 if !@axis
			@tolerance=0 if !@tolerance
			edges=[]
			case mode
			when 0,90,"slope"
				sels=[]
				sels= selection.empty? ? entities : selection
				vectorz=@edit_transform.zaxis
				axis=[@edit_transform.xaxis,@edit_transform.yaxis,@edit_transform.zaxis]
				list_axis=["X","Y","Z"]
				if mode==0 || mode==90
					prompts = [Strings.GetString("Axis?"),Strings.GetString("Tolerance?")]
					defaults =[list_axis[@axis],roundnumber(@tolerance.radians,2)]
					list=["X|Y|Z",""]
					input = UI.inputbox(prompts, defaults,list, Strings.GetString("Select Axis"))  
					if input
						@axis=list_axis.index(input[0])
						vectorz =axis[@axis] 
						@tolerance=input[1].to_f.degrees
					end
					sels.each{|e|  
						if e.is_a?Sketchup::Edge    
							a=((Math::PI/ 2)-(e.line[1].angle_between vectorz))
							edges<< e if (roundnumber(a-mode.degrees).abs<=@tolerance)||(roundnumber(a+mode.degrees).abs<=@tolerance)
						end
					}
				else
					prompts = [Strings.GetString("Axis?"),Strings.GetString("Min slope?"),Strings.GetString("Max slope?")]
					defaults =(@min_slope_edge && @max_slope_edge) ? [list_axis[@axis],@min_slope_edge,@max_slope_edge] : [list_axis[@axis],0,90]
					list=["X|Y|Z"]
					input = UI.inputbox(prompts, defaults,list, Strings.GetString("Enter slope"))              
					if input
						@axis=list_axis.index(input[0])
						vectorz =axis[@axis] 
						@min_slope_edge=input[1].to_f
						@max_slope_edge=input[2].to_f
						sels.each{|e|  
							if e.is_a?Sketchup::Edge   
								a= e.line[1].angle_between vectorz
								edges<< e if (roundnumber(a-@min_slope_edge.degrees)>=0) && (roundnumber(@max_slope_edge.degrees-a)>=0) 
							end
						}
					end  
				end
			when "length"
				sels=[]
				sels= selection.empty? ? entities : selection                                                 
				edge=sels.grep(Sketchup::Edge)
				@min_length=0 if !@min_length
				edge = edge.chunk { |f| f.length }.sort_by{|fs| fs[1].length}[-1][1] if edge && edge.length>0
				de= (edge && edge[0]) ? ((edge[0].length).to_f.ceil.to_s) : "100"
				#defaults =(@min_length && @max_length) ? [(parse_length(@min_length)).to_s,(parse_length(@max_length)).to_s] : [(parse_length(0)).to_s,(parse_length(de)).to_s]
				defaults=[Sketchup.format_length(@min_length.to_f), Sketchup.format_length(de.to_f)] 
				prompts = [Strings.GetString("Min length?"),Strings.GetString("Max length?")]
				input = UI.inputbox(prompts,defaults,Strings.GetString("Enter length edge"))
				if input
					@min_length=parse_length input[0]
					@max_length=parse_length input[1]
					edges =sels.select{|e| (e.is_a?Sketchup::Edge) && ((parse_length e.length) >= @min_length ) && ((parse_length e.length) <= @max_length)}
				end
			when "same_length"
				if selection.length>0
					selection.each{|f| edges+=entities.select{|e| (f.is_a?Sketchup::Edge) && (e.is_a?Sketchup::Edge) && (f.length==e.length) } }
				else
					UI.messagebox Strings.GetString("Select first edge")
				end
			end
			selection.clear
			edges.uniq!
			if edges.empty?
				Sketchup.set_status_text Strings.GetString("No selected edge")
			else
				Sketchup.set_status_text Strings.GetString(edges.length.to_s + " selected edges")
				selection.add edges
			end	
		end
		def self.parse_length(input)
			(return 0) if !input
			begin
				value=input.to_s.to_l
			rescue 
				value=input.to_s.to_f
			end 
			return value
		end
		def self.roundnumber(num,e=10)
			return ((num*(10**e)).round/ (10**e).to_f)
		end	
		def self.get_numvers(face)
			(return 0) if not face.is_a?Sketchup::Face
			ver=[]
			vertices=[]    
			vertices =face.outer_loop.vertices*2    
			(1..face.vertices.length).each { |i|
				p1=vertices[i].position
				p2=vertices[i+1].position
				p3=vertices[i+2].position
				v1=p1.vector_to p2
				v2=p2.vector_to p3
				(ver<< vertices[i+1].position) if !(v1.samedirection? v2)
			}
			return ver.length
		end	      
		def self.select_face(mode)
			model = Sketchup.active_model
			selection = model.selection 
			entities=model.active_entities
			@axis=2 if !@axis
			@tolerance=0 if !@tolerance
			faces=[]	
			case mode 
			when 0,90,"slope"
				sels=[]
				sels= selection.empty? ? entities : selection
				vectorz=@edit_transform.zaxis
				axis=[@edit_transform.xaxis,@edit_transform.yaxis,@edit_transform.zaxis]
				list_axis=["X","Y","Z"]
				if mode==0 || mode==90
					prompts = [Strings.GetString("Axis?"),Strings.GetString("Tolerance?")]
					defaults =[list_axis[@axis],roundnumber(@tolerance.radians,2)]
					list=["X|Y|Z",""]
					input = UI.inputbox(prompts, defaults,list, Strings.GetString("Select Axis"))  
					if input
						@axis=list_axis.index(input[0])
						vectorz =axis[@axis] 
						@tolerance=input[1].to_f.degrees
					end
					if mode==0
						faces=sels.select{|e| (e.is_a?Sketchup::Face) && ((roundnumber(e.normal.angle_between(vectorz)-mode.degrees).abs<=@tolerance)||
																	  (roundnumber(e.normal.angle_between(vectorz)-Math::PI).abs<=@tolerance))}
					else
						faces=sels.select{|e| (e.is_a?Sketchup::Face) && ((roundnumber(e.normal.angle_between(vectorz)-mode.degrees).abs<=@tolerance))}
					end
				else                      
					prompts = [Strings.GetString("Axis?"),Strings.GetString("Min slope?"),Strings.GetString("Max slope?")]
					defaults =(@min_slope && @max_slope) ? [list_axis[@axis],@min_slope,@max_slope] : [list_axis[@axis],0,180]
					list=["X|Y|Z"]
					input = UI.inputbox(prompts, defaults,list, Strings.GetString("Enter slope"))              
					if input
						@axis=list_axis.index(input[0])
						vectorz =axis[@axis] 
						@min_slope=input[1].to_f
						@max_slope=input[2].to_f
						faces=sels.select{|e| (faces<< e) if (e.is_a?Sketchup::Face) && (roundnumber((e.normal.angle_between vectorz)-@min_slope.degrees)>=0) && (roundnumber(@max_slope.degrees-(e.normal.angle_between vectorz))>=0)}
					end  
				end                                 
			when "area"
				sels=[]
				sels= selection.empty? ? entities : selection
				prompts = [Strings.GetString("Min area?"),Strings.GetString("Max area?")]
				unit= Sketchup.format_area(0)[Sketchup.format_area(0).to_s.index(" ")..-1]  
				faces=sels.grep(Sketchup::Face)
				faces = faces.chunk { |f| f.area }.sort_by{|fs| fs[1].length}[-1][1] if faces && faces.length>0
				de= (faces && faces[0]) ? (Sketchup.format_area(faces[0].area).to_f.ceil.to_s) : "100"
				defaults=[@min_area.to_s+unit,@max_area.to_s+unit]
				defaults =(@min_area && !(faces && faces[0]) ) ?  [@min_area.to_s+unit,de+unit] : ["0"+unit,de+unit]
				input = UI.inputbox(prompts, defaults, Strings.GetString("Enter area face"))
				if input
					@min_area=input[0].to_f
					@max_area= input[1].to_f
					faces=sels.select{|e| (e.is_a?Sketchup::Face)&&((Sketchup.format_area e.area).to_f>=@min_area)&&((Sketchup.format_area e.area).to_f<=@max_area)}                        
				end                 
			when "numver"
				sels=[]
				sels= selection.empty? ? entities : selection
				if sels.length>0
					prompts = [Strings.GetString("Number?(>=3)")]
					defaults =@numver ? [@numver] : [4]
					input = UI.inputbox prompts, defaults, Strings.GetString("Enter number vertices")                
					if input
						numver=input[0].to_i  
						if numver>=3  
							@numver=numver
							faces=sels.select{|e| (e.is_a?Sketchup::Face) && (get_numvers(e)==@numver)}                          
						end
					end
				end
			when "same_area"
				if selection.length>0
					selection.each{|f| faces+=entities.select{|e| (f.is_a?Sketchup::Face) && (e.is_a?Sketchup::Face) && (roundnumber(f.area-e.area)==0)}}  
				else 
					UI.messagebox Strings.GetString("Select first face")
				end
			when "parallel"
				if selection.length>0
					selection.each{|f| faces+=entities.select{|e| (f.is_a?Sketchup::Face) && (e.is_a?Sketchup::Face) && (f.normal.samedirection? e.normal) } }  		
				else 
					UI.messagebox Strings.GetString("Select first face")
				end
			when "step"
				if selection.length>0 
					prompts = [Strings.GetString("Horizontal Step?"),Strings.GetString("Vertical Step?")]
					defaults = (@horizontal_step & @vertical_step) ? [@horizontal_step,@vertical_step] : [1,1]
					input = UI.inputbox(prompts,defaults,Strings.GetString("Enter Step Select."))
					if input 
						@horizontal_step=input[0].to_i
						@vertical_step=input[1].to_i                         
						selection.each{|s|
							if s.is_a?Sketchup::Face
								@sels1=[];@sels=[]
								@sels1<< s;@sels<< s
								find_select(s,0,@horizontal_step,0) 
								faces+= @sels1
								@sels1.each{|e| find_select(e,0,@vertical_step,1)}
								faces+=@sels1
							end        
						}   
					end
				else 
					UI.messagebox Strings.GetString("Select first face")
				end
			end
			selection.clear
			faces.uniq!
			if faces.empty? 
				Sketchup.set_status_text Strings.GetString("No selected face")           
			else
				Sketchup.set_status_text Strings.GetString(faces.length.to_s + " selected faces")
				faces.each{|f| selection.add f.edges ; selection.add f }
			end
		end
		def self.find_select(fa,index,step,direct)
			(0..fa.edges.length-1).each{|i|
				ed=fa.edges[i]
				direct1=i.divmod(2)[1]             
				(0..ed.faces.length-1).each{|j|  
					f =  ed.faces[j]
					index1=index
					if not @sels.include?(f)
						@sels<< f
						if index1==step 
							index1=0
							@sels1<< f
						else
							index1+=1
						end   
						find_select(f,index1,step,direct)
					end
				} if direct1==direct
			}           
		end  
		def self.axes_edit_transform()
			model=Sketchup.active_model
			return model.axes.transformation if Sketchup.version.to_i>=16
			model.start_operation "get edit transform"
			ents=model.active_entities  
			begin   
				g=ents.add_group(ents.add_group) 
				t=Geom::Transformation.new(g.transformation.xaxis,g.transformation.yaxis,g.transformation.zaxis,g.transformation.origin)
				g.erase! if g && g.valid? && !g.deleted? 
			rescue
				t=model.edit_transform
			end
			model.abort_operation
			return t
		end
		def self.main(function)
		    @edit_transform=self.axes_edit_transform
			case function
			when 0
				select_edge 90
			when 1
				select_edge 0
			when 2
				select_edge "slope"
			when 3
				select_edge "length"
			when 4
				select_face 90
			when 5
				select_face 0
			when 6
				select_face "slope"
			when 7
				select_face "numver"
			when 8
				select_face "area"             
			when 9
				select_edge "same_length"
			when 10
				select_face "same_area"        
			when 11
				select_face "parallel"
			when 12
				select_face "step"
			end
		end        
end
