module OrbitApp
    module Module
      module SideBarRegisition
          Version = "0.2"

          module ClassMethods
            @@side_bars = []

          def add(var)
            @@side_bars << var
          end

          def find_by_key(key)
            @@side_bars.each{|t|
              return t if t.name == key
            }
            return nil
          end

          def render_all(request,params,user,current_module_app)
            @@side_bars.collect{|t| t.render(request,params,user,current_module_app)}.join.html_safe
          end

          def all
            return @@side_bars
          end

          def all_get_ordered!
            @@side_bars.sort! {|x,y| x.get_sidebar_order! <=> y.get_sidebar_order! }
          end

        end
      
        extend ClassMethods
        def self.included( other )
          other.extend( ClassMethods )
        end

        class SideBar
          # include ApplicationHelper
          # include AdminHelper
          include SideBarRenderer

          def initialize(name = '',key,get_module_app, approvable_with_link, authorizable_with_link, &block)     
            @head_label = name
            @context_links = []
            @available_for = []
            @active_for_controllers = []
            @active_for_object_auth = []
            @active_for_app_auth = []
            @active_for_tag = []
            @head_link = ""
            @app_base_path = ''
            @module_app_key = key
            @get_module_app = get_module_app
            @sidebar_order = 0 
            @approvable_with_link = approvable_with_link
            @authorizable_with_link = authorizable_with_link
            block.arity < 1 ? instance_eval(&block) : block.call(self) if block_given?
            # setup_module_app(module_app_key)
            finalize!
            SideBarRegisition.add(self)
            SideBarRegisition.all_get_ordered!
          end
          
          def get_sidebar_order!
            @sidebar_order = (get_module_app.sidebar_order rescue 0)
          end
          
          def get_icon_class
            @icon_class
          end

          def get_module_app
            @get_module_app.call
          end

          def get_module_app_key
            @module_app_key
          end

          def head_label_i18n(var,options ={})
            @head_label = var
            @icon_class = options[:icon_class]
          end

          def available_for(var)
            @available_for = var
          end

          def active_for_controllers(var)
            @active_for_controllers = var
          end

          def active_for_object_auth(var)
            @active_for_object_auth = var
          end

          def head_link_path(var)
            @head_link = var
          end

          def context_link(*var)
            var[1].merge!({:module_app_key=>@module_app_key,:get_module_app=>@get_module_app}) unless @module_app_key.nil?
            new_context_link = ContextLink.new(*var)
            @context_links << new_context_link
          end

          def finalize!
            set_controllers_scope
            # set_default_active_app_auth
            current_priority = @context_links.count
            if @approvable_with_link
              context_link 'approval_setting',
                            :link_path => "admin_authorizations_path(get_module_app.key, 'category_approval')",
                            :priority => current_priority + 1,
                            :available_for => [:manager]
            end
            if @authorizable_with_link
              context_link 'module_authorization',
                            :link_path => "admin_authorizations_path(get_module_app.key)",
                            :priority => current_priority + 2,
                            :available_for => [:manager]
            end
            @context_links.each do |t| 
              # t.set_module_app = @module_app
              t.finalize!
            end
          end

          protected
          # def setup_module_app(var)
          #   @module_app_title = var
          #   @module_app = ModuleApp.where(:key=>var).desc(:create_date).first
          #   @module_app_key = @module_app.key
          # end

          # def set_default_active_app_auth
          #   @active_for_app_auth = @module_app.title
          # end

          def set_controllers_scope
            var = @active_for_controllers
            @active_for_controllers = []
            var[:private].each do |controller|
              @active_for_controllers <<   "panel/#{@module_app_key}/back_end/"+controller
            end unless var[:private].nil?
            var[:public].each do |controller|
              @active_for_controllers <<   controller
            end unless var[:public].nil? 
          end
        end

        class ContextLink
          include ContextLinkRenderer
          attr_reader :label_i18n,:available_for,:priority,:path,:active_for_action

          def initialize(label_i18n="NoNameLink",options={})
            @label_i18n = label_i18n
            @priority = options[:priority] || 0
            @path = options[:link_path] || ""
            set_available_for_avoiding_sensitive_links(options[:available_for] )
            @active_for_action = options[:active_for_action] || []
            @active_for_object_auth = options[:active_for_object_auth] || []
            @active_for_app_auth = options[:active_for_app_auth] || []
            @active_for_category = options[:active_for_category] || []
            @active_for_tag = options[:active_for_tag] || []
            @module_app_key = options[:module_app_key]
            @get_module_app = options[:get_module_app]
          end

          def set_available_for_avoiding_sensitive_links(available_for)
            sensitive_list = {}
            sensitive_list[:module_app] =/.*manager_auth_proc.*/ 
            sensitive_list[:object_auth] = /.*object_auth.*/
            
            sensitive_list.each do |index,regx|
              if @path.match(regx)
              @available_for = case index
                when :module_app
                   [:admin]
                when :object_auth
                   [:manager,:admin]
              end #of case
            end #of if
            end #of each
            @available_for = available_for if @available_for.nil?
          end #of def

          def get_module_app
            @get_module_app.call
          end

          def active?
            for_action = @active_for_action.blank? ? false : active_for_action?
            for_app_auth = @active_for_app_auth.blank? ? false : active_for_app_auth?
            for_ob_auth = @active_for_object_auth.blank? ? false : active_for_ob_auths?
            for_category = @active_for_category.blank? ? false : active_for_category?
            for_tag = @active_for_tag.blank? ? false : active_for_tag?
            for_action || for_app_auth || for_ob_auth || for_tag
          end

          def active_for_action?
            @active_for_action[controller] == action
          end

          # def set_module_app=(var)
          #   @module_app = var
          #   @module_app_key = var.key
          # end

          def finalize!
            set_active_actions
          end

          protected
          def set_active_actions
            controller_action_hash = @active_for_action
            @active_for_action = Hash[controller_action_hash.map{|controller,action| ["panel/#{@module_app_key}/back_end/"+controller.to_s,action.to_s]}]
          end
        end
    end
  end
end