# Copyright 2004, Rick Wilson 

# 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 :          Windowizer 3.0b5
# Description :   makes storefront windows from selected quadrilaterals
# Author :        RW
# Usage :         select faces, set preferences,
#                 and POOF! - windows!
# Date :          16.Jul.2004
# Type :		tool
# History:
#			3.0b6 (6/22/2005) - fixed "edit" bug
#			3.0b5 (5/12/2005) - added support for multiple erase
#						  added drop-down material selection
#			3.0b4 (1/25/2005) - added "edit" function
#			3.0b3 (1/25/2005) - added "inherit" and "erase" functions
#			3.0b2 (1/24/2005) - added nonQuadrilateral simple windows
#						- added attribute handling
#			3.0b1	(1/20/2005) - added proportional rows/columns
#			2.3 (15.Dec.2004) - fixed bounded face verification bug
#			2.2 (15.Sep.2004) - fixed group/component bug
#			2.1 (17.Aug.2004) - fixed floating point bug in dialog box
#						- fixed context menu validation bug
#						- fixed selection validation bug
#			2.0 (12.Aug.2004) - added features: corner selections, non-bounded face support,
#						  multiple face support
#			1.1e(26.Jul.2004) - metric support
#			1.1d(23.Jul.2004) - new selection filters; added flush corner & floor windows
#			1.1c(23.Jul.2004) - revised the revision to correct 0 col/row glitch
#			1.1 (23.Jul.2004) - revised to correct vector bugs resulting in
#						  strange windows outside of frames
#			1.0 (16.Jul.2004) - first version

require 'sketchup.rb'
#require 'offset.rb'
#require 'arraysum.rb'
require 'getMaterials.rb'
require 'EntsGetAtt.rb'

class Array
	def sum
		x=nil
		0.upto(self.length-1) do |e|
			if ((self[e].class==Fixnum) || (self[e].class==Float))
				x = x + self[e] if x!=nil
				x = self[e] if x==nil
			end
		end
		return x
	end
end

class Sketchup::Face
	def offset(dist)
		pi=Math::PI
		if (not ((dist.class==Fixnum || dist.class==Float || dist.class==Length) && dist!=0))
			return nil
		end
		verts=self.outer_loop.vertices
		pts=[]
		0.upto(verts.length-1) do |a|
			vec1=(verts[a].position-verts[a-(verts.length-1)].position).normalize
			vec2=(verts[a].position-verts[a-1].position).normalize
			vec3=(vec1+vec2).normalize
			if vec3.valid?
				ang=vec1.angle_between(vec2)/2
				ang=pi/2 if vec1.parallel?(vec2)
				vec3.length=dist/Math::sin(ang)
				t=Geom::Transformation.new(vec3)
				if pts.length > 0
					if not (vec2.parallel?(pts.last.vector_to(verts[a].position.transform(t))))
						t=Geom::Transformation.new(vec3.reverse)
					end
				end
				pts.push(verts[a].position.transform(t))
			end
		end
		Sketchup.active_model.active_entities.add_face(pts)
	end
end

class Wdw
end

class Windowizer

def initialize
	@model = Sketchup.active_model
	@entities = @model.active_entities
	@materials=@model.materials
	if not defined? $framewidth
		$vPanes = nil
		$hPanes = nil
		$framewidth = 2.inch
		$frameheight = 2.inch
		$mullwidth = 2.inch
		$mullheight = 2.inch
		$frameinset = 4.inch
		$glassinset = 2.inch
		$framecolor = "DimGray"
		$glasscolor = "Blue Glass"
	end
	$allSame=nil if $allSame!="edit"
	add_paint()							#ADD DEFAULT PAINT COLORS IF NECESSARY
	activate
end

#	FIND THE INSET FACE

def find_face(face1,face2,discard)
	$face=nil
	face1edges=face1.edges
	face2edges=face2.edges
	0.upto(3) do |a|
		0.upto(3) do |b|
			if ((face1edges[a] != face2edges[b]) and (face1edges[a].common_face(face2edges[b]) != discard ))
				if ((face1edges[a].common_face(face2edges[b]) != face1) and (face1edges[a].common_face(face2edges[b]) != face2))
					if (face1edges[a].common_face(face2edges[b]))
						return face1edges[a].common_face(face2edges[b])
						#face = face1edges[a].common_face(face2edges[b])
					end
				end
			end
		end
	end
end

#	FIND THE LOWEST 2 POINTS ON THE SELCTED FACE

