# * George Moschovitis  <gm@navel.gr>
# (c) 2004-2005 Navel, all rights reserved.
# $Id$

require 'nitro/render'
require 'nitro/scaffold'
require 'nitro/filters'

module N
	
# The Controller part in the MVC paradigm.
# A Controller encpsulates a set of actions.

class Controller 
	include Render
	include Scaffolding
	include Filtering		

	# Use the method_missing hook to compile the actions
	# for this controller.
	
	def method_missing(action, *args)
		if Rendering.compile_action(self.class, action, @base)
			send(action, *args)
		else
			super
		end
	end

	class << self 
		alias __old_inherited inherited

		def inherited(subclass)
			subclass.class_eval %{
				DEF_FILE = caller[2].split(':').first
			}	
			__old_inherited(subclass)
		end

		# Return the 'action' methods for this Controller.
		# Some dangerous methods from ancestors are removed.
		
		def action_methods
    	classes = self.ancestors.reject do |a| 
				[Object, Kernel, Render].include?(a) 
			end
			
			methods =  classes.inject([]) do |action_methods, klass| 
				action_methods + klass.public_instance_methods(false) 
			end
			
			methods.delete('method_missing')

			# temp hack, FIXME:

			methods.delete('pretty_print')
			methods.delete('pretty_print_cycle')
			methods.delete('pretty_print_instance_variables')
			methods.delete('pretty_print_inspect')
			
			return methods
		end

		# Return the arguments of the given action.
		
		def action_method_arguments(action)
			if Nitro.resolve_action_arguments
				unless defined?(ArgsProcessor)
					begin
						require_gem 'ParseTree'
						require 'parse_tree'
						require 'sexp_processor'
					rescue
						# No parse tree support
					end
					
					Object.class_eval %{
						class ArgsProcessor < SexpProcessor # :nodoc:
							attr_accessor :args

							def initialize
								super
								@require_empty = false
							end

							def process_args(exp)
								@args = exp.slice(1..-1)
								return Sexp.new(exp)
							end
						end
					}
				end

				ptree = ParseTree.new
				sexpp = ArgsProcessor.new
				sexp = ptree.parse_tree_for_method(self, action)	
				sexpp.process(sexp)

				return sexpp.args
			else
				return []
			end
		end
	end
end

end