=begin
#-------------------------------------------------------------------------------------------------------------------------------------------------
#*************************************************************************************************
# Copyright 2009 - Designed September 2009 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			:   CurviloftLoftTool.rb
# Original Date	:   05 Sep 2009 - version 1.0
# Type			:   Sketchup Tools
# Description	:   Manage the interactive GUI tool for Curviloft Loft
#-------------------------------------------------------------------------------------------------------------------------------------------------
#*************************************************************************************************
=end

module F6_Curviloft
			
T6[:TIT_CurveMover] = "Curve Mover"
			
#--------------------------------------------------------------------------------------------------------------
# Top Calling functions: create the classes and launch the tools
#--------------------------------------------------------------------------------------------------------------			 				   

def F6_Curviloft.launch_curve_mover(*args)
	puts "Launch Curve Mover"
	tool = CVL_CurveMoverTool.new
	Sketchup.active_model.select_tool tool
end

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# SU Tool Class to manage GUI for Bezier Loft
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
					
class CVL_CurveMoverTool < Traductor::PaletteSuperTool

def initialize(along_path=false)
	@model = Sketchup.active_model
	
	#Loading strings
	@title = T6[:TIT_CurveMover]
	@along_path = along_path
	puts "LOFT PATH = #{@along_path}"
	
	#Initializing the cursors
	@idcursor_curve_mover = MYPLUGIN.create_cursor "CurveMover", 0, 0
	@idcursor_curve_mover = 0
	@id_cursor_arrow_exit = MYPLUGIN.create_cursor "Arrow_Exit", 0, 0	
	puts "cursor mover = #{@idcursor_curve_mover}"
		
	#Initializating the Edge Picker
	init_edge_picker

	#Creating the palette manager and texts
	init_palette
	init_text
	
end

def make_proc(&proc) ; proc ; end

def init_text

end

#Initializating the Edge Selection Picker
def init_edge_picker
	@anglemax = 40
	@modifier = 'F'
	#@aperture = MYDEFPARAM[Traductor::EdgePicker.default_symb_aperture(:CVL__)]
	#@aperture = nil if @aperture && @aperture < 5
	
	hsh = {}
	hsh["notify_proc"] = self.method 'notify_edge_picked'
	hsh["modifier"] = @modifier if @modifier
	hsh["anglemax"] = @anglemax if @anglemax
	@selmode = Traductor::EdgePicker.new hsh
end

#Creating the palette manager
def init_palette
	proc_exec = make_proc() { execute }
	proc_gray = make_proc() { false }
	proc_get_prop = self.method 'option_get_prop'
	proc_set_prop = self.method 'option_set_prop'
	
	#List of options
	lst_options = []
	#lst_options.push 'loft_line_only'
	#lst_options.push 'loft_bezier' unless @along_path 
	
	hsh = { 'title' => @title, 'list_options' => lst_options, 
			'option_get_proc' => proc_get_prop, 'option_set_proc' => proc_set_prop,
            'finish_proc_gray' => proc_gray, 'finish_proc_exec' => proc_exec,
			'selmode' => @selmode }
			
	@palman = PaletteManager.new(self, 'CurveMover', hsh) { refresh_view }
end

def option_get_prop(*args) 
	puts "option get proc"
end
	
def option_set_prop(*args)
	puts "option set proc"
end

#Control the State of the tool
def set_state(state)
	return if @state == state
	return UI.beep if state == 1 && !@ok_origin
	#return UI.beep if state == 2 && !@ok_target
	@state = state
	if state > 1	
		@state = 2
		execute
		return
	end	
	if state <= 1
		@pt_target = nil
	end	
	if state <= 0
		@pt_origin = nil
	end	
	info_show
end

#--------------------------------------------------
# Standard SU Tool messages
#--------------------------------------------------

#Tool activation
def activate
	@model = Sketchup.active_model
	@selection = @model.selection
	@entities = @model.active_entities
	@view = @model.active_view

	@ph = @view.pick_helper
	@ip1 = Sketchup::InputPoint.new		
	@ip2 = Sketchup::InputPoint.new		
	@inference = Traductor::VecInference.new
	@button_down = false
	@ctrl_down = false
	@shift_down = false	
	@xdown = nil
	@ydown = nil		
	@state = 0	
	@button_down = false
	@pt_origin = nil
	@pt_target = nil
	
	#Initiating the palette
	@palman.initiate
	
	#initiating the Curl Manager and testing the current model selection
	#hsh = { :anglemax => @anglemax }
	#@curlman = CVL_CurlManager.new hsh
	#lst_groups = @curlman.analyze_model_selection
	@selmode.check_initial_selection
	lst_groups = @selmode.get_contours
	puts "\ngroups = #{lst_groups.length} "
	
	@view.invalidate
	info_show

	@view.invalidate
	info_show
end

def reset_selection

end

#Tool Deactivation
def deactivate(view)
	@palman.terminate
	view.invalidate
end

#Cancel and undo methods
def onCancel(flag, view)
	#User did an Undo
	case flag
	when 1, 2	#Undo or reselect the tool
		activate
		return
	when 0	#user pressed Escape
		puts 'Cancel'
		set_state @state - 1
		onMouseMove_zero
	end
end

#Setting the cursor
def onSetCursor
	ic = super
	return (ic != 0) if ic
	#cursor = @idcursor_curve_mover
	cursor = @selmode.onSetCursor

	UI::set_cursor cursor
end

#Contextual menu
def getMenu(menu)
	@palman.init_menu		
	@selmode.getMenu menu
	@palman.option_menu menu
	true
