=begin
#-------------------------------------------------------------------------------------------------------------------------------------------------
#*************************************************************************************************
# Designed April / July 2008 by Fredo6

# Permission to use this software for any purpose and without fee is hereby granted
# Distribution of this software for commercial purpose is subject to:
#  - the expressed, written consent of the author
#  - the inclusion of the present copyright notice 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			:   LoaderOnSurface.rb
# Original Date	:   04 June 2008 - version 1.2
#					31 Jul 2009 - version 1.5
# Type			:   Sketchup Tools
# Description	:   Loader for the Suite of Tools to draw on a surface
# Menu Items	:   Tools --> submenu "Tools on Surface"
# Toolbar		:   Name = "Tools on Surface"
# Usage			:   See Tutorial and Quick Ref Card in PDF format
#-------------------------------------------------------------------------------------------------------------------------------------------------
#*************************************************************************************************
=end

module F6_SUToolsOnSurface

#---------------------------------------------------------------------------------------------------------------------------
# Overall Configuration for the Tools	
#---------------------------------------------------------------------------------------------------------------------------

MENU_PERSO = [:T_MenuTools_Fredo6Collection, "Tools", :T_MenuPlugins_Fredo6Collection, "Plugins"]

#---------------------------------------------------------------------------------------------------------------------------
#Constants for TOS  Modules (do not translate here, use Translation Dialog Box instead)	
#---------------------------------------------------------------------------------------------------------------------------

#Menu and Toolbar icons
T6[:TOS_GENERIC_Menu] = "Generic Tools on Surface"
T6[:TOS_GENERIC_Tooltip] = "Start any tool and keep it persistent during session"
TOS_GENERIC_Icon = "Generic"

T6[:TOS_LINE_Menu] = "Line on Surface"
T6[:TOS_LINE_Tooltip] = "Draw Lines and Construction Lines on Surface"
TOS_LINE_Icon = "Line"

T6[:TOS_OFFSET_Menu] = "Offset on Surface"
T6[:TOS_OFFSET_Tooltip] = "Draw offset contours on Surface"
TOS_OFFSET_Icon = "Offset"

T6[:TOS_FREEHAND_Menu] = "Free Hand on Surface"
T6[:TOS_FREEHAND_Tooltip] = "Free Hand on Surface (without inference)"
TOS_FREEHAND_Icon = "Freehand"

T6[:TOS_POLYLINE_Menu] = "Edit Contours on Surface"
T6[:TOS_POLYLINE_Tooltip] = "Interactive edition of contours on surface"
TOS_POLYLINE_Icon = "Polyline"

T6[:TOS_ERASER_Menu] = "Eraser on Surface"
T6[:TOS_ERASER_Tooltip] = "Eraser on Surface (remove edges)"
TOS_ERASER_Icon = "Eraser"

T6[:TOS_VOIDTRIANGLE_Menu] = "Repair small empty triangles"
T6[:TOS_VOIDTRIANGLE_Tooltip] = "Repair small empty triangles (if generated by offset operation)"

T6[:TOS_MAKEFACE_Menu] = "Generate Faces"
T6[:TOS_MAKEFACE_Tooltip] = "Generate faces when possible"

#--------------------------------------------------------
# Default Parameters
#--------------------------------------------------------

#General to all tools on surface
T6[:TOS_DEFAULT_SECTION_General] = "Global Parameters for all tools"
T6[:TOS_DEFAULT_Persistence] = "Preserve parameters across Sketchup sessions"
T6[:TOS_COLOR_PseudoSelection] = "Color of the selection"
T6[:TOS_COLOR_Normal] = "Color of main contour and line drawing in interactive mode |FR|tot"
T6[:TOS_COLOR_Secondary] = "Color of secondary contours or ring lines in interactive mode"
T6[:TOS_DEFAULT_Group] = "Generate contour as a Group"
T6[:TOS_COLOR_Group] = "Color of contour when Group option is On"
T6[:TOS_DEFAULT_CPoint_L] = "Mark all new vertices with a construction point (plain line)"
T6[:TOS_DEFAULT_CPoint_C] = "Mark all new vertices with a construction point (Construction line)"
T6[:TOS_DEFAULT_GenFaces] = "Generate faces when offset is done outside on true borders"
T6[:TOS_DEFAULT_GenCurve] = "Generate contours as curves (useful for Joint Push Pull)"
T6[:TOS_DEFAULT_Protractor] = "Show Protractor (when applicable)"

