# Copyright 2008, Tomasz Marek
#------------------------------------------------------------------------
# I INVITE you to a while of reflection about a role of LOVE in our lives
# while using this tool, beacuse your brain will be quite idle durnig
# the process :) I kindly suggest you to spend saved time with ones
# that you love! :)
#------------------------------------------------------------------------
# Permission to use, copy, modify, and distribute this software for 
# any purpose and without fee is hereby granted, provided that the above
# copyright notice appear in all copies.

# 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 :			frontface.rb 1.2
# Description :		Hower over a back face to reverse it, visible material will be preserved
# Author :			Tomasz Marek
# Installation:		Copy to Sketchup/Plugins folder and restart SU
# Usage :			1. Active the Tool from the icon or Plugins menu, Left Click toggles revesing
#				2. Hover over a back-face to reverse it.
#				3. press CTRL to switch to mode when back face material is replaced by the default
# Date :			7th December 2009
# Type :			Tool
# History:			1.2 (7. Dec. 2009) - icons added, CTRL to replace back material with the default
#				1.1 (12.Oct.2008) - correct recognition of back faces
#					in nested components and groups
#				1.0 (11.Oct.2008) - first version

require 'sketchup.rb'

class FrontFaceTool

def initialize
	@ip = Sketchup::InputPoint.new
	cursor_path = Sketchup.find_support_file("FrontFaceCursor.png", "Plugins/FrontFace_files")
	if cursor_path
		@cursor_on = UI.create_cursor(cursor_path, 12, 12)
	end
	cursor_path = Sketchup.find_support_file("FrontFaceCursorOff.png", "Plugins/FrontFace_files")
	if cursor_path
		@cursor_off = UI.create_cursor(cursor_path, 12, 12)
	end
	cursor_path = Sketchup.find_support_file("FrontFace_OnDef.png", "Plugins/FrontFace_files")
	if cursor_path
		@cursor_on_def= UI.create_cursor(cursor_path, 12, 12)
	end
end

def reset
	@ip.clear
	@reverse=false
	@triger=true
	@default=false
	@triger_def=true
end

def activate
	self.reset
	Sketchup::set_status_text "Hover over a back face to reverse it"
end

def onSetCursor
	if @reverse
		if @default
			UI.set_cursor(@cursor_on_def) if @cursor_on_def
		else
			UI.set_cursor(@cursor_on) if @cursor_on
		end
	else
		UI.set_cursor(@cursor_off)
	end
end

def onLButtonDown(flags, x, y, view)
	@reverse=!@reverse if @triger
	@triger=false
end

def onLButtonUp(flags, x, y, view)
	@triger=true
end

def onMouseMove(flags, x, y, view)
	onSetCursor
	if @reverse
		@ip.pick(view,x,y)
		face = @ip.face
		if face!=nil
			camera=view.camera
			ray=view.pickray x,y
			face, side=examineFace(face,camera,ray)
			if side==false
				reverseFace(face)
				view.invalidate
			end
		end
	end
end

def draw(view)
	if @reverse
		view.draw_text([5,5], @default ? "Reversing and back material to default!" : "Reversing faces")
	end
end

def onKeyDown(key, repeat, flags, view)
	if key=VK_CONTROL
		@default=!@default
		onSetCursor
	end
end

def examineFace(face, camera, ray)
	model=Sketchup.active_model
	hit_point,family=model.raytest ray
	if hit_point != nil
			if family != nil
				if family.last.class==Sketchup::Face
					face=family.last
					family=findFaceBelow(hit_point, ray[1]) if (!face.visible? or !face.layer.visible?)

					if family != nil
						face=family.last
						trans=findGlobalTransformation(family)
						norm=face.normal
						norm.transform! trans
					end
				else
					norm=camera.direction.reverse
				end
			else
				norm=face.normal
			end
	end
	norm=camera.direction.reverse if norm==nil
	angle=camera.direction.angle_between norm

	return [face, angle>3.14159265/2.0]
end

	def findFaceBelow(hit_point, vector)
		model=Sketchup.active_model
		new_origin, new_family=model.raytest [hit_point, vector]
		if new_origin != nil
				if new_family != nil
					if new_family.last.class==Sketchup::Face
						face=new_family.last
						if (!face.visible? or !face.layer.visible?)
							family=findFaceBelow(new_origin, vector)
						else
							family=new_family
						end
					end
				end
		end
		return family
	end

def onCancel (reason, view)
	Sketchup.send_action("selectSelectionTool:")
end

def findGlobalTransformation(parents)
	trans=Geom::Transformation.new
	parents.each do |parent|
		trans=trans*parent.transformation if parent.class != Sketchup::Face
	end
	return trans
end

def reverseFace(face)
	face.reverse!
	if @default
		face.material, face.back_material = face.back_material, face.material
	else
		face.material, face.back_material = face.back_material, nil
	end
end

end # of FrontFace class


if( not file_loaded?("frontface.rb") )
	UI.menu("Plugins").add_item("Start FrontFace[TM] Tool") { Sketchup.active_model.select_tool FrontFaceTool.new }
	dir = Sketchup.find_support_file("Plugins")
	cmd = UI::Command.new("Start FrontFace Tool") { Sketchup.active_model.select_tool FrontFaceTool.new }
	cmd.large_icon = cmd.small_icon = dir+"/FrontFace_files/FrontFaceIcon.png"
	cmd.status_bar_text = cmd.tooltip = "Tool for reversing back faces"
	tb = UI::Toolbar.new("FrontFace(TM)")
	tb.add_item cmd
	tb.show if tb.get_last_state == -1
end

file_loaded("frontface.rb")