def find_lowPoints(face)
	fVerts=face.vertices
	low1=fVerts[0]
	low2=low1
	0.upto(3) do |a|
		fVertsZ1=fVerts[a].position[2]
		if (fVertsZ1 <= low2.position[2])
			low2=fVerts[a]
		end
		if (fVertsZ1 <= low1.position[2])
			low2=low1
			low1=fVerts[a]
		end
	end
	0.upto(3) do |a|
		edge=face.edges[a]
		if ((edge.used_by?(low1)) && (edge.used_by?(low2)))
			$lowE=a
		end
	end
end

#	PAINT THE INSET FACES

def insetPaint(face)
	$faceEdges = face.edges					#Select edges so we know where we've been
	if $glassinset != 0
		face.pushpull (- $glassinset)			#Inset the glass
		discard=$faceEdges[0].faces[0]		#These lines find the new inset face
		face1=$faceEdges[0].faces[1]			# |
		face2=$faceEdges[1].faces[1]			# |
		face=find_face(face1,face2,discard)		#_V____
		#HERE IS WHERE TO SET ATTRIBUTE FOR GLASS
	end
	face.material=$glasscolor				#Paint the new inset face
	face.attribute_dictionary("WindowizerPane", true)				#CREATE THE ATTRIBUTE DICTIONARY (AD) FOR THIS OBJECT
	face.set_attribute("WindowizerPane","Frame",$wName)				#ATTRIBUTES: Parent frame name
	face.set_attribute("WindowizerPane","Material",face.material.name)	#ATTRIBUTES: Glass Material
	face.delete_attribute("WindowizerFrame")
end

#	BEGIN THE MAIN ROUTINE

def activate
	s = @model.selection
	$ss=[]
	$unb=[]
	$bnd=[]
	$unbNQ=[]
	$bndNQ=[]
	$nonQuad=[]


#		CHECK THE SELECTIONS!

	0.upto(s.length-1) do |x|
		$ss.push(s[x]) if ((s[x].class == Sketchup::Face) && (s[x].edges.length == 4))
		$nonQuad.push(s[x]) if((s[x].class == Sketchup::Face) && (s[x].edges.length != 4))
	end

	s.clear
	return UI.messagebox("No faces selected") if ($ss.empty? && $nonQuad.empty?)
	@model.start_operation "Windowizer" if $allSame!="edit"

	if $ss.length>1
		same = UI.messagebox("Use same settings for all quadrilateral faces?", MB_YESNO)
	else
		same=6
	end

	if not $ss.empty?
		if same==6
			$windowizerMode="edit" if $allSame=="edit"
			$allSame=true if $allSame!="edit"
			return nil if windowizer_settings().to_s=="end"
			$allSame=true if $allSame=="edit"
		end
	end

#	DO QUADRILATERAL FACES

#		CHECK FOR FACE-IN-A-FACE

	while $ss.length > 0
		bounded = nil
		ssEdges=$ss.first.edges
		0.upto(ssEdges.length-1) do |e|
			if ((ssEdges[e-1].faces == ssEdges[e].faces) && (ssEdges[e].faces.length == 2))
				bounded = true
			end
		end
		if bounded == true
			$bnd.push($ss.first)				#IS A FACE-IN-FACE
		else
			$unb.push($ss.first)				#NOT A FACE-IN-FACE
		end
		$ss.shift
	end

	$allSame=true if $allSame=="edit"
	$bnd.each {|bb| bounded(bb)}
	$unb.each {|bb| unbounded(bb)}
	$bnd=$unb=$ss=$allSame=nil
	@model.selection.clear
	@model.commit_operation if $allSame!="edit"

	@model.start_operation "windowizerNQ" if $allSame!="edit"
#	DO NON-QUADRILATERAL FACES

	if $nonQuad.length>1
		same = UI.messagebox("Use same settings for all non-quadrilateral faces?", MB_YESNO)
	else
		same=6
	end

	if not $nonQuad.empty?
		if same==6
			$allSame=true if $allSame!="edit"
			return nil if windowizer_settings().to_s=="end"
		end
	end

#		CHECK FOR FACE-IN-A-FACE

	while $nonQuad.length > 0
		bounded = nil
		ssEdges=$nonQuad.first.edges
		0.upto(ssEdges.length-1) do |e|
			if ((ssEdges[e-1].faces == ssEdges[e].faces) && (ssEdges[e].faces.length == 2))
				bounded = true
			end
		end
		if bounded == true
			$bndNQ.push($nonQuad.first)				#IS A FACE-IN-FACE
		else
			$unbNQ.push($nonQuad.first)				#NOT A FACE-IN-FACE
		end
		$nonQuad.shift
	end

	$allSame=true if $allSame=="edit"
	$bndNQ.each {|bb| boundedNQ(bb)}
	$unbNQ.each {|bb| unboundedNQ(bb)}
	$bndNQ=$unbNQ=$nonQuad=$allSame=nil
	@model.selection.clear
	@model.commit_operation if $allSame!="edit"
