require 'sketchup'
require 'ShaDe//lib//utils.rb'
require 'ShaDe//lib//geometry.rb'
require 'ShaDe//lib//data-structures.rb'
require 'ShaDe//lib//main-structures.rb'
require 'ShaDe//lib//constraints.rb'
require 'ShaDe//lib//goals.rb'

#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#predicate_type:: "Constraint" or "Goal"
#Method that creates the dialog for choosing the name of a custom constraint or goal
def create_name_dialog(predicate_type)
	
	name = nil
	# Create the WebDialog instance for choosing the name
	name_dialog = UI::WebDialog.new("Choose #{predicate_type} name", true, "Choose #{predicate_type} name", 250, 150, 150, 150, true)
	
	# Attach an action callback
	name_dialog.add_action_callback("get_name") do |web_dialog, name|
		
		#Obtain the class name
		class_name = name.gsub(" ", "_")
		class_name[0] = class_name[0].chr.to_s.upcase
		
		#If class_name is not used...
		if !Object.const_defined?(class_name)

			name_dialog.close
			# Find and show our html file
			html_path = Sketchup.find_support_file "chooseInterfaceType.html" , Constants::HTML_DIR
			choose_interface_dialog = create_choose_interface_dialog(predicate_type, class_name)
			choose_interface_dialog.set_file(html_path)
			choose_interface_dialog.show()
		else
			UI.messagebox("The name is already in use")
		end
	end
	
	return name_dialog
end

#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#predicate_type:: "Constraint" or "Goal"
#class_name:: name of the class that will wrap the constraint or the goal
#
#Method that creates the dialog for choosing the type of interface to be used when creating a custom constraint or goal
def create_choose_interface_dialog(predicate_type, class_name)
	# Create the WebDialog instance for choosing the interface type
	choose_interface_dialog = UI::WebDialog.new("Choose interface type", true, "Choose interface type", 250, 150, 150, 150, true)
	
	# Attach an action callback
	choose_interface_dialog.add_action_callback("get_type") do |web_dialog, type|
		
		choose_interface_dialog.close
		
		if type == "GUI"
			# Find and show our html file
			html_path = Sketchup.find_support_file "GUIDialogFocus.html" , Constants::HTML_DIR
			gui_dialog_focus = create_GUI_dialog_focus(predicate_type, class_name)
			gui_dialog_focus.set_file(html_path)
			gui_dialog_focus.show()
		elsif type == "CODE"
			# Find and show our html file
			html_path = Sketchup.find_support_file "write#{predicate_type}CustomCode.html" , Constants::HTML_DIR
			code_dialog = create_code_dialog(predicate_type, class_name)
			code_dialog.set_file(html_path)
			code_dialog.show()
		end

	end
	
	return choose_interface_dialog
end