#For Offset on Surface
T6[:TOS_DEFAULT_SECTION_Offset] = "Offset on Surface"
T6[:TOS_DEFAULT_Contour_Select] = "Offset: Contour implicit selection"
T6[:TOS_DEFAULT_Contour_Outer] = "Outer Only"
T6[:TOS_DEFAULT_Contour_All] = "All"
T6[:TOS_DEFAULT_Contour_Inner] = "Inner Only"
TOS_DEFAULT_Choice_Contour = [ ['O', :TOS_DEFAULT_Contour_Outer],
                               ['A', :TOS_DEFAULT_Contour_All],
                               ['I', :TOS_DEFAULT_Contour_Inner] ]
T6[:TOS_DEFAULT_Alone] = "Alone option: Ignore rest of model when offsetting surface"
T6[:TOS_COLOR_Alone] = "Color of contour when Alone option is set"
T6[:TOS_DEFAULT_Simplify] = "Offset: Simplify generated contour"
							   
#-- Default parameters for shapes
T6[:TOS_DEFAULT_SECTION_Shapes] = "Shapes on Surface"
T6[:TOS_DEFAULT_Diameter] = "Circle: Draw polygon and circle by Radius or by Diameter"
T6[:TOS_DEFAULT_CircleSegments] = "Circle, Ellipse, Arcs: Default number of segments"
T6[:TOS_DEFAULT_PolygonSegments] = "Polygon: Default number of segments"
T6[:TOS_DEFAULT_Protractor_Sector] = "Sectors: Show Protractor"
T6[:TOS_DEFAULT_TrigoSense] = "Sectors: Default trigonometric sense for sectors"

#-- Freehand
T6[:TOS_DEFAULT_SECTION_Freehand] = "Free Hand on Surface"
T6[:TOS_DEFAULT_Freehand_Time] = "Freehand: time between 2 points in second"
T6[:TOS_DEFAULT_Freehand_Precision] = "Freehand: Precision in screen pixels (distance between 2 points)"
T6[:TOS_DEFAULT_Freehand_ClickMode] = "Freehand: Click and Release mode"
T6[:TOS_DEFAULT_Freehand_InfLock] = "Freehand: Lock Inference mode at first startup"

#-- Inference when drawing lines and shapes
T6[:TOS_DEFAULT_SECTION_Inference] = "Inference mechanism"
T6[:TOS_DEFAULT_Inference_Precision] = "Inference: Precision in screen pixels"
T6[:TOS_COLOR_Inference_None] = "Inference: color when no inference"
T6[:TOS_COLOR_Inference_AtVertex] = "Inference: color when line is collinear at vertex"
T6[:TOS_COLOR_Inference_Collinear] = "Inference: color when line is collinear to a given direction"
T6[:TOS_COLOR_Inference_Perpendicular] = "Inference: color when line is perpendicular to a given direction"
T6[:TOS_COLOR_Inference_Angle] = "Inference: color when line is based on Angle to a given direction"

#Functions keys
T6[:DEFAULT_Key_LineMode] = "Toggle Line / Construction Line (All tools)"
T6[:DEFAULT_Key_ClickMode] = "Toggle Click mode / freehand mode (Freehand tool)"
T6[:DEFAULT_Key_CPoint] = "Toggle Construction Points at vertices (All tools)"
T6[:DEFAULT_Key_Simplify] = "Toggle Simplify contours (Offset tool)"
T6[:DEFAULT_Key_Contours] = "Toggle Contour Selection (Offset tool)"
T6[:DEFAULT_Key_InputAxes] = "Toggle Axes, Radius/Diameter, Trigo sense (Shapes tool)"
T6[:DEFAULT_Key_Group] = "Toggle Generation in Group (All tools)"
T6[:DEFAULT_Key_Alone] = "Toggle Alone option (Offset tool)"
T6[:DEFAULT_Key_Protractor] = "Toggle Protractor (Line and Shape tools)"
T6[:DEFAULT_Key_GenFaces] = "Toggle generation of faces (All tools)"
T6[:DEFAULT_Key_GenCurves] = "Toggle generation of curves (All tools)"