end

#		DEFAULT SETTINGS - PROMPT THE USER FOR THE WINDOWIZER SETTINGS

def windowizer_settings
	if $allSame=="edit"
		#puts $allSame.to_s + " - got to default settings section"
		if ((not defined? $vPanes) || ($vPanes==nil))
			$vPanes=2
			puts $vPanes
		end
		if ((not defined? $hPanes) || ($hPanes==nil))
			$hPanes=2 
			puts $hPanes
		end
	end
	if not $allSame=="edit"
		$vPanes=$vPanes.to_s if $vPanes.class==Fixnum
		$vPanes=$vPanes.join(",") if $vPanes.class==Array
		$hPanes=$hPanes.to_s if $hPanes.class==Fixnum
		$hPanes=$hPanes.join(",") if $hPanes.class==Array
		mats=getMaterials
		
		if $allSame == true
			enums = ['','','','','','','','',mats,mats]
			prompts = ["Rows", "Columns", "Frame Width", "Frame Height", "Mullion Width", "Mullion Height                              ", "Frame Inset", "Glass Inset", "Frame Color", "Glass Color"]
			values = [$vPanes, $hPanes, $framewidth, $frameheight, $mullwidth, $mullheight, $frameinset, $glassinset, $framecolor, $glasscolor]
			results = inputbox prompts, values, enums, "Windowizer Settings"
		else
			enums = ['','','','','','','',mats,mats]
			prompts = ["Rows", "Columns", "Frame Width", "Frame Height", "Mullion Width", "Mullion Height                              ", "Glass Inset", "Glass Color"]
			values = [$vPanes, $hPanes, $framewidth, $frameheight, $mullwidth, $mullheight, $glassinset, $glasscolor]
			results = inputbox prompts, values, enums, "Windowizer Settings"
		end
		if not results
			return "end"
		end	
	
		if $allSame == true
			$vPanes,$hPanes,$framewidth,$frameheight,$mullwidth,$mullheight,$frameinset,$glassinset,$framecolor,$glasscolor=results
		else
			$vPanes,$hPanes,$framewidth,$frameheight,$mullwidth,$mullheight,$glassinset,$glasscolor=results
		end
	end
#				CHECK PANES VARIABLES FOR ARRAYS

	if $vPanes.class == String
		if (not $vPanes.index(','))
			$vPanes=$vPanes.to_i
		else
			$vPanes=$vPanes.split(',')
			0.upto($vPanes.length-1) do |p|
				$vPanes[p]=$vPanes[p].to_i
				$vPanes[p]=1 if $vPanes[p]==0
			end
		end
	else
		($vPanes=1 if $vPanes<1) if $vPanes.class != Array
	end
	if $hPanes.class == String
		if (not $hPanes.index(','))
			$hPanes=$hPanes.to_i
		else
			$hPanes=$hPanes.split(',')
			0.upto($hPanes.length-1) do |p|
				$hPanes[p]=$hPanes[p].to_i
				$hPanes[p]=1 if $hPanes[p]==0
			end
		end
	else
		($hPanes=1 if $hPanes<1) if $hPanes.class != Array
	end

	if $vPanes.class==Fixnum
		$vPanes=1 if $vPanes<1
	end
	if $hPanes.class==Fixnum
		$hPanes=1 if $hPanes<1
	end

	$framewidth = 0.25.inch if $framewidth <= 0.inch
	$frameheight = 0.25.inch if $frameheight <= 0.inch
	$mullwidth = 0.25.inch if $mullwidth <= 0.inch
	$mullheight = 0.25.inch if $mullheight <= 0.inch
#	$frameinset = 0.5.inch if $frameinset == 0.inch
#	$glassinset = 0.5.inch if $glassinset == 0.inch
end

#		ADD THE DEFAULT PAINTS

def add_paint()

#		ADD THE GLASS PAINT

	if ((@materials["Blue Glass"] == nil) && (@materials["<Blue Glass>"] == nil))
		glass=@materials.add("Blue Glass")
		glass.color=[162,163,196]
		glass.alpha=0.6
	end

#		ADD THE FRAME PAINT

	if (@materials["DimGray"] == nil)
		frame=@materials.add("DimGray")
		frame.color="DimGray"
	end
end

# START BOUNDED FACE OPERATIONS