#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#predicate_type:: "Constraint" or "Goal"
#class_name:: name of the class that will wrap the constraint or the goal
#
#Method that creates the dialog for directly typing the code of a custom constraint or goal
def create_code_dialog(predicate_type, class_name)
	code = nil
	# Create the WebDialog instance for writing the code
	code_dialog = UI::WebDialog.new("Write #{predicate_type} custom code", true, "Write #{predicate_type} custom code", 550, 750, 150, 150, true)

	# Attach an action callback for checking the code syntax
	code_dialog.add_action_callback("check_syntax") do |web_dialog, code|
		# Fix the code
		code.gsub!("<BR>", "\n")
		code.gsub!("<TAB>", "\t")

		# Eval the method rescuing the exceptions
		string_errors = ""
		begin
		
			#Define the class without satisfied? method (if the name is properly chosen, then the next eval clause will not raise errors)
			Object.const_set(class_name, Class.new { 
			
				eval("attr_reader :name")
				
				eval("def initialize;  @name = \"#{class_name}\" end")
				
				eval("def delete; end")
			
			})
			
			code = "#{code}
				return result"
				
			# Define (or re-define) the satisfied? method
			eval("class #{class_name}
			
				def satisfied?; result = true\n #{code}\n end
			
			end")
		rescue Exception => e
			bad_syntax = true
			string_errors = e.message.gsub("\n", " ").gsub("\t", " ").gsub(":in `create_execution_toolbar'", "")
		end	
		
		js_command = ""
		if bad_syntax
			js_command = "writeSyntaxResults(\"#{string_errors}\")"
		else
			js_command = "writeSyntaxResults(\"Syntax OK\")"
		end
		web_dialog.execute_script(js_command)
	end
	
	# Attach an action callback for executing the code
	code_dialog.add_action_callback("execute_code") do |web_dialog, rubish_code|
		# Execute the method satisfied? rescuing the exceptions
		# If we are here, it means the method satisfied? has been created
		string_errors = ""
		if predicate_type == "Constraint"
			begin
				constraint_class = eval("#{class_name}")
				constraint = constraint_class.new
				constraint.satisfied?
			rescue Exception => e
				bad_execution = true
				string_errors = e.message.gsub("\n", " ").gsub("\t", " ")
			end
		else
			begin
				goal_class = eval("#{class_name}")
				goal = goal_class.new
				goal.satisfied?
			rescue Exception => e
				bad_execution = true
				string_errors = e.message.gsub("\n", " ").gsub("\t", " ")
			end
		end
		
		js_command = ""
		if bad_execution
			js_command = "writeExecutionResults(\"#{string_errors}\")"
		else
			js_command = "writeExecutionResults(\"Execution OK\")"
		end
		web_dialog.execute_script(js_command)
	end
	
	# Attach an action callback for saving the code
	code_dialog.add_action_callback("write_code") do |web_dialog, rubish_code|
		# Write the code into an auxiliar file
		file_name = Sketchup.find_support_file Constants::STARTUP_FILE_NAME, Constants::LIB_DIR
		directory = ShadeUtils.get_directory_from_sketchup_path(file_name)
		if predicate_type == "Constraint"
			File.open("#{directory}//#{Constants::CONSTRAINT_FOLDER_NAME}//#{class_name}.txt", 'w') do |f|
				f.write("#{code}\n")
			end
			# Add the constraint to the project
			constraint_class = eval("#{class_name}")
			constraint = constraint_class.new
			Shade.project.execution.add_constraint(constraint)
			Shade.add_constraint_class_name([constraint_class, class_name])
		else
			File.open("#{directory}//#{Constants::GOAL_FOLDER_NAME}//#{class_name}.txt", 'w') do |f|
				f.write("#{code}\n")
			end
			# Add the goal to the project
			goal_class = eval("#{class_name}")
			goal = goal_class.new
			Shade.project.execution.add_goal(goal)
			Shade.add_goal_class_name([goal_class, class_name])
		end

		# Close the code dialog
		code_dialog.close
	end
	
	return code_dialog
end

#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#predicate_type:: "Constraint" or "Goal"
#class_name:: name of the class that will wrap the constraint or the goal
#
#Method that creates the dialog for choosing the predicate global focus (that is, the "rule applied" or the "current shape")
def create_GUI_dialog_focus(predicate_type, class_name)
	gui_dialog_focus = UI::WebDialog.new("Choose #{predicate_type} focus", true, "Choose #{predicate_type} focus", 250, 150, 150, 150, true)
	
	# Attach an action callback for getting the chosen focus
	gui_dialog_focus.add_action_callback("get_focus") do |web_dialog, focus|
		
		gui_dialog_focus.close
		
		if focus == "RULE APPLIED"
			# Find and show our html file
			html_path = Sketchup.find_support_file "GUIDialogRuleFocus.html" , Constants::HTML_DIR
			gui_dialog_rule = create_GUI_dialog_rule(predicate_type, class_name)
			gui_dialog_rule.set_file(html_path)
			gui_dialog_rule.show()
		elsif focus == "CURRENT SHAPE"
			# Find and show our html file
			html_path = Sketchup.find_support_file "GUIDialogShapeFocus.html" , Constants::HTML_DIR
			gui_dialog_shape = create_GUI_dialog_shape(predicate_type, class_name)
			gui_dialog_shape.set_file(html_path)
			gui_dialog_shape.show()
		end

	end
	
	return gui_dialog_focus
end

#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#predicate_type:: "Constraint" or "Goal"
#class_name:: name of the class that will wrap the constraint or the goal
#
#Method that creates the dialog for choosing the rule focus (that is, the "rule id" or the "rule transformation")
def create_GUI_dialog_rule(predicate_type, class_name)
	gui_dialog_rule = UI::WebDialog.new("Choose #{predicate_type} rule focus", true, "Choose #{predicate_type} rule focus", 250, 150, 150, 150, true)
	
	# Attach an action callback for getting the chosen focus
	gui_dialog_rule.add_action_callback("get_focus") do |web_dialog, focus|
		
		gui_dialog_rule.close
		
		if focus == "RULE ID"
			# Find and show our html file
			html_path = Sketchup.find_support_file "GUIDialogRuleID.html" ,Constants::HTML_DIR
			gui_rule_id = create_GUI_rule_id(predicate_type, class_name)
			gui_rule_id.set_file(html_path)
			gui_rule_id.show()
		elsif focus == "FIRST RULE ID"
			# Find and show our html file
			html_path = Sketchup.find_support_file "GUIDialogFirstRuleID.html" ,Constants::HTML_DIR
			gui_first_rule_id = create_GUI_first_rule_id(predicate_type, class_name)
			gui_first_rule_id.set_file(html_path)
			gui_first_rule_id.show()
		elsif focus == "TRANSFORMATION"
			# Find and show our html file
			html_path = Sketchup.find_support_file "GUIDialogRuleTransformation.html" ,Constants::HTML_DIR
			gui_rule_transformation = create_GUI_rule_transformation(predicate_type, class_name)
			gui_rule_transformation.set_file(html_path)
			gui_rule_transformation.show()
		end

	end
	
	return gui_dialog_rule
end


#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#predicate_type:: "Constraint" or "Goal"
#class_name:: name of the class that will wrap the constraint or the goal
#
#Method that creates the dialog for choosing the current shape focus (that is, the "whole shape", the "points" or the "segments")
def create_GUI_dialog_shape(predicate_type, class_name)
	gui_dialog_shape = UI::WebDialog.new("Choose #{predicate_type} shape focus", true, "Choose #{predicate_type} shape focus", 250, 150, 150, 150, true)
	
	# Attach an action callback for getting the chosen current shape focus
	gui_dialog_shape.add_action_callback("get_focus") do |web_dialog, focus|
		
		gui_dialog_shape.close
		
		if focus == "WHOLE SHAPE"
			# Find and show our html file
			html_path = Sketchup.find_support_file "GUIDialogWholeShape.html" ,Constants::HTML_DIR
			gui_dialog_whole_shape = create_GUI_dialog_whole_shape(predicate_type, class_name)
			gui_dialog_whole_shape.set_file(html_path)
			gui_dialog_whole_shape.show()
		elsif focus == "POINTS"
			# Find and show our html file
			html_path = Sketchup.find_support_file "GUIDialogPointsFocus.html" ,Constants::HTML_DIR
			gui_dialog_points_focus = create_GUI_dialog_points_focus(predicate_type, class_name)
			gui_dialog_points_focus.set_file(html_path)
			gui_dialog_points_focus.show()
		elsif focus == "SEGMENTS"
			# Find and show our html file
			html_path = Sketchup.find_support_file "GUIDialogSegments.html" ,Constants::HTML_DIR
			gui_dialog_segments_focus = create_GUI_dialog_segments(predicate_type, class_name)
			gui_dialog_segments_focus.set_file(html_path)
			gui_dialog_segments_focus.show()
		end

	end
	
	return gui_dialog_shape
end

#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#predicate_type:: "Constraint" or "Goal"
#class_name:: name of the class that will wrap the constraint or the goal
#
#Method that creates the dialog for choosing the points focus (that is, the "number of points" or the "position of points")
def create_GUI_dialog_points_focus(predicate_type, class_name)
	gui_dialog_points_focus = UI::WebDialog.new("Choose #{predicate_type} points focus", true, "Choose #{predicate_type} points focus", 250, 150, 150, 150, true)
	
	# Attach an action callback for getting the chosen points focus
	gui_dialog_points_focus.add_action_callback("get_focus") do |web_dialog, focus|
		
		gui_dialog_points_focus.close
		
		if focus == "NUMBER OF POINTS"
			# Find and show our html file
			html_path = Sketchup.find_support_file "GUIDialogNumberOfPoints.html" ,Constants::HTML_DIR
			gui_dialog_number_of_points = create_GUI_dialog_number_of_points(predicate_type, class_name)
			gui_dialog_number_of_points.set_file(html_path)
			gui_dialog_number_of_points.show()
		elsif focus == "POSITION OF POINTS"
			# Find and show our html file
			html_path = Sketchup.find_support_file "GUIDialogPositionOfPoints.html" ,Constants::HTML_DIR
			gui_dialog_position_of_points = create_GUI_dialog_position_of_points(predicate_type, class_name)
			gui_dialog_position_of_points.set_file(html_path)
			gui_dialog_position_of_points.show()
		end

	end
	
	return gui_dialog_points_focus
end

#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#predicate_type:: "Constraint" or "Goal"
#class_name:: name of the class that will wrap the constraint or the goal
#code:: string with the code for the method "satisfied" of either a constraint or a goal
#
#Method that creates the class and stores the code for a custom constraint or goal
def create_code(predicate_type, class_name, code)
	# Create the class
	bad_sintax = false
	begin
		#Define the class without satisfied? method (if the name is properly chosen, then the next eval clause will not raise errors)
		Object.const_set(class_name, Class.new { 
		
			eval("attr_reader :name")
			
			eval("def initialize;  @name = \"#{class_name}\" end")
			
			eval("def delete; end")
		
		})
		
		code = "#{code}
				return result"
		# Define (or re-define) the satisfied? method
		eval("class #{class_name}
		
			def satisfied?; result = true\n #{code}\n end
		
		end")
	rescue Exception => e
		bad_syntax = true
		string_errors = e.message.gsub("\n", " ").gsub("\t", " ").gsub(":in `create_execution_toolbar'", "")
	end	
	
	if !bad_sintax
		# Write the code into an auxiliar file
		file_name = Sketchup.find_support_file Constants::STARTUP_FILE_NAME, Constants::LIB_DIR
		directory = ShadeUtils.get_directory_from_sketchup_path(file_name)
		if predicate_type == "Constraint"
			File.open("#{directory}//#{Constants::CONSTRAINT_FOLDER_NAME}//#{class_name}.txt", 'w') do |f|
				f.write("#{code}\n")
			end
			# Add the constraint to the project
			constraint_class = eval("#{class_name}")
			constraint = constraint_class.new
			Shade.project.execution.add_constraint(constraint)
			Shade.add_constraint_class_name([constraint_class, class_name])
		else
			File.open("#{directory}//#{Constants::GOAL_FOLDER_NAME}//#{class_name}.txt", 'w') do |f|
				f.write("#{code}\n")
			end
			# Add the goal to the project
			goal_class = eval("#{class_name}")
			goal = goal_class.new
			Shade.project.execution.add_goal(goal)
			Shade.add_goal_class_name([goal_class, class_name])
		end
	end
end

#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#predicate_type:: "Constraint" or "Goal"
#class_name:: name of the class that will wrap the constraint or the goal
#
#Method that creates the dialog for configuring the predicate focused in the applied rule id
def create_GUI_rule_id(predicate_type, class_name)
	gui_dialog_rule_id = UI::WebDialog.new("Configure rule id #{predicate_type}", true, "Configure rule id #{predicate_type}", 700, 100, 150, 150, true)
	
	# Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate.
	gui_dialog_rule_id.add_action_callback("get_data") do |web_dialog, data|
		
		gui_dialog_rule_id.close
		data_a = data.split(",")
		
		relation_type = data_a[0]
		id_type = data_a[1]
		number = data_a[2]
		
		predicate_string = ""
				
		case relation_type  
			when "EQUAL"
				predicate_string = "(ShadeUtils.last_rule_id =="
			when "DIFFERENT"
				predicate_string = "!(ShadeUtils.last_rule_id =="
			when "BIGGER"
				predicate_string = "(ShadeUtils.last_rule_id >"
			when "LESS"
				predicate_string = "(ShadeUtils.last_rule_id <"
			when "BIGGEREQ"
				predicate_string = "(ShadeUtils.last_rule_id >="
			when "LESSEQ"
				predicate_string = "(ShadeUtils.last_rule_id <="
			when "FOLLOWING"
				predicate_string = "(ShadeUtils.last_rule_id - 1 =="
			end  
			
		code = ""
		
		case id_type  
			when "PREVIOUS"
				predicate_string = "#{predicate_string} ShadeUtils.previous_rule_id"
				code = "if Shade.project.execution.execution_history
						if Shade.project.execution.execution_history.size > 1
							result = #{predicate_string})
						end
					  end"
			when "NUMBER"
				predicate_string = "#{predicate_string} #{number}"
				code = "if Shade.project.execution.execution_history
						result = #{predicate_string})
					   end"
			end  
		
	
		create_code(predicate_type, class_name, code)
	end
	
	return gui_dialog_rule_id
end

#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#predicate_type:: "Constraint" or "Goal"
#class_name:: name of the class that will wrap the constraint or the goal
#
#Method that creates the dialog for configuring the predicate focused in the first applied rule id
def create_GUI_first_rule_id(predicate_type, class_name)
	gui_dialog_first_rule_id = UI::WebDialog.new("Configure first rule id #{predicate_type}", true, "Configure first rule id #{predicate_type}", 700, 100, 150, 150, true)
	
	# Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate.
	gui_dialog_first_rule_id.add_action_callback("get_data") do |web_dialog, data|
		
		gui_dialog_first_rule_id.close
		data_a = data.split(",")
		
		relation_type = data_a[0]
		number = data_a[1]
		
		predicate_string = ""
				
		case relation_type  
			when "EQUAL"
				predicate_string = "(ShadeUtils.first_rule_id == #{number}"
			when "DIFFERENT"
				predicate_string = "!(ShadeUtils.first_rule_id == #{number}"
			when "BIGGER"
				predicate_string = "(ShadeUtils.first_rule_id > #{number}"
			when "LESS"
				predicate_string = "(ShadeUtils.first_rule_id < #{number}"
			when "BIGGEREQ"
				predicate_string = "(ShadeUtils.first_rule_id >= #{number}"
			when "LESSEQ"
				predicate_string = "(ShadeUtils.first_rule_id <= #{number}"
			end  
			

		code = "if Shade.project.execution.execution_history
				if Shade.project.execution.execution_history.size == 1
					result = #{predicate_string})
				end
			  end"
		
	
		create_code(predicate_type, class_name, code)
	end
	
	return gui_dialog_first_rule_id
end

#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#predicate_type:: "Constraint" or "Goal"
#class_name:: name of the class that will wrap the constraint or the goal
#
#Method that creates the dialog for configuring the predicate focused in the applied rule transformation
def create_GUI_rule_transformation(predicate_type, class_name)
	gui_dialog_rule_transformation = UI::WebDialog.new("Configure rule transformation #{predicate_type}", true, "Configure rule transformation #{predicate_type}", 700, 100, 150, 150, true)
	
	# Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate.
	gui_dialog_rule_transformation.add_action_callback("get_data") do |web_dialog, data|
		
		gui_dialog_rule_transformation.close
		data_a = data.split(",")
		
		transformation_type = data_a[0]
		relation_type = data_a[1]
		number = data_a[2]
		
		code = ""
				
		case transformation_type  
			when "XTRASLATION"
				code = "last_t = ShadeUtils.last_rule_transformation()
					   factor = last_t[2]"
			when "YTRASLATION"
				code = "last_t = ShadeUtils.last_rule_transformation()
					   factor = last_t[5]"
			when "ROTATION"
				code = "last_t = ShadeUtils.last_rule_transformation()
					   if !(last_t[5] == 0)
						factor = Math.atan(last_t[4].quo(last_t[5]))
					   elsif !(last_t[0] == 0)
					     factor = Math.atan(-1*(last_t[1].quo(last_t[0])))
					   elsif (last_t[4] > 0)
						factor = Math::PI / 2
					   else
					     factor = -1*(Math::PI / 2)
					   end"
					     
			when "SCALE"
				code = "last_t = ShadeUtils.last_rule_transformation()
					   factor = Math.sqrt(last_t[0]**2 + last_t[1]**2)"
			end  
			
		predicate_string = ""
		
		case relation_type  
			when "EQUAL"
				predicate_string = "(factor == #{number})"
			when "DIFFERENT"
				predicate_string = "!(factor == #{number})"
			when "BIGGER"
				predicate_string = "(factor > #{number})"
			when "LESS"
				predicate_string = "(factor < #{number})"
			when "BIGGEREQ"
				predicate_string = "(factor >= #{number})"
			when "LESSEQ"
				predicate_string = "(factor <= #{number})"
			end
		
		code = "#{code}
			  if Shade.project.execution.execution_history
				result = #{predicate_string}
			  end"
		
		create_code(predicate_type, class_name, code)
	end
	
	return gui_dialog_rule_transformation
end

#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#predicate_type:: "Constraint" or "Goal"
#class_name:: name of the class that will wrap the constraint or the goal
#
#Method that creates the dialog for configuring the predicate focused in the whole shape
def create_GUI_dialog_whole_shape(predicate_type, class_name)
	gui_dialog_whole_shape = UI::WebDialog.new("Configure whole shape #{predicate_type}", true, "Configure whole shape #{predicate_type}", 700, 100, 150, 150, true)
	
	# Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate.
	gui_dialog_whole_shape.add_action_callback("get_data") do |web_dialog, data|
		
		data_a = data.split(",")
		ok = true
		
		relation_type = data_a[0]
		shape = data_a[1]
		
		code = ""
		
		ok = true
		case shape  
			when "AXIOM"
				code = "shape = ShadeUtils.axiom"
			when "PREVIOUS SHAPE"
				code = "shape = ShadeUtils.previous_shape"
			when "FILE SHAPE"
				load_shape_path = UI.openpanel "Load Shape", "", "*.txt"
				code = "shape = LabelledShape.new([], [])
					   shape.load(#{load_shape_path})"
			when "FILE CONTOUR"
				chosen_area_path = UI.openpanel("Open area", "" ,"*.area")	
				if chosen_area_path
					points_string = nil
					File.open(chosen_area_path, 'r') do |f|
						while line = f.gets
							line_a = line.split
							point = Array.new
							point[0] = line_a[0].to_f.m
							point[1] = line_a[1].to_f.m
							point[2] = line_a[2].to_f.m
							if points_string
								points_string = "#{points_string},[#{point[0]}, #{point[1]}, #{point[2]}]"
							else
								points_string = "[[#{point[0]}, #{point[1]}, #{point[2]}]"
							end
						end
						points_string = "#{points_string}]"
					end
					code = "#{code}
					       shape = true
					       ac = AreaConstraint.new(#{points_string})"
				else
					ok = false
				end
			end
		
		if ok
			predicate_string = ""
					
			case relation_type  
				when "EQUAL"
					if (shape == "FILE CONTOUR")
						ok = false
						UI.messagebox("You cannot use file contour option with equal relation")
					else
						predicate_string = "(ShadeUtils.current_shape == shape)"
					end
				when "DIFFERENT"
					if (shape == "FILE CONTOUR")
						ok = false
						UI.messagebox("You cannot use file contour option with different relation")
					else
						predicate_string = "!(ShadeUtils.current_shape == shape)"
					end
				when "SUBSHAPE"
					if (shape == "FILE CONTOUR")
						ok = false
						UI.messagebox("You cannot use file contour option with subshape relation")
					else
						code = "#{code}
							  flag_s=  shape.shape_expression(ShadeUtils.current_shape, Constants::SUBSHAPE, Constants::SEGMENTS, false)
						       flag_p = shape.shape_expression(ShadeUtils.current_shape, Constants::SUBSHAPE, Constants::POINTS, false)"
						predicate_string = "(flag_s && flag_p)"
					end
				when "SUPERSHAPE"
					if (shape == "FILE CONTOUR")
						ok = false
						UI.messagebox("You cannot use file contour option with supershape relation")
					else
						code = "#{code}
							  flag_s=  ShadeUtils.current_shape.shape_expression(shape, Constants::SUBSHAPE, Constants::SEGMENTS, false)
						       flag_p = ShadeUtils.current_shape.shape_expression(shape, Constants::SUBSHAPE, Constants::POINTS, false)"
						predicate_string = "(flag_s && flag_p)"
					end
				when "NOT SUBSHAPE"
					if (shape == "FILE CONTOUR")
						ok = false
						UI.messagebox("You cannot use file contour option with subshape relation")
					else
						code = "#{code}
							  flag_s=  shape.shape_expression(ShadeUtils.current_shape, Constants::SUBSHAPE, Constants::SEGMENTS, false)
						       flag_p = shape.shape_expression(ShadeUtils.current_shape, Constants::SUBSHAPE, Constants::POINTS, false)"
						predicate_string = "!(flag_s && flag_p)"
					end
				when "NOT SUPERSHAPE"
					if (shape == "FILE CONTOUR")
						ok = false
						UI.messagebox("You cannot use file contour option with supershape relation")
					else
						code = "#{code}
							  flag_s=  ShadeUtils.current_shape.shape_expression(shape, Constants::SUBSHAPE, Constants::SEGMENTS, false)
						       flag_p = ShadeUtils.current_shape.shape_expression(shape, Constants::SUBSHAPE, Constants::POINTS, false)"
						predicate_string = "!(flag_s && flag_p)"
					end
				when "INSIDE"
					if !(shape == "FILE CONTOUR")
						ok = false
						UI.messagebox("You have to specify the file contour option")
					end
					predicate_string = "ac.satisfied?"
			end
		end
			
		if ok
			gui_dialog_whole_shape.close
			
			code = "#{code}
			        result = true
				   if shape
				     result = #{predicate_string}
				   end"
			create_code(predicate_type, class_name, code)
		end
	end
	
	return gui_dialog_whole_shape
end

#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#predicate_type:: "Constraint" or "Goal"
#class_name:: name of the class that will wrap the constraint or the goal
#
#Method that creates the dialog for configuring the predicate focused in the number of points of the shape
def create_GUI_dialog_number_of_points(predicate_type, class_name)
	gui_dialog_number_of_points = UI::WebDialog.new("Configure points number #{predicate_type}", true, "Configure points number #{predicate_type}", 700, 100, 150, 150, true)
	
	# Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate.
	gui_dialog_number_of_points.add_action_callback("get_data") do |web_dialog, data|
		
		gui_dialog_number_of_points.close
		data_a = data.split(",")
		
		point_type = data_a[0]
		relation_type = data_a[1]
		argument_type = data_a[2]
		number = data_a[3]
		argument_point_type = data_a[4]
		
		code = "labels = ShadeUtils.get_labels(ShadeUtils.current_shape, \"#{point_type}\")
					   number = 0
					   labels.each { |list|
						number += list.size
					   }"
		
		case argument_type
			when "NUMBER"
				code = "#{code}
				         argument_number = #{number}"
			when "CURRENT SHAPE"
				code = "#{code}
					  labels = ShadeUtils.get_labels(ShadeUtils.current_shape, \"#{argument_type  }\")
					   argument_number = 0
					   labels.each { |list|
						argument_number += list.size
					   }"
			when "PREVIOUS SHAPE"
				code = "#{code}
					  labels = ShadeUtils.get_labels(ShadeUtils.previous_shape, \"#{argument_type  }\")
					   argument_number = 0
					   labels.each { |list|
						argument_number += list.size
					   }"
		end

		predicate_string = ""
				
		case relation_type  
			when "EQUAL"
				predicate_string = "(number == argument_number)"
			when "DIFFERENT"
				predicate_string = "!(number == argument_number)"
			when "BIGGER"
				predicate_string = "(number > argument_number)"
			when "LESS"
				predicate_string = "(number < argument_number)"
			when "BIGGEREQ"
				predicate_string = "(number >= argument_number)"
			when "LESSEQ"
				predicate_string = "(number <= argument_number)"
			end
			
		code = "#{code}
			  result = #{predicate_string}"
	
		create_code(predicate_type, class_name, code)
	end
	
	return gui_dialog_number_of_points
end

#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#predicate_type:: "Constraint" or "Goal"
#class_name:: name of the class that will wrap the constraint or the goal
#
#Method that creates the dialog for configuring the predicate focused in the position of the points of the current shape
def create_GUI_dialog_position_of_points(predicate_type, class_name)
	gui_dialog_position_of_points = UI::WebDialog.new("Configure points position #{predicate_type}", true, "Configure points position #{predicate_type}", 700, 100, 150, 150, true)
	
	# Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate.
	gui_dialog_position_of_points.add_action_callback("get_data") do |web_dialog, data|
		
		gui_dialog_position_of_points.close
		data_a = data.split(",")
		
		quantification = data_a[0]
		number = data_a[1]
		point_type = data_a[2]
		argument_point_type = data_a[3]
		relation_type = data_a[4]
		meters = data_a[5]
			
		code = "labels = ShadeUtils.get_labels(ShadeUtils.current_shape, \"#{point_type}\")"
		if !(argument_point_type == "ORIGIN")
			code = "#{code}
					argument_labels = ShadeUtils.get_labels(ShadeUtils.current_shape, \"#{argument_point_type.capitalize}\")"
		else
			code = "#{code}
					p = Point.new(0,0)"
		end
		
		predicate_string = ""
		
		case relation_type  
			when "EQUAL"
				predicate_string = "(l.key.point.distance(p) == #{meters}.m)"
			when "DIFFERENT"
				predicate_string = "!(l.key.point.distance(p) == #{meters}.m)"
			when "BIGGER"
				predicate_string = "(l.key.point.distance(p) > #{meters}.m)"
			when "LESS"
				predicate_string = "(l.key.point.distance(p) < #{meters}.m)"
			when "BIGGEREQ"
				predicate_string = "(l.key.point.distance(p) >= #{meters}.m)"
			when "LESSEQ"
				predicate_string = "(l.key.point.distance(p) <= #{meters}.m)"
			end
		
		case quantification
			when "ALL"
				if !(argument_point_type == "ORIGIN")
					code = "#{code}
						   ok = true
						   labels.each { |list| 
							list.reset_iterator
							while l = list.get_next
								found = false
								i = 0
								while ((i < argument_labels.size) && !found)
									j = 0
									while ((j < argument_labels[i].size) && !found)
										if !(l==argument_labels[i].get_node_i(j))
											p = argument_labels[i].get_node_i(j).key.point
											if #{predicate_string}
												found = true
											end
										end
										j += 1
									end
									i += 1
								end
								ok = (ok && found)
							end
						   }
						   result = ok"
				else
					code = "#{code}
						   ok = true
						   labels.each { |list| 
							list.reset_iterator
							while l = list.get_next
								if !#{predicate_string}
									ok = false
								end

							end
						   }
						   result = ok"
				end
			when "NUMBER"
				if !(argument_point_type == "ORIGIN")
					code = "#{code}
					        number = #{number}
						   number_l = 0
						   if labels.size > 0
							   labels.each { |list| 
								list.reset_iterator
								while l = list.get_next
									i = 0
									while (i < argument_labels.size) 
										j = 0
										found = false
										while ((j < argument_labels[i].size) && !found)
											if !(l==argument_labels[i].get_node_i(j))
												p = argument_labels[i].get_node_i(j).key.point
												if #{predicate_string}
													number_l += 1 
													found = true
												end
											end
											j += 1
										end
										i += 1
									end
								end
							   }
							   result = (number_l >= number)
						   end"
						   
				else
					code = "#{code}
					        number_l = 0
						   if labels.size > 0
							   labels.each { |list| 
								list.reset_iterator
								while l = list.get_next
									if !#{predicate_string}
										number_l += 1
									end
								end
							   }
							   result = (number_l >= number)
						   end"
				end
			
		end
		
		create_code(predicate_type, class_name, code)
	end
	
	return gui_dialog_position_of_points
end

#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#predicate_type:: "Constraint" or "Goal"
#class_name:: name of the class that will wrap the constraint or the goal
#
#Method that creates the dialog for configuring the predicate focused in the segments of the current shape
def create_GUI_dialog_segments(predicate_type, class_name)
	gui_dialog_segments = UI::WebDialog.new("Configure segments #{predicate_type}", true, "Configure segments #{predicate_type}", 700, 100, 150, 150, true)
	
	# Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate.
	gui_dialog_segments.add_action_callback("get_data") do |web_dialog, data|
		
		gui_dialog_segments.close
		data_a = data.split(",")
		
		quantification = data_a[0]
		number = data_a[1]
		relation_type = data_a[2]
		meters = data_a[3]

		predicate_string = ""
		case relation_type  
			when "EQUAL"
				predicate_string = "(s.key.length == #{meters}.m)"
			when "DIFFERENT"
				predicate_string = "!(s.key.length == #{meters}.m)"
			when "BIGGER"
				predicate_string = "(s.key.length > #{meters}.m)"
			when "LESS"
				predicate_string = "(s.key.length < #{meters}.m)"
			when "BIGGEREQ"
				predicate_string = "(s.key.length >= #{meters}.m)"
			when "LESSEQ"
				predicate_string = "(s.key.length <= #{meters}.m)"
			end
			
		code = ""
		
		case quantification
			when "ALL"
				code = "ok = true
					   ShadeUtils.current_shape.s.each_key { |layer_name| 
						ShadeUtils.current_shape.s[layer_name].reset_iterator
						while s_node = ShadeUtils.current_shape.s[layer_name].get_next
							s_node.list.reset_iterator
							while s = s_node.list.get_next
								if !#{predicate_string}
									ok = false
								end
							end
						end
					   }
					   result = ok"
			when "NUMBER"
				code = "number_s = 0
					   number = #{number}
					   ShadeUtils.current_shape.s.each_key { |layer_name| 
						ShadeUtils.current_shape.s[layer_name].reset_iterator
						while s_node = ShadeUtils.current_shape.s[layer_name].get_next
							s_node.list.reset_iterator
							while s = s_node.list.get_next
								if #{predicate_string}
									number_s += 1
								end
							end
						end
					   }
					   result = (number_s >= number)"
			
		end
	
		create_code(predicate_type, class_name, code)
	end
	
	return gui_dialog_segments
	
end

#Author:: Manuela Ruiz  (mailto:mruiz@lcc.uma.es)
#
#Method that creates the dialog for configuring a design script that will be able to execute a number of projects in a sequential  manner
def create_robot_dialog
	gui_dialog_robot = UI::WebDialog.new("Create new design script", true, "Create new design script", 500, 300, 150, 150, true)
	
	Shade.robot = Robot.new
	
	# Attach an action callback for saving the script
	gui_dialog_robot.add_action_callback("save_robot") do |web_dialog, kk|
		
		if Shade.robot.project_paths.size > 0
		
			path_to_save_to = UI.savepanel "Save Script", "", "script.txt"
			if path_to_save_to
				Shade.robot.save(path_to_save_to)
				gui_dialog_robot.close
			end
			
		else
			UI.messagebox("There are no projects added")
		end
		
	end
	
	# Attach an action callback for adding a project to the script
	gui_dialog_robot.add_action_callback("add_project") do |web_dialog, kk|
		
		project_path = UI.openpanel("Open project", "" ,"*.prj")
		prompts = ["Execution mode"]
		default = ["Goals"]
		list = ["Goals|Number of rules"]
		input = UI.inputbox prompts, default, list, "Execution mode"
		
		if input
			execution_mode = input[0]
			mode_string = input[0].to_s
			ok = true
			if !(input[0] == "Goals")
				prompts = ["Number of rules"]
				default = ["1"]
				list = []
				n_input = UI.inputbox prompts, default, list, "Number of rules"
				
				if n_input
					mode_string = "#{n_input[0]} rules"
					execution_mode = n_input[0]
					
				else
					ok = false
				end
			end
			if ok		
				Shade.robot.project_paths.push project_path
				Shade.robot.execution_modes.push execution_mode
				project_info_string = "#{ShadeUtils.get_title_from_path(project_path)}:#{mode_string}"
				js_command = "writeProjectInfo(\"#{project_info_string}\")"
				web_dialog.execute_script(js_command)
			end
		end
		
	end
	
	return gui_dialog_robot
end


def create_tutorial_dialog(web)
  # Create the WebDialog instance for choosing the interface type
  tutorial_dialog = UI::WebDialog.new("Tutorial para la generación de viviendas segun la normativa de Montaner", true, "Tutorial para la generación de viviendas segun la normativa de Montaner", 250, 150, 150, 150, true)
  
  # Attach an action callback
  tutorial_dialog.add_action_callback("get_tutorial") do |web_dialog, tutorial|
    
    tutorial_dialog.close 
  
    atras = ""
    siguiente = ""
    fin = false
    
    case web
    when "Tutorial.html"
       atras = "Tutorial.html"
       siguiente = "Tutorial1.html"
      fin = false
    when "Tutorial1.html"
      atras = "Tutorial.html"
      siguiente = "Tutorial2.html"
      fin = false
    when "Tutorial2.html"
      atras = "Tutorial1.html"
      siguiente = "Tutorial3.html"
      fin = false
   when "Tutorial3.html"
      atras = "Tutorial2.html"
      siguiente = "TutorialInteractivo.html"
      fin = false
   when "TutorialInteractivo.html"
	atras = "Tutorial3.html"
	siguiente = "TutorialInteractivo.html"
	fin = true
    else
      atras = "Tutorial.html"
      siguiente = "Tutorial1.html"
      fin = false
    end
    
    if !fin
      if tutorial == "Siguiente"
        # Find and show our html file
        html_path = Sketchup.find_support_file siguiente ,Constants::HTML_DIR
        name_dialog = create_tutorial_dialog(siguiente)
        name_dialog.set_file(html_path)
        name_dialog.show()
      elsif tutorial == "Atras"
        # Find and show our html file
        html_path = Sketchup.find_support_file atras ,Constants::HTML_DIR
        name_dialog = create_tutorial_dialog(atras)
        name_dialog.set_file(html_path)
        name_dialog.show()
      end
    else
      # Find and show our html file
      html_path = Sketchup.find_support_file atras ,Constants::HTML_DIR
      name_dialog = create_tutorial_dialog(atras)
      name_dialog.set_file(html_path)
      name_dialog.show()
    end
    
  end
  
  return tutorial_dialog
end


def create_gramatica_dialog(web)
  # Create the WebDialog instance for choosing the interface type
  gramatica_dialog = UI::WebDialog.new("Tutorial para gramáticas del cuadrado y de la vivienda simple", true, "Tutorial para gramáticas del cuadrado y de la vivienda simple", 250, 150, 150, 150, true)
  
  # Attach an action callback
  gramatica_dialog.add_action_callback("get_gramatica") do |web_dialog, gramatica|
	  
	  if Shade.contour_face
			Shade.contour_face.erase!  
			Shade.montaner_shape = nil
			Shade.contour_face = nil
			Shade.montaner_status = nil
			Shade.montaner_actions = nil
			Shade.previous_montaner_shape = nil
		end
    
    gramatica_dialog.close 
  
    atras = ""
    siguiente = ""
    fin = false
    
    case web
    when "Gramatica.html"
       atras = "Gramatica.html"
       siguiente = "Gramatica2.html"
      fin = false
    when "Gramatica1.html"
      atras = "Gramatica.html"
      siguiente = "Gramatica2.html"
      fin = false
    when "Gramatica2.html"
      atras = "Gramatica.html"
      siguiente = "Gramatica3.html"
      fin = false
    when "Gramatica3.html"
      atras = "Gramatica2.html"
      siguiente = "Gramatica4.html"
      fin = false
    when "Gramatica4.html"
     atras = "Gramatica3.html"
     siguiente = "Gramatica5.html"
     fin = true
#    when "Tutorial4.html"
#      atras = "Tutorial3.html"
#      siguiente = "Tutorial5.html"
#      fin = false
#    when "Tutorial5.html"
#      atras = "Tutorial4.html"
#      siguiente = "Tutorial6.html"
#      fin = false
#    when "Tutorial6.html"
#      atras = "Tutorial5.html"
#      siguiente = "Tutorial6.html"  
#      fin = true    
#   when "Tutorial.html"
#     stmt2
    else
      atras = "Gramatica.html"
      siguiente = "Gramatica1.html"
      fin = false
    end
    
    if !fin
      if gramatica == "Siguiente"
        # Find and show our html file
        html_path = Sketchup.find_support_file siguiente ,Constants::HTML_DIR
        name_dialog = create_gramatica_dialog(siguiente)
        name_dialog.set_file(html_path)
        name_dialog.show()
      elsif gramatica == "Atras"
        # Find and show our html file
        html_path = Sketchup.find_support_file atras ,Constants::HTML_DIR
        name_dialog = create_gramatica_dialog(atras)
        name_dialog.set_file(html_path)
        name_dialog.show()
      end
    else
      # Find and show our html file
      html_path = Sketchup.find_support_file atras ,Constants::HTML_DIR
      name_dialog = create_gramatica_dialog(atras)
      name_dialog.set_file(html_path)
      name_dialog.show()
    end
    
  end
  
  return gramatica_dialog
end


def start_tutorial_dialog(web)
  # Create the WebDialog instance for choosing the interface type
  tutorial_dialog = UI::WebDialog.new("Información útil", true, "Información útil", 739, 641, 739, 641, true)
  
  # Attach an action callback
  tutorial_dialog.add_action_callback("start_tutorial") do |web_dialog, tutorial|
    
    tutorial_dialog.close 
  
    atras = ""
    siguiente = ""
    fin = false
    
    case web
    when "Start.html"
       atras = "Start.html"
       siguiente = "Start.html"
      fin = true
#    when "Tutorial1.html"
#      atras = "Tutorial.html"
#      siguiente = "Tutorial2.html"
#      fin = false
#    when "Tutorial2.html"
#      atras = "Tutorial1.html"
#      siguiente = "Tutorial3.html"
#      fin = false
#    when "Tutorial3.html"
#      atras = "Tutorial2.html"
#      siguiente = "Tutorial4.html"
#      fin = false
#    when "Tutorial4.html"
#      atras = "Tutorial3.html"
#      siguiente = "Tutorial5.html"
#      fin = false
#    when "Tutorial5.html"
#      atras = "Tutorial4.html"
#      siguiente = "Tutorial6.html"
#      fin = false
#    when "Tutorial6.html"
#      atras = "Tutorial5.html"
#      siguiente = "Tutorial6.html"  
#      fin = true    
#   when "Tutorial.html"
#     stmt2
    else
      atras = "Tutorial.html"
      siguiente = "Tutorial1.html"
      fin = false
    end
    
    if !fin
      if tutorial == "Siguiente"
        # Find and show our html file
        html_path = Sketchup.find_support_file siguiente ,Constants::HTML_DIR
        name_dialog = start_tutorial_dialog(siguiente)
        name_dialog.set_file(html_path)
        name_dialog.show()
      elsif tutorial == "Atras"
        # Find and show our html file
        html_path = Sketchup.find_support_file atras ,Constants::HTML_DIR
        name_dialog = start_tutorial_dialog(atras)
        name_dialog.set_file(html_path)
        name_dialog.show()
      end
    else
      # Find and show our html file
      html_path = Sketchup.find_support_file atras ,Constants::HTML_DIR
      name_dialog = start_tutorial_dialog(atras)
      name_dialog.set_file(html_path)
      name_dialog.show()
    end
    
  end
  
  return tutorial_dialog
end