#Constants for PolygonOnSurface Module (do not translate)	
T6[:MSG_Shape_Origin] = "Pick Initial Point"
T6[:MSG_Shape_End] = "Pick End Point"

T6[:NAME_Rectangle] = "Rectangle"	
T6[:NAME_Parallelogram] = "Parallelogram"
T6[:NAME_Ellipse] = "Ellipse"	
T6[:NAME_Arc] = "Arc"	
T6[:NAME_Polygon] = "Polygon"	
T6[:NAME_Circle] = "Circle"	
T6[:NAME_Sector] = "Sector (Pie)"	
T6[:NAME_Circle3P] = "Circle (3 Points)"	

T6[:STR_AXE_LENGTH] = "Length"
T6[:STR_AXE_WIDTH] = "Width"
T6[:STR_AXE_RADIUS] = "Radius"
T6[:STR_AXE_DIAMETER] = "Diameter"
T6[:STR_AXE_CHORD] = "Chord"
T6[:STR_AXE_SAGITTA] = "Sagitta"
T6[:STR_AXE_AXIS] = "Axis"
T6[:STR_AXE_FIRST_CHORD] = "First Chord"
T6[:STR_AXE_SECOND_CHORD] = "Second Chord"
T6[:STR_Clockwise] = "Clockwise"
T6[:STR_AntiClockwise] = "Anti-Clockwise"

T6[:STR_Orig_Center] = "Center"
T6[:STR_Orig_BottomMid] = "Bottom-Mid"
T6[:STR_Orig_BottomLeft] = "Bottom-Left"
T6[:STR_Orig_LeftMid] = "Left_Mid"

T6[:DLG_NumSeg] = "Number of segments (based on 360 degrees)"
T6[:TIP_Segment] = "Segments"
T6[:MSG_ErrorInput] = "Invalid or Irrelevant value in VCB"

#Shape Codes
CODE_Line = ''
CODE_Rectangle = 'R'
CODE_Parallelogram = 'P/'
CODE_Circle = 'C'
CODE_Circle3P = 'C3'
CODE_Polygon = 'P'
CODE_Ellipse = 'E'
CODE_Arc = 'A'
CODE_Sector = 'S'
CODE_Spline = 'Sp'

#Hash Table defining each shape (do not translate text)
HSHAPE_RECTANGLE = { 
	'Type' => CODE_Rectangle,
	'NameConv' => 'Rectangle',
	'Symb' => :NAME_Rectangle,
	'HotX' => 3,
	'HotY' => 31,
	'NbSegDef' => 4,
	'NbFixed' => true,
	'Ortho' => true,
	'Piecemeal' => true,
	'Axe1' => :STR_AXE_LENGTH,
	'Axe2' => :STR_AXE_WIDTH
	} 
	
HSHAPE_ELLIPSE = { 
	'Type' => CODE_Ellipse,
	'NameConv' => 'Ellipse',
	'Symb' => :NAME_Ellipse,
	'NbFixed' => false,
	'Ortho' => true,
	'Radial' => true
	} 
	
HSHAPE_PARALLELOGRAM = { 
	'Type' => CODE_Parallelogram,
	'NameConv' => 'Parallelogram',
	'Symb' => :NAME_Parallelogram,
	'NbSegDef' => 4,
	'NbFixed' => true,
	'Ortho' => false,
	'Piecemeal' => true
	} 

HSHAPE_ARC = { 
	'Type' => CODE_Arc,
	'NameConv' => 'Arc',
	'Symb' => :NAME_Arc,
	'NbSegMin' => 2,
	'NbFixed' => false,
	'Arc' => true,
	'Ortho' => true,
	'Axe1' => :STR_AXE_CHORD,
	'Axe2' => :STR_AXE_SAGITTA
	} 