def bounded(face)
	if not $allSame
		Sketchup.active_model.selection.clear
		Sketchup.active_model.selection.add(face)
		prompts=["Frame Inset", "Frame Color"]
		values =[$frameinset, $framecolor]
		results=inputbox prompts, values, "Windowizer Settings"
		return nil if not results
		$frameinset = results[0]
		$framecolor = results[1]
	end
 	if $frameinset != 0
		$faceEdges = face.edges					#Select edges so we know where we've been
		face.pushpull (-$frameinset)	#Inset the frame
		$face_Edges = []
		0.upto($faceEdges.length-1) do |a|
			$face_Edges[$face_Edges.length]=$faceEdges[a] if ($faceEdges[a].valid?)	#Pass valid edges to new handler
		end

#FIX THIS SECTION FOR RARE INSTANCES THAT A 3-EDGE-BOUNDED FACE DOESN'T SELECT PROPERLY
#		face=nil
#		discard=$face_Edges[0].faces[0]				#These lines find the new inset face
#		face1=$face_Edges[0].faces[1]				# |
#		face2=$face_Edges[1].faces[1]				# |
#		face = nil							# |
#		face=find_face(face1,face2,discard)			#_V____
#END SECTION
#		0.upto($face_Edges.length-1) do |e|
#			if (($face_Edges[e-1].faces == $face_Edges[e].faces) && ($face_Edges[e].faces.length == 2))
#				discard = $face_edges[e-1].faces[0]
#			end
#		end
#END FIX THIS SECTION
		face=nil
		discard=$face_Edges[0].faces[0]				#These lines find the new inset face
		face1=$face_Edges[0].faces[1]				# |
		face2=$face_Edges[1].faces[1]				# |
		face = nil							# |
		face=find_face(face1,face2,discard)			#_V____
		face.attribute_dictionary("WindowizerFrame", true)		#CREATE THE ATTRIBUTE DICTIONARY (AD) FOR THIS OBJECT


	end
	$unb.push(face)
end

# START UNBOUNDED FACE OPERATIONS

