 
#  Copyright 2006-2008 Stanislav Senotrusov <senotrusov@gmail.com>
# 
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
# 
#      http://www.apache.org/licenses/LICENSE-2.0
# 
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.


#  Copyright (c) 2004-2007 David Heinemeier Hansson
#
#  Permission is hereby granted, free of charge, to any person obtaining
#  a copy of this software and associated documentation files (the
#  "Software"), to deal in the Software without restriction, including
#  without limitation the rights to use, copy, modify, merge, publish,
#  distribute, sublicense, and/or sell copies of the Software, and to
#  permit persons to whom the Software is furnished to do so, subject to
#  the following conditions:
#
#  The above copyright notice and this permission notice shall be
#  included in all copies or substantial portions of the Software.
#
#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
#  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
#  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
#  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
#  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


module ActionView::Helpers
  module FormOptionsHelper
    def grouped_collection_select(object, method, collection, partition_by, sort_groups_by, sort_items_by, group_label_method, value_method, text_method, options = {}, html_options = {})
      InstanceTag.new(object, method, self, nil, options.delete(:object)).to_grouped_collection_select_tag(collection, partition_by, sort_groups_by, sort_items_by, group_label_method, value_method, text_method, options, html_options)
    end
    
    def grouped_options_for_select(collection, partition_by, sort_groups_by, sort_items_by, group_label_method, value_method, text_method, value)
      (partitioned = collection.partition_by(&partition_by)).keys.sort_by(&sort_groups_by).inject("") do |options_for_select, group|
        options_for_select += "<optgroup label=\"#{html_escape(group.send(group_label_method))}\">"
        options_for_select += options_from_collection_for_select(partitioned[group].sort_by(&sort_items_by), value_method, text_method, value)
        options_for_select += '</optgroup>'
      end
    end
  end
  
  class InstanceTag
    def to_grouped_collection_select_tag(collection, partition_by, sort_groups_by, sort_items_by, group_label_method, value_method, text_method, options, html_options)
      html_options = html_options.stringify_keys
      add_default_name_and_id(html_options)
      value = value(object)
      content_tag(
        "select", add_options(grouped_options_for_select(collection, partition_by, sort_groups_by, sort_items_by, group_label_method, value_method, text_method, value), options, value), html_options
      )
    end
  end
  
  class FormBuilder
    def grouped_collection_select(method, collection, partition_by, sort_groups_by, sort_items_by, group_label_method, value_method, text_method, options = {}, html_options = {})
      @template.grouped_collection_select(@object_name, method, collection, partition_by, sort_groups_by, sort_items_by, group_label_method, value_method, text_method, options.merge(:object => @object), html_options)
    end
  end
end