HSHAPE_SECTOR = { 
	'Type' => CODE_Sector,
	'NameConv' => 'Sector',
	'Symb' => :NAME_Sector,
	'NbFixed' => false,
	'Ortho' => false,
	'1/2 Axe1' => :STR_AXE_RADIUS,
	'1/2 Axe2' => :STR_AXE_RADIUS
	} 
	
HSHAPE_POLYGON = { 
	'Type' => CODE_Polygon,
	'Single' => true,
	'NameConv' => 'Polygon',
	'Symb' => :NAME_Polygon,
	'NbFixed' => false,
	'Radial' => true,
	'Piecemeal' => true,
	'Axe1' => :STR_AXE_DIAMETER,
	'1/2 Axe1' => :STR_AXE_RADIUS
	} 

HSHAPE_CIRCLE = { 
	'Type' => CODE_Circle,
	'Single' => true,
	'NameConv' => 'Circle',
	'Symb' => :NAME_Circle,
	'NbFixed' => false,
	'Radial' => true,
	'Axe1' => :STR_AXE_DIAMETER,
	'1/2 Axe1' => :STR_AXE_RADIUS
	} 

HSHAPE_CIRCLE3P = { 
	'Type' => CODE_Circle3P,
	'NameConv' => 'Circle3P',
	'Symb' => :NAME_Circle3P,
	'NbFixed' => false,
	'Radial' => true,
	'Axe1' => :STR_AXE_FIRST_CHORD,
	'Axe2' => :STR_AXE_SECOND_CHORD,
	'IniAxe1' => true,
	'IniAxe2' => true
	} 


#Defining constants and strings
T6[:TOS_TITLE] = "Tools on Surface"

#Attribute signatures - DO NOT TRANSLATE
TOS___Dico = "skp"
TOS___SignEdge = "ToolOnSurface"
TOS___AnchorEdge = "AnchorOnSurface"
TOS___ParamEdge = "ParamOnSurface"

#---------------------------------------------------------------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------------------------------------
# EXTERNAL API to launch TOS menus: F6_SUToolsOnSurface.launch_action
# Action code must be passed as a symbol
# TOOLS
#   - :line --> Line
#   - :eraser --> Eraser of contour
#   - :freehand --> Free Hand
#   - :edit --> Edit contour
#   - :generic --> Generic tool on Surface (i.e. last active in Generic mode)
# SHAPES: use the symbol :shape as first argument and pass the following strings as second argument
#                 (for instance:  F6_SUToolsOnSurface.launch_action :shape, 'Circle')
#   - 'Rectangle'
#   - 'Circle'
#   - 'Circle3P' --> Circle by 3 points
#   - 'Polygon'
#   - 'Sector'
#   - 'Arc'
#   - 'Parallelogram'
#   - 'Ellipse'
# CONTEXTUAL MENUS: Make sure that there is a valid model selection
#   - :edit_selection --> Edit mode if selection is a contour
#   - :make_face --> make all possible faces from one or a set of edges
#   - :void_triangle --> Repair small empty triangle by making them a face
#---------------------------------------------------------------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------------------------------------
	
def F6_SUToolsOnSurface.launch_action(action_code, param=nil)
	MYPLUGIN.launch_action action_code, param
end

#--------------------------------------------------------
# Startup routine (called from LibFredo6)
#--------------------------------------------------------
	