def unbounded(face)
	frame=face
	if ($wName=frame.get_attributes("WindowizerFrame")["Name"])==nil
		$wName=Wdw.new.to_s.slice(6..14)
	end
	puts $wName
	if not $allSame
		@model.selection.clear
		@model.selection.add(face)
		return nil if windowizer_settings() == "end"
	end
	return if not face
	face.material=$framecolor				#PAINT THE NEW INSET FACE
	discard = nil
	discard = face						#THE INSET FACE IS NOW THE DISCARD FOR THE WINDOW PANES

	find_lowPoints(face)

	$edge1=face.edges[$lowE]				#PUT THE FACE EDGES IN A USABLE ORDER
	$edge2=face.edges[$lowE-3]
	$edge3=face.edges[$lowE-2]
	$edge4=face.edges[$lowE-1]

	if $hPanes.class==Fixnum
		$hLength1=($edge1.length-((2*$framewidth)+($mullwidth * ($hPanes - 1))))/$hPanes	#Glass length, bottom edge
		$hLength2=($edge3.length-((2*$framewidth)+($mullwidth * ($hPanes - 1))))/$hPanes	#Glass length, top edge
	else
		$hLength1=($edge1.length-((2*$framewidth)+($mullwidth * ($hPanes.length - 1))))/$hPanes.sum	#Glass length, bottom edge
		$hLength2=($edge3.length-((2*$framewidth)+($mullwidth * ($hPanes.length - 1))))/$hPanes.sum	#Glass length, top edge
	end
	if $vPanes.class==Fixnum
		$vLength1=($edge4.length-((2*$frameheight)+($mullheight * ($vPanes - 1))))/$vPanes	#Glass length, left edge
		$vLength2=($edge2.length-((2*$frameheight)+($mullheight * ($vPanes - 1))))/$vPanes	#Glass length, right edge
	else
		$vLength1=($edge4.length-((2*$frameheight)+($mullheight * ($vPanes.length - 1))))/$vPanes.sum	#Glass length, left edge
		$vLength2=($edge2.length-((2*$frameheight)+($mullheight * ($vPanes.length - 1))))/$vPanes.sum	#Glass length, right edge
	end

	if ($edge4.used_by?($edge1.start))
		$hpt1=Geom::Point3d.new($edge1.start.position)
	else
		$hpt1=Geom::Point3d.new($edge1.end.position)
	end

	0.upto(3) do |a|
		if (face.vertices[a].position == $hpt1)
			$hpt2=Geom::Point3d.new(face.vertices[a-3].position)
			$hpt3=Geom::Point3d.new(face.vertices[a-1].position)
			$hpt4=Geom::Point3d.new(face.vertices[a-2].position)
		end		
	end
	
	if ($edge1.start.position == $hpt1)
		$hVec1=$edge1.line[1]
	else
		$hVec1=$edge1.line[1].reverse
	end
	if ($edge3.start.position == $hpt4)	
		$hVec2=$edge3.line[1].reverse
	else
		$hVec2=$edge3.line[1]
	end
	if ($edge4.start.position == $hpt3)
		$vVec1=$edge4.line[1].reverse
	else
		$vVec1=$edge4.line[1]
	end
	if ($edge2.start.position == $hpt2)
		$vVec2=$edge2.line[1]
	else
		$vVec2=$edge2.line[1].reverse
	end

	if $vPanes.class==Fixnum
		$vP=$vPanes
	else
		$vP=$vPanes.length
	end
	if $hPanes.class==Fixnum
		$hP=$hPanes
	else
		$hP=$hPanes.length
	end
	$vStart1=$vStart2=0.0
	1.upto($vP) do |n|
 		$hStart1=$hStart2=0.0
		1.upto($hP) do |m|
			if $hPanes.class==Fixnum
				$hpt1x=$hpt1.offset($hVec1, ($framewidth+($mullwidth*(m-1))+($hLength1 * (m-1))))
				$hpt2x=$hpt1.offset($hVec1, ($framewidth+($mullwidth*(m-1))+($hLength1 * m)))
				$hpt3x=$hpt3.offset($hVec2, ($framewidth+($mullwidth*(m-1))+($hLength2 * (m-1))))
				$hpt4x=$hpt3.offset($hVec2, ($framewidth+($mullwidth*(m-1))+($hLength2 * m)))
			else
				$hpt1x=$hpt1.offset($hVec1, ($framewidth+($mullwidth*(m-1))+$hStart1))
				$hpt2x=$hpt1.offset($hVec1, ($framewidth+($mullwidth*(m-1))+$hStart1+($hLength1 * $hPanes[m-1])))
				$hpt3x=$hpt3.offset($hVec2, ($framewidth+($mullwidth*(m-1))+$hStart2))
				$hpt4x=$hpt3.offset($hVec2, ($framewidth+($mullwidth*(m-1))+$hStart2+($hLength2 * $hPanes[m-1])))

				$hStart1=$hStart1+($hLength1*$hPanes[m-1])
				$hStart2=$hStart2+($hLength2*$hPanes[m-1])
			end

			if $vPanes.class==Fixnum
				$vpt1x=$hpt1.offset($vVec1, ($frameheight+($mullheight*(n-1))+($vLength1 * (n-1))))	
				$vpt2x=$hpt1.offset($vVec1, ($frameheight+($mullheight*(n-1))+($vLength1 * n)))
				$vpt3x=$hpt2.offset($vVec2, ($frameheight+($mullheight*(n-1))+($vLength2 * (n-1))))
				$vpt4x=$hpt2.offset($vVec2, ($frameheight+($mullheight*(n-1))+($vLength2 * n)))
			else
				$vpt1x=$hpt1.offset($vVec1, ($frameheight+($mullheight*(n-1))+$vStart1))	
				$vpt2x=$hpt1.offset($vVec1, ($frameheight+($mullheight*(n-1))+$vStart1+($vLength1 * $vPanes[n-1])))
				$vpt3x=$hpt2.offset($vVec2, ($frameheight+($mullheight*(n-1))+$vStart2))
				$vpt4x=$hpt2.offset($vVec2, ($frameheight+($mullheight*(n-1))+$vStart2+($vLength2 * $vPanes[n-1])))
			end

			$line1=[Geom::Point3d.new($hpt1x), Geom::Point3d.new($hpt3x)]
			$line2=[Geom::Point3d.new($hpt2x), Geom::Point3d.new($hpt4x)]
			$line3=[Geom::Point3d.new($vpt1x), Geom::Point3d.new($vpt3x)]
			$line4=[Geom::Point3d.new($vpt2x), Geom::Point3d.new($vpt4x)]

			$pt0=Geom.intersect_line_line($line1, $line3)
			$pt1=Geom.intersect_line_line($line2, $line3)
			$pt2=Geom.intersect_line_line($line2, $line4)
			$pt3=Geom.intersect_line_line($line1, $line4)

			pts = []
			pts[0] = $pt0
			pts[1] = $pt1
			pts[2] = $pt2
			pts[3] = $pt3

			face = @entities.add_face pts
			insetPaint(face)
		end
		$vStart1=$vStart1+($vLength1*$vPanes[n-1])
		$vStart2=$vStart2+($vLength2*$vPanes[n-1])
	end
	if $vPanes.class==Array
		vPanes=$vPanes.join(",")
	else
		vPanes=$vPanes.to_s
	end
	if $hPanes.class==Array
		hPanes=$hPanes.join(",")
	else
		hPanes=$hPanes.to_s
	end
	frame.attribute_dictionary("WindowizerFrame", true)			#CREATE THE ATTRIBUTE DICTIONARY (AD) FOR THIS OBJECT
	frame.set_attribute("WindowizerFrame","Name",$wName)			#ATTRIBUTES: Name
	frame.set_attribute("WindowizerFrame","vPanes",vPanes)
	frame.set_attribute("WindowizerFrame","hPanes",hPanes)
	frame.set_attribute("WindowizerFrame","fWidth",$framewidth)
	frame.set_attribute("WindowizerFrame","fHeight",$frameheight)
	frame.set_attribute("WindowizerFrame","mWidth",$mullwidth)
	frame.set_attribute("WindowizerFrame","mHeight",$mullheight)
	frame.set_attribute("WindowizerFrame","fInset",$frameinset)
	frame.set_attribute("WindowizerFrame","gInset",$glassinset)
	frame.set_attribute("WindowizerFrame","fColor",$framecolor)
	frame.set_attribute("WindowizerFrame","gColor",$glasscolor)