end

#Return key pressed
def onReturn(view)
	execute 
end

#Exit the tool
def exit_tool
	@model.select_tool nil 
end

#Porcedure to refresh the view ehn options are changed
def refresh_view
	@view.invalidate
	info_show
end

#resume after view tools
def resume(view)
	onMouseMove_zero
end	

#Button Down
def onLButtonDown(flags, x, y, view)
	return if super
	#puts "click down"
	@selmode.onLButtonDown(flags, x, y, view)
	#set_state @state + 1
	@xdown = x
	@ydown = y
end


#Button Up
def onLButtonUp(flags, x, y, view)
	return if super
	#puts "click up"
	#return if @xdown && (@xdown - x).abs < 5 && (@ydown - y).abs < 5
	@selmode.onLButtonUp(flags, x, y, view)
	#set_state @state + 1
	#onMouseMove_zero
end

#Double Click received
def onLButtonDoubleClick(flags, x, y, view)
	return if super
	puts "double click"
	@selmode.onLButtonDoubleClick(flags, x, y, view)
	onMouseMove_zero
end

#Key Up
def onKeyUp(key, rpt, flags, view)
	key = Traductor.check_key key, flags, true
	
	puts "key up = #{key}"
	
	#Curve selection
	return onMouseMove_zero if @selmode.onKeyUp(key, rpt, flags, view)

	#Inference modifiers
	if @inference.handleKeyUp(key, rpt, flags, view)
		onMouseMove_zero
		return
	end	
	
	@control_down = false
end

#Key down
def onKeyDown(key, rpt, flags, view)
	key = Traductor.check_key key, flags, false

	puts "key down = #{key}"

	#Curve selection
	return onMouseMove_zero if @selmode.onKeyDown(key, rpt, flags, view)

	#Inference modifiers
	if @inference.handleKeyDown(key, rpt, flags, view)
		onMouseMove_zero
		#onMouseMove 0, @x, @y, view
		return
	end	
	
	case key			
	#Calling options
	when CONSTRAIN_MODIFIER_KEY

	when COPY_MODIFIER_KEY
		@control_down = true
		return
		
	else
		@control_down = false
		return
	end	
	@control_down = false
	
	onMouseMove_zero
	info_show
end

#Mouse Move method
def onMouseMove_zero ; onMouseMove(@flags, @xmove, @ymove, @view) if @xmove ; end

def onMouseMove(flags, x, y, view)
	#Event for the palette
	return if super
	
	@xmove = x
	@ymove = y

	#Synchronize draw and move
	return if @moving
	@moving = true

	#Curev Selection
	@ip1.pick view, x, y
	view.tooltip = @ip1.tooltip
	@selmode.onMouseMove(flags, x, y, view)

	#Picking the Origin
	if @state == 0
		@pt_target = nil
		@ip1.pick view, x, y
		view.tooltip = @ip1.tooltip
		#check_curl @ip1
		@pt_origin = @inference.set_xy_origin(view, x, y)
		@ok_origin = true
	
	#Picking the target
	elsif @state == 1
		@ip2.pick view, x, y, @ip1
		@pt_target = @inference.compute_xy_inference view, x, y
		view.tooltip = @inference.get_tooltip
	end
	
	#Refreshing the view
	#view.tooltip = ""
	#onSetCursor
	view.invalidate
end	

#----------------------------------------------------------------
# Drawing Methods
#----------------------------------------------------------------

#Draw method for Polyline tool
def draw(view)	
	
	@moving = false

	#drawing the curl
	if @current_edge
		#color = 'darkgray'
		#G6.draw_lines_with_offset view, @llines, color, 3, ''
	end
	
	#Drawing the selected curves
	@selmode.draw view
	#@curlman.draw_contours view
	
	#Drawing the input points
	view.line_width = 1
	if @state >= 0 && @pt_origin
		@ip1.draw view
	end
	
	if @state >= 1 && @pt_target
		@ip2.draw view if @ip2.position == @pt_target && @inference.no_autoinference
		@inference.draw2d view if @pt_target
	end
	
	#Drawing the palette
	super
end

#display information in the Sketchup status bar
def info_show
	msg = "select Extremity of curve"
	label = ""
	txval = ""

	Sketchup.set_status_text msg
	Sketchup.set_status_text label, SB_VCB_LABEL
	Sketchup.set_status_text txval, SB_VCB_VALUE

end

#-----------------------------------------------------------------
# Computation methods
#-----------------------------------------------------------------

def check_curl(ip)
	#No edge selected
	puts "vertex = #{ip.vertex} edge = #{ip.edge}"
	edge = ip.edge
	unless edge
		@current_edge = nil
		return
	end	
	
	#Edge already computed
	unless edge == @current_edge && edge.parent == @current_parent
		t = ip.transformation
		ledges = G6.curl_edges(edge)
		@current_edge = edge
		@current_parent = edge.parent
		@llines = []
		ledges.each { |e| @llines.push t * e.start.position, t * e.end.position }
	end		
end

#----------------------------------------------------------------
# Entity Picker Management
#----------------------------------------------------------------

#add or remove entity from selection
def notify_edge_picked(action, ledges)
	puts "#{@title} --> ACTION = #{action} >> #{(ledges.class == Array) ? ledges.length : "nil"}"
	ledges
end

#-----------------------------------------------------------------
# Building Geometry
#-----------------------------------------------------------------

def execute
	puts "execute"
	set_state 0
end
	
end	#End Class CVL_CurveMoverTool
	
end	#End Module F6_Curviloft