#Create all commands with menus and toolbar icons
def F6_SUToolsOnSurface.startup	

	#Top menu
	MYPLUGIN.declare_topmenu nil, MENU_PERSO

	#Declaring Generic icon
	MYPLUGIN.declare_command(:TOS_GENERIC_) { F6_SUToolsOnSurface.launch_action :generic }
	MYPLUGIN.declare_separator
	
	#Declaring Commands
	MYPLUGIN.declare_command(:TOS_LINE_) { F6_SUToolsOnSurface.launch_action :line }
	MYPLUGIN.declare_separator
	
	F6_SUToolsOnSurface.declare_command_shapes
	MYPLUGIN.declare_separator
	
	MYPLUGIN.declare_command(:TOS_OFFSET_) { F6_SUToolsOnSurface.launch_action :offset }
	MYPLUGIN.declare_command(:TOS_FREEHAND_) { F6_SUToolsOnSurface.launch_action :freehand }
	MYPLUGIN.declare_separator
	MYPLUGIN.declare_command(:TOS_POLYLINE_) { F6_SUToolsOnSurface.launch_action :edit }
	MYPLUGIN.declare_command(:TOS_ERASER_) { F6_SUToolsOnSurface.launch_action :eraser }
	
	#Contextual menu to edit contour on surface
	tc = Traductor::TestCondition.new() { F6_SUToolsOnSurface.check_if_polyline Sketchup.active_model.selection }
	MYPLUGIN.declare_context_handler(:TOS_POLYLINE_, tc, true) { F6_SUToolsOnSurface.launch_action :edit_selection }

	#Contextual menu to treat small void triangle
	tc = Traductor::TestCondition.new() { F6_SUToolsOnSurface.void_triangle_check_selection }
	MYPLUGIN.declare_context_handler(:TOS_VOIDTRIANGLE_, tc) { F6_SUToolsOnSurface.launch_action :void_triangle }

	#Contextual menu to generate faces from contour
	tc = Traductor::TestCondition.new() { F6_SUToolsOnSurface.make_face_check_selection }
	MYPLUGIN.declare_context_handler(:TOS_MAKEFACE_, tc) { F6_SUToolsOnSurface.launch_action :make_face }
	
	#Declaring the default parameter
	F6_SUToolsOnSurface.default_param
	
	#Startup of the Plugin
	MYPLUGIN.go	
end

#Define the menu for the shapes
def F6_SUToolsOnSurface.get_list_shapes
	@lst_shapes = [HSHAPE_RECTANGLE, HSHAPE_CIRCLE, HSHAPE_POLYGON, HSHAPE_ELLIPSE, HSHAPE_PARALLELOGRAM,
	               HSHAPE_ARC, HSHAPE_CIRCLE3P, HSHAPE_SECTOR]
end

def F6_SUToolsOnSurface.declare_command_shapes
	F6_SUToolsOnSurface.get_list_shapes
	@lst_shapes.each do |hshape| 	
		symb = hshape['Symb']
		text = T6[symb]
		icon = hshape['NameConv']
		MYPLUGIN.declare_command_long(symb, text, text, icon) { F6_SUToolsOnSurface.launch_action :shape, hshape['NameConv'] }
	end	
end

#Check if the selection contains a Contour on Surface
def F6_SUToolsOnSurface.check_if_polyline(selection)
	selection.find { |e| e.instance_of?(Sketchup::Edge) && e.get_attribute(TOS___Dico, TOS___SignEdge) }
end	
	
#Check of selection for contextual menu : Generate Face	
def F6_SUToolsOnSurface.make_face_check_selection
	Sketchup.active_model.selection.each do |e|
		return true if e.instance_of?(Sketchup::Edge) || e.instance_of?(Sketchup::Curve)
	end	
	false
end
	
#Check of selection for contextual menu : Repair void triangles	
def F6_SUToolsOnSurface.void_triangle_check_selection
	@dsnap = Sketchup.active_model.options["UnitsOptions"]["LengthSnapLength"].to_f unless @dsnap
	Sketchup.active_model.selection.find { |e| e.instance_of?(Sketchup::Edge) && e.length <= @dsnap && e.faces.length == 1 }