end

def boundedNQ(face)
	frame=face
	$wName=Wdw.new.to_s
	$wName.slice!(6..14)
	puts $wName
	if not $allSame
		Sketchup.active_model.selection.clear
		Sketchup.active_model.selection.add(face)
		prompts=["Frame Inset", "Frame Color"]
		values =[$frameinset, $framecolor]
		results=inputbox prompts, values, "Windowizer Settings"
		return nil if not results
		$frameinset = results[0]
		$framecolor = results[1]
	end
 	if $frameinset != 0
		$faceEdges = face.edges					#Select edges so we know where we've been
		face.pushpull (-$frameinset)	#Inset the frame
		$face_Edges = []
		0.upto($faceEdges.length-1) do |a|
			$face_Edges[$face_Edges.length]=$faceEdges[a] if ($faceEdges[a].valid?)	#Pass valid edges to new handler
		end

		face=nil
		discard=$face_Edges[0].faces[0]				#These lines find the new inset face
		face1=$face_Edges[0].faces[1]				# |
		face2=$face_Edges[1].faces[1]				# |
		face = nil							# |
		face=find_face(face1,face2,discard)			#_V____
		face.attribute_dictionary("WindowizerFrame", true)			#CREATE THE ATTRIBUTE DICTIONARY (AD) FOR THIS OBJECT
		face.set_attribute("WindowizerFrame","Name",$wName)			#ATTRIBUTES: Name
		face.set_attribute("WindowizerFrame","vPanes",$vPanes)
		face.set_attribute("WindowizerFrame","hPanes",$hPanes)
		face.set_attribute("WindowizerFrame","fWidth",$framewidth)
		face.set_attribute("WindowizerFrame","fHeight",$frameheight)
		face.set_attribute("WindowizerFrame","mWidth",$mullwidth)
		face.set_attribute("WindowizerFrame","mHeight",$mullheight)
		face.set_attribute("WindowizerFrame","fInset",$frameinset)
		face.set_attribute("WindowizerFrame","gInset",$glassinset)
		face.set_attribute("WindowizerFrame","fColor",$framecolor)
		face.set_attribute("WindowizerFrame","gColor",$glasscolor)

	end
	$unbNQ.push(face)

end

def unboundedNQ(face)
#	UI.messagebox("Got here")
	$wName=Wdw.new
	if not $allSame
		@model.selection.clear
		@model.selection.add(face)
		return nil if windowizer_settings() == "end"
	end
	return if not face
	face.material=$framecolor				#PAINT THE NEW INSET FACE
	newface=face.offset(-$framewidth)
	insetPaint(newface)
	face.attribute_dictionary("WindowizerFrame", true)			#CREATE THE ATTRIBUTE DICTIONARY (AD) FOR THIS OBJECT
	face.set_attribute("WindowizerFrame","Name",$wName)			#ATTRIBUTES: Name
	face.set_attribute("WindowizerFrame","vPanes",$vPanes)
	face.set_attribute("WindowizerFrame","hPanes",$hPanes)
	face.set_attribute("WindowizerFrame","fWidth",$framewidth)
	face.set_attribute("WindowizerFrame","fHeight",$frameheight)
	face.set_attribute("WindowizerFrame","mWidth",$mullwidth)
	face.set_attribute("WindowizerFrame","mHeight",$mullheight)
	face.set_attribute("WindowizerFrame","fInset",$frameinset)
	face.set_attribute("WindowizerFrame","gInset",$glassinset)
	face.set_attribute("WindowizerFrame","fColor",$framecolor)
	face.set_attribute("WindowizerFrame","gColor",$glasscolor)

