=begin 

	GEOM2d_BOOLEANS since VER 1.3

	(C) Joel Gustafsson
-----------------------------------------------------------------------
	Permission to use, copy, modify and distribute this software 
	as long as above copyright notice is included.

	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.
------------------------------------------------------------------------
   
    # This module has basically the same functionality as old plugin, hopefully improved....
	
	# Since ver 1.3. Intersect with edges and not whole Sketchup::Face..
    # Removed 1 layer in loop since only 1 targetface is in use.
	# Intersection method was run twice in ver 1.2. Which slowed things down.
    # Face centers from Targetface are collected for removing face-holes later. (In case when there are no edges passing face.)
	# This should(?) be more predictable instead of face classify resulting face centers for removal.
	# New algoritm for Orient groups Z-AXIS to face normal ( for gluebehavior. )
	
	TODO: 
	* Turn into class? Code is quite procedual and only return 1 group.
	* Support multiple Targetfaces ? A component can only glue to 1 face..
	* 
	
=end


require 'sketchup.rb' # redundant ?

module GEOM2d_BOOLEANS

	def self.create_boolean( targetFace, gp, classify_mode )

		model = Sketchup.active_model 
		ents  = model.active_entities
		gents = gp.entities 
		
	  # Collect target face edges # ( was face clone.. )
		#
		centers = []
		edg_group = ents.add_group()
		edg_ents  = edg_group.entities
		
		targetFace.loops.each{ |loop| edg_ents.add_face( loop.vertices ) }  
		edg_ents.add_face( targetFace.outer_loop.vertices )  
		
		faces2go = edg_ents.grep( Sketchup::Face ).each{ |face|
			if classify_mode == Sketchup::Face::PointInside 
				centers.push( face.bounds.center.project_to_plane( targetFace.plane ) ) # fix Boolean subtract
			end
			face.edges.each{|edg|
				break unless edg.faces[1]
				break centers.push( face.bounds.center.project_to_plane( targetFace.plane ) )  #ver 1.3. stops from looping all edges after match.
			}
		}
		edg_ents.erase_entities( faces2go )
		
	  #	Intersect edges with group  #
	  # Better results than exploding, I think..
	  # Exploding edgegroup onto faces crashes materials sometimes. Also noticed this bug(?)
	  # http://sketchucation.com/forums/viewtopic.php?f=180&t=49646&hilit=+face+material
	  # No comments yet..
	    #
		tr = Geom::Transformation.new()
		gptr = edg_group.transformation
		gents.intersect_with( false, gptr, gents, tr, false, [edg_group] ) #intersected twice in 1.2 ??
		edg_group.erase! 
		
	  # Remove unwanted intersected geometry. The classify_mode determines which boolean mode is performed.
	  # 
		edges2go = gents.grep( Sketchup::Edge ).select{|edg|
			edg if targetFace.classify_point( edg.start ) == classify_mode && targetFace.classify_point( edg.end ) == classify_mode  
			edg if targetFace.classify_point( edg.bounds.center ) == classify_mode #ver 1.3 edg.bounds.center
		}
		gents.erase_entities( edges2go )
		
	  # HOLES. ver 1.3 face.centers point3D comparison. 
	  # This now avoids the classify face method which should be a performance improvement. REVIEW: reliability ?
	    #
		unless centers.empty?
			faces2go = gents.grep( Sketchup::Face ).select{|face| face if centers.include?( face.bounds.center ) }
			gents.erase_entities( faces2go )
		end
		
	  # ORIENT GROUP Z-AXIS aligned to face normal for glue behavior. ver 1.3
	  # During explosions transformations gets reset to global axis
		#
		tr = Geom::Transformation.new( targetFace.bounds.center.project_to_plane( targetFace.plane ), targetFace.normal )
		gp.transform!( tr ) # group to face 
		gents.transform_entities( tr.inverse, gents.to_a ) # entities to face
		gents.parent.invalidate_bounds # reset bbox 
			
		gp # group
		
	end # method
end # module