end
	
	
#Declaring the Default Parameters	
def F6_SUToolsOnSurface.default_param
	dp = MYDEFPARAM

	#Global parameters
	dp.separator :TOS_DEFAULT_SECTION_General
	dp.declare :TOS_DEFAULT_Persistence, true, "B"
	dp.declare :TOS_COLOR_PseudoSelection, "Blue", "K"
	dp.declare :TOS_COLOR_Normal, "Red", "K"
	dp.declare :TOS_COLOR_Secondary, "Orange", "K"
	dp.declare :TOS_DEFAULT_Group, false, "B"
	dp.declare :TOS_COLOR_Group, "DarkRed", "K"
	dp.declare :TOS_DEFAULT_CPoint_L, false, "B"
	dp.declare :TOS_DEFAULT_CPoint_C, true, "B"
	dp.declare :TOS_DEFAULT_GenCurve, true, "B"
	dp.declare :TOS_DEFAULT_GenFaces, true, "B"
	dp.declare :TOS_DEFAULT_Protractor, false, "B"

	#Offset on Surface
	dp.separator :TOS_DEFAULT_SECTION_Offset
	dp.declare :TOS_DEFAULT_Contour_Select, 'O', "H:", T6[TOS_DEFAULT_Choice_Contour]
	dp.declare :TOS_DEFAULT_Alone, false, "B"
	dp.declare :TOS_COLOR_Alone, "DarkGreen", "K"
	dp.declare :TOS_DEFAULT_Simplify, true, "B"
	
	#-- Default parameters for shapes
	dp.separator :TOS_DEFAULT_SECTION_Shapes
	dp.declare :TOS_DEFAULT_Diameter, true, "B"
	dp.declare :TOS_DEFAULT_CircleSegments, 24, 'I:>=3<=100'
	dp.declare :TOS_DEFAULT_PolygonSegments, 6, 'I:>=3<=100'
	dp.declare :TOS_DEFAULT_Protractor_Sector, true, "B"
	dp.declare :TOS_DEFAULT_TrigoSense, true, 'B'

	#-- Inference when drawing lines and shapes
	dp.separator :TOS_DEFAULT_SECTION_Freehand
	dp.declare :TOS_DEFAULT_Freehand_Time, 0.1, 'F:>=0.05<=2.0'
	dp.declare :TOS_DEFAULT_Freehand_Precision, 30, 'I:>=10<=200'
	dp.declare :TOS_DEFAULT_Freehand_ClickMode, true, 'B'
	dp.declare :TOS_DEFAULT_Freehand_InfLock, true, 'B'
		
	#-- Inference when drawing lines and shapes
	dp.separator :TOS_DEFAULT_SECTION_Inference
	dp.declare :TOS_DEFAULT_Inference_Precision, 30, 'I:>=10<=50'
	dp.declare :TOS_COLOR_Inference_None, "Black", "K"
	dp.declare :TOS_COLOR_Inference_AtVertex, "Purple", "K"
	dp.declare :TOS_COLOR_Inference_Collinear, "DeepPink", "K"
	dp.declare :TOS_COLOR_Inference_Perpendicular, "Brown", "K"
	dp.declare :TOS_COLOR_Inference_Angle, "Chocolate", "K"

	#function keys
	fkeys = Traductor::FKeyOption.fkeys
	MYDEFPARAM.separator :T_DEFAULT_SectionFunctionKey
	MYDEFPARAM.declare :DEFAULT_Key_LineMode, 'F2', 'H', fkeys
	MYDEFPARAM.declare :DEFAULT_Key_CPoint, 'F3', 'H', fkeys
	MYDEFPARAM.declare :DEFAULT_Key_ClickMode, 'F4', 'H', fkeys
	MYDEFPARAM.declare :DEFAULT_Key_Simplify, 'F4', 'H', fkeys
	MYDEFPARAM.declare :DEFAULT_Key_Contours, 'F5', 'H', fkeys
	MYDEFPARAM.declare :DEFAULT_Key_InputAxes, 'F5', 'H', fkeys
	MYDEFPARAM.declare :DEFAULT_Key_Group, 'F6', 'H', fkeys
	MYDEFPARAM.declare :DEFAULT_Key_Alone, 'F7', 'H', fkeys
	MYDEFPARAM.declare :DEFAULT_Key_Protractor, 'F7', 'H', fkeys
	MYDEFPARAM.declare :DEFAULT_Key_GenFaces, 'F8', 'H', fkeys
	MYDEFPARAM.declare :DEFAULT_Key_GenCurves, 'F9', 'H', fkeys
	
end
	
end	#End Module F6_SUToolsOnSurface