end

def Windowizer.edit
	begin
	puts "Edit mode"
	@model=Sketchup.active_model
	sel=@model.selection
	ents=@model.active_entities

	@model.start_operation "Windowizer Edit"

	wName=sel.first.get_attribute("WindowizerPane", "Frame")
	wName=sel.first.get_attribute("WindowizerFrame", "Name") if not wName
	$frame=[]
	ents.each {|e| $frame.push(e) if e.get_attribute("WindowizerFrame", "Name")==wName}
#	puts $frame
	$frame=$frame.first
	$tvPanes=$frame.get_attribute("WindowizerFrame","vPanes")
	$thPanes=$frame.get_attribute("WindowizerFrame","hPanes")
	$tframewidth=$frame.get_attribute("WindowizerFrame","fWidth")
	$tframeheight=$frame.get_attribute("WindowizerFrame","fHeight")
	$tmullwidth=$frame.get_attribute("WindowizerFrame","mWidth")
	$tmullheight=$frame.get_attribute("WindowizerFrame","mHeight")
	$tframeinset=$frame.get_attribute("WindowizerFrame","fInset")
	$tglassinset=$frame.get_attribute("WindowizerFrame","gInset")
	$tframecolor=$frame.get_attribute("WindowizerFrame","fColor")
	$tglasscolor=$frame.get_attribute("WindowizerFrame","gColor")

	$allSame="edit"
	if (UI.messagebox("Change to current settings?", MB_YESNO))==7
		mats=getMaterials
		prompts = ["Rows", "Columns", "Frame Width", "Frame Height", "Mullion Width", "Mullion Height          ", "Frame Inset", "Glass Inset", "Frame Color", "Glass Color"]
		values = [$tvPanes, $thPanes, $tframewidth, $tframeheight, $tmullwidth, $tmullheight, $tframeinset, $tglassinset, $tframecolor, $tglasscolor]
		enums = ['','','','','','','','',mats,mats]
		results = inputbox prompts, values, enums, "Change Current Window Settings"
		return nil if results==false
		$tvPanes,$thPanes,$tframewidth,$tframeheight,$tmullwidth,$tmullheight,$tframeinset,$tglassinset,$tframecolor,$tglasscolor=results

#					SAVE OLD SETTINGS
		vPanes=$vPanes
		hPanes=$hPanes
		framewidth=$framewidth
		frameheight=$frameheight
		mullwidth=$mullwidth
		mullheight=$mullheight
		frameinset=$frameinset
		glassinset=$glassinset
		framecolor=$framecolor
		glasscolor=$glasscolor
#					USE NEW SETTINGS
		$vPanes=$tvPanes
		$hPanes=$thPanes
		$framewidth=$tframewidth
		$frameheight=$tframeheight
		$mullwidth=$tmullwidth
		$mullheight=$tmullheight
		$frameinset=$tframeinset
		$glassinset=$tglassinset
		$framecolor=$tframecolor
		$glasscolor=$tglasscolor

		#sel.clear
		#sel.add($frame)
		#Windowizer.eraseOne
		Windowizer.erase
		sel.clear
		sel.add($frame)
		Windowizer.new

#					RESTORE OLD SETTINGS
		$allSame=nil
		$vPanes=vPanes
		$hPanes=hPanes
		$framewidth=framewidth
		$frameheight=frameheight
		$mullwidth=mullwidth
		$mullheight=mullheight
		$frameinset=frameinset
		$glassinset=glassinset
		$framecolor=framecolor
		$glasscolor=glasscolor
	else
		#sel.clear
		#sel.add($frame)
		#Windowizer.eraseOne
		Windowizer.erase
		sel.clear
		sel.add($frame)
		Windowizer.new
	end

	@model.commit_operation

rescue NoMethodError
	$stderr
	$allSame=nil
	raise
end
end


def Windowizer.inherit
	puts "Inherit mode"
	model=Sketchup.active_model
	ents=model.active_entities
	wName=model.selection.first.get_attribute("WindowizerPane", "Frame")
	wName=model.selection.first.get_attribute("WindowizerFrame", "Name") if not wName
	$frame=[]
	ents.each {|e| $frame.push(e) if e.get_attribute("WindowizerFrame", "Name")==wName}
