# Supports Organizer.rb
=begin rdoc

= Parking.rb
Copyright 2005-2014 by Rick Wilson - All Rights Reserved

== Disclaimer
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.

== License
This software is distributed under the Smustard End User License Agreement
http://www.smustard.com/eula

== Information
Author:: Rick Wilson
Organization:: Smustard
Name:: Parking
Version:: 1.4.1
SU Version:: 4.0
Date:: 2014-04-30
Description:: Draw parking lot lines

Usage::
* 1:: select "Plugins>Draw Parking Spaces" and select first point, then type a distance or select a second point
* 2:: to toggle direction of the parking lines:	 	press the ] key 	or right-click
* 3:: to toggle between Absolute and Minimum width:	press the [ key 	or shift + right-click
	
History::
* 1.0.0:: 2005-06-28
	* first version
* 1.1.0:: 2005-07-14
	* added angled parking, separated settings into its own menu item/dialog
* 1.2.0:: 2010-09-21
	* updated code to fully utilize the ParkingTool class
* 1.3.0:: 2012-06-08
	* updated to provide option for absolute (non-varying) width
	* added new feature to reverse parking lines direction relative to the baseline
* 1.4.0:: 2014-05-02
	* wrapped in module Smustard
	* packaged for the EW
* 1.4.1:: 2014-05-16
	* version 1.4.0 works in SU 2014, but a code block didn't work in earlier versions (due to changes in Ruby).  Fixed this to work in all versions.


ToDoList::
	* 
	* 

=end


module Smustard
	
	if ($submenu) # legacy programs creating a global
		Smustard::Submenu = $submenu unless Smustard.constants.include?("Submenu")
	else
		Smustard::Submenu = nil unless Smustard.constants.include?("Submenu")
	end
	

	if ($smustard_toolbar)	# legacy programs creating a global
		Smustard::Toolbar = $smustard_toolbar unless Smustard.constants.include?("Toolbar")
			
	else
		Smustard::Toolbar = UI::Toolbar.new("Smustard") unless Smustard.constants.include?("Toolbar")
			
	end

class ParkingTool < LineTool
	
	@@parking_width_type = "Absolute"
	@@parking_width = 9.feet
	@@parking_depth = 18.feet
	@@parking_angle = 90
	@@reverse_direction = false
	
	@@firstrun = true
	
	@@cmd_parking = UI::Command.new("Draw Parking"){ Sketchup.active_model.select_tool(ParkingTool.new()) }
	@@cmd_parking.tooltip = "Parking"
	@@cmd_parking.status_bar_text = "Draw parking spaces with two clicks"
	@@cmd_parking.large_icon = "ParkingToolLarge.png"
	@@cmd_parking.small_icon = "ParkingToolSmall.png"
	
	@@cmd_parking_settings = UI::Command.new("Parking Settings"){ Sketchup.active_model.select_tool(ParkingTool.new(true)) }
	@@cmd_parking_settings.tooltip = "Parking Settings"
	@@cmd_parking_settings.status_bar_text = "Review/Modify the Parking Tool settings"
	@@cmd_parking_settings.large_icon = "ParkingToolSettingsLarge.png"
	@@cmd_parking_settings.small_icon = "ParkingToolSettingsSmall.png"
	
	attr_accessor :type, :width, :depth, :angle
	
	

	def initialize(doSettings=false)
		
		settings() if doSettings || @@firstrun
		
		@type = @@parking_width_type
		@width = @@parking_width
		@depth = @@parking_depth
		@angle = @@parking_angle
		super()
		
	end



	# Create new geometry when the user has selected two points.
	def create_geometry(pt1, pt2, view)
		ents = view.model.active_entities
		dist = pt1.distance(pt2)
		#vec1 = width = pt2-pt1
		vec1 =  pt2-pt1
		vec2 = Geom::Vector3d.new(vec1.y,-vec1.x,0.0)
		vec2.reverse! if @@reverse_direction
		
		if vec2.length>0
			vec2.length = @depth
			width = @width
			
			if @angle != 90
				trans = Geom::Transformation.rotation(pt1, Geom::Vector3d.new(0,0,1), (@angle-90).degrees)
				vec2.transform!(trans)
				#vec2.length = @depth + (((Math::sin(90-@angle.abs).degrees)*@width)/(Math::sin(@angle.degrees))) if vec2.length!=0
				vec2.length = @depth + ((Math::sin((90-@angle).degrees)/Math::sin(@angle.degrees))*@width)
				width = @width/(Math::sin(@angle.degrees))
			end
			
			spaces = (dist/width).to_i
			
			if @@parking_width_type=="Minimum"
				#width.length = dist/spaces.to_f if width.length>0
				width = dist/spaces.to_f if width > 0
			end

			#puts("Calculated #{spaces} spaces at #{@@parking_width_type} #{@width.to_s}; Calculated stall width: #{width.inch.to_s}")
			
			pt3 = pt1.transform(vec2)
			view.model.start_operation("Parking lines")
			#ents.add_edges(pt3,pt1,pt2)
			ents.add_edges(pt1,pt3)

			vec3 = vec1.clone
			vec3.length = width
			#ents.add_line(pt1,pt3)
			
			1.upto(spaces) do |i|
				pt0=pt1.clone
				pt1.transform!(vec3)
				pt3.transform!(vec3)
				#ents.add_line(pt1,pt3)
				ents.add_edges(pt3,pt1,pt0)
			end
			
			view.model.commit_operation
			
		end
		
	end



	# Draw the geometry on screen
	def draw_geometry(pt1, pt2, view)
		ents = view.model.active_entities
		dist = pt1.distance(pt2)
		#vec1 = (width = pt2-pt1).clone
		vec1 = pt2-pt1
		vec2 = Geom::Vector3d.new(vec1.y,-vec1.x,0.0)
		vec2.reverse! if @@reverse_direction
		#vec2.length = @depth if vec2.length>0
		if vec2.length > 0
			vec2.length = @depth
			width = @width
			
			if @angle != 90
				trans = Geom::Transformation.rotation(pt1, Geom::Vector3d.new(0,0,1), (@angle-90).degrees)
				vec2.transform!(trans)
				#vec2.length = @depth + (((Math::sin(@angle-90).abs.degrees)*@width)/(Math::sin(@angle.degrees))) if vec2.length!=0
				vec2.length = @depth + ((Math::sin((90-@angle).degrees)/Math::sin(@angle.degrees))*@width)
				width = @width/(Math::sin @angle.degrees)
			end
			
			spaces = (dist/width).to_i
			
			if @@parking_width_type=="Minimum"
				width = dist/spaces.to_f if width > 0
			end
			
			Sketchup.set_status_text("Calculated #{spaces} spaces at #{@@parking_width_type} #{@width}; Calculated stall width: #{width.inch.to_s}")
			
			pt3 = pt1.transform(vec2)
			view.draw_line(pt1,pt2)
			view.draw_line(pt1,pt3)
			vec3 = vec1.clone
			vec3.length = width
			
			1.upto(spaces) do |i|
				#puts "Creating view geometry #{i} of #{spaces}"
				pt1.transform!(vec3)
				pt3.transform!(vec3)
				view.draw_line(pt1,pt3)
			end
			
		end
		
	end
	
	

	def onRButtonDown(flags,x,y,view)
		case flags
			when 2 # right click only
				@@reverse_direction ? @@reverse_direction = false : @@reverse_direction = true
			when 6 # SHIFT + right click
				@@parking_width_type == "Absolute" ? @@parking_width_type = "Minimum" : @@parking_width_type = "Absolute"
		end
	end


	
	def onKeyUp(key,repeat,flags,view)
		if( key == CONSTRAIN_MODIFIER_KEY &&
			view.inference_locked? &&
			(Time.now - @shift_down_time) > 0.5 )
			view.lock_inference
		end
		#puts key
		case key
			when 219 # left bracket [
				#puts "toggle absolute/relative"
				@@parking_width_type == "Absolute" ? @@parking_width_type = "Minimum" : @@parking_width_type = "Absolute"
			when 221 # right bracket ]
				#puts "toggle direction"
				@@reverse_direction ? @@reverse_direction = false : @@reverse_direction = true
			#else
			#	deactivate(Sketchup.active_model.active_view)
		end
		
	end



	def settings()
		@@parking_angle = 30 if @@parking_angle<30
		@@parking_angle = 150 if @@parking_angle>150
		prompts = ["Width Type", "Width","Depth","Angle (degrees)"]
		values = [@@parking_width_type,@@parking_width,@@parking_depth,@@parking_angle]
		options = ["Absolute|Minimum","","",""]
		results = inputbox prompts, values, options, "Parking Settings"
		if results != false
			@@parking_width_type,@@parking_width,@@parking_depth,@@parking_angle = results
			@@firstrun = false if @@firstrun
		else
			return nil
		end
	end
	
	
	
	def ParkingTool.settings()
		settings()
	end
	
	
	
	def ParkingTool.build_ui()
		Smustard::Submenu ? (organizer = Smustard::Submenu) : (organizer = UI.menu("Plugins"))
		
		Smustard::Toolbar.add_item(@@cmd_parking)
		Smustard::Toolbar.add_item(@@cmd_parking_settings)

		submenu = organizer.add_submenu("Parking Spaces")
			submenu.add_item(@@cmd_parking)
			submenu.add_item(@@cmd_parking_settings)

	end

end # class ParkingTool

end # module Smustard

unless file_loaded?(__FILE__)
	file_loaded(__FILE__)
	Smustard::ParkingTool.build_ui

end