#	puts $frame
	$frame=$frame.first
	$vPanes=$frame.get_attribute("WindowizerFrame","vPanes")
	$hPanes=$frame.get_attribute("WindowizerFrame","hPanes")
	$framewidth=$frame.get_attribute("WindowizerFrame","fWidth")
	$frameheight=$frame.get_attribute("WindowizerFrame","fHeight")
	$mullwidth=$frame.get_attribute("WindowizerFrame","mWidth")
	$mullheight=$frame.get_attribute("WindowizerFrame","mHeight")
	$frameinset=$frame.get_attribute("WindowizerFrame","fInset")
	$glassinset=$frame.get_attribute("WindowizerFrame","gInset")
	$framecolor=$frame.get_attribute("WindowizerFrame","fColor")
	$glasscolor=$frame.get_attribute("WindowizerFrame","gColor")

end


#def Windowizer.eraseOne
#	puts "EraseOne mode"
#	model=Sketchup.active_model
#	ents=model.active_entities
#	$ss=[]
#	edgeSet=[]
#	model.start_operation "Windowizer erase" if $allSame!="edit"
##				GET THE FRAME NAME FROM THE SELECTED PANE
#	wName=model.selection.first.get_attribute("WindowizerPane", "Frame")
#	wName=model.selection.first.get_attribute("WindowizerFrame", "Name") if not wName
##				GET ALL PANES W/ SAME PARENT FRAME
#	ents.each {|e| $ss.push(e) if e.get_attribute("WindowizerPane", "Frame")==wName}
#	puts $ss
##				GET ALL EDGES
#	$ss.each {|f| f.edges.each {|fe| fe.faces.each {|fef| edgeSet.push(fef.edges)}}}
#	edgeSet.flatten!.uniq!
##				ERASE EDGES
#	edgeSet.each {|e| e.erase!}
#	model.selection.clear
#	model.commit_operation if $allSame!="edit"
#end



def Windowizer.erase
	puts "Erase mode"
	model=Sketchup.active_model
	ents=model.active_entities
	sel=model.selection
	model.start_operation "Windowizer erase" if $allSame!="edit"
	wdws=[]
	sel.each {|se| wdws.push(se.get_attribute("WindowizerPane", "Frame"))}
	wdws.flatten!	
	wdws.uniq!
	wdws.delete(nil)
	for wName in wdws
		$ss=[]
		edgeSet=[]
#				GET ALL PANES W/ SAME PARENT FRAME
		ents.each {|e| $ss.push(e) if e.get_attribute("WindowizerPane", "Frame")==wName}
#		puts $ss
#				GET ALL EDGES
		$ss.each {|f| f.edges.each {|fe| fe.faces.each {|fef| edgeSet.push(fef.edges)}}}
		edgeSet.flatten!
		edgeSet.uniq!
#				ERASE EDGES
		edgeSet.each {|e| (e.erase! if e.valid?)}
		model.selection.clear
	end
	model.commit_operation if $allSame!="edit"
end



def Windowizer.validate_selection
	Sketchup.active_model.selection.each {|e| return true if e.class == Sketchup::Face}
	return nil
end

def Windowizer.validate_selection2
	return nil if Sketchup.active_model.selection.length > 1
	return true if not Sketchup.active_model.selection.first.attribute_dictionary("WindowizerPane")==nil
	return true if not Sketchup.active_model.selection.first.attribute_dictionary("WindowizerFrame")==nil
	return nil
end

def Windowizer.validate_selection3
	for e in Sketchup.active_model.selection
		return true if not e.attribute_dictionary("WindowizerPane")==nil
		return true if not e.attribute_dictionary("WindowizerFrame")==nil
	end
	return nil
end

end	#END CLASS WINDOWIZER

if( not file_loaded?("windowizer.rb") )
	UI.add_context_menu_handler do |menu|
		menu.add_separator
		submenu=menu.add_submenu("Windowizer")
			submenu.add_item("Windowize") { Windowizer.new } if (Windowizer.validate_selection)
			submenu.add_item("Edit Window") { Windowizer.edit } if (Windowizer.validate_selection2)
			submenu.add_item("Inherit Settings") { Windowizer.inherit } if (Windowizer.validate_selection2)
			submenu.add_separator if (Windowizer.validate_selection3)
			submenu.add_item("Erase Window") { Windowizer.erase } if (Windowizer.validate_selection3)
	end
end
#-----------------------------------------------------------------------------
file_loaded("windowizer.rb")


#if not file_loaded?("windowizer.rb")
#	UI.add_context_menu_handler do |menu|
#		menu.add_separator if (Windowizer.validate_selection)
# 		menu.add_item("Windowizer") { Windowizer.new } if (Windowizer.validate_selection)
#	end
#end
#
#-----------------------------------------------------------------------------
#file_loaded("windowizer.rb")
