/*
  Multimaps
*/
%include <std_map.i>

%fragment("StdMultimapTraits","header",fragment="StdSequenceTraits")
{
  namespace swig {
    template <class RubySeq, class K, class T >
    inline void 
    assign(const RubySeq& rubyseq, std::multimap<K,T > *multimap) {
      typedef typename std::multimap<K,T>::value_type value_type;
      typename RubySeq::const_iterator it = rubyseq.begin();
      for (;it != rubyseq.end(); ++it) {
	multimap->insert(value_type(it->first, it->second));
      }
    }

    template <class K, class T>
    struct traits_asptr<std::multimap<K,T> >  {
      typedef std::multimap<K,T> multimap_type;
      static int asptr(VALUE obj, std::multimap<K,T> **val) {
	int res = SWIG_ERROR;
	if ( TYPE(obj) == T_HASH ) {
	  static ID id_to_a = rb_intern("to_a");
	  VALUE items = rb_funcall(obj, id_to_a, 0);
	  return traits_asptr_stdseq<std::multimap<K,T>, std::pair<K, T> >::asptr(items, val);
	} else {
	  multimap_type *p;
	  res = SWIG_ConvertPtr(obj,(void**)&p,swig::type_info<multimap_type>(),0);
	  if (SWIG_IsOK(res) && val)  *val = p;
	}
	return res;
      }
    };
      
    template <class K, class T >
    struct traits_from<std::multimap<K,T> >  {
      typedef std::multimap<K,T> multimap_type;
      typedef typename multimap_type::const_iterator const_iterator;
      typedef typename multimap_type::size_type size_type;
            
      static VALUE from(const multimap_type& multimap) {
	swig_type_info *desc = swig::type_info<multimap_type>();
	if (desc && desc->clientdata) {
	  return SWIG_NewPointerObj(new multimap_type(multimap), desc, SWIG_POINTER_OWN);
	} else {
	  size_type size = multimap.size();
	  int rubysize = (size <= (size_type) INT_MAX) ? (int) size : -1;
	  if (rubysize < 0) {
	    SWIG_RUBY_THREAD_BEGIN_BLOCK;
	    rb_raise(rb_eRuntimeError,
		     "multimap size not valid in Ruby");
	    SWIG_RUBY_THREAD_END_BLOCK;
	    return Qnil;
	  }
	  VALUE obj = rb_hash_new();
	  for (const_iterator i= multimap.begin(); i!= multimap.end(); ++i) {
	    VALUE key = swig::from(i->first);
	    VALUE val = swig::from(i->second);

	    VALUE oldval = rb_hash_aref( obj, key );
	    if ( oldval == Qnil )
	      rb_hash_aset(obj, key, val);
	    else {
	      // Multiple values for this key, create array if needed
	      // and add a new element to it.
	      VALUE ary;
	      if ( TYPE(oldval) == T_ARRAY )
		ary = oldval;
	      else
		{
		  ary = rb_ary_new2(2);
		  rb_ary_push( ary, oldval );
		  rb_hash_aset( obj, key, ary );
		}
	      rb_ary_push( ary, val );
	    }
	    
	  }
	  return obj;
	}
      }
    };
  }
}

%define %swig_multimap_methods(MultiMap...) 
  %swig_map_common(%arg(MultiMap));

  %extend {
    VALUE __getitem__(const key_type& key) const {
      MultiMap::const_iterator i = self->find(key);
      if ( i != self->end() )
	{
	  MultiMap::const_iterator e = $self->upper_bound(key);
	  VALUE ary = rb_ary_new();
	  for ( ; i != e; ++i )
	    {
	      rb_ary_push( ary, swig::from<MultiMap::mapped_type>( i->second ) );
	    }
	  if ( RARRAY_LEN(ary) == 1 )
	    return RARRAY_PTR(ary)[0];
	  return ary;
	}
      else
	return Qnil;
    }

    void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) {
      self->insert(MultiMap::value_type(key,x));
    }

  VALUE inspect()
    {
      MultiMap::iterator i = $self->begin();
      MultiMap::iterator e = $self->end();
      VALUE str = rb_str_new2( swig::type_name< MultiMap >() );
      str = rb_str_cat2( str, " {" );
      VALUE tmp;
      while ( i != e )
	{
	  const MultiMap::key_type& key    = i->first;
	  const MultiMap::key_type& oldkey = key;
	  tmp = swig::from( key );
	  str = rb_str_buf_append( str, rb_inspect(tmp) );
	  str = rb_str_cat2( str, "=>" );

	  VALUE vals = rb_ary_new();
	  for ( ; i != e && key == oldkey; ++i )
	    {
	      const MultiMap::mapped_type& val = i->second;
	      tmp = swig::from( val );
	      rb_ary_push( vals, tmp );
	    }

	  if ( RARRAY_LEN(vals) == 1 )
	    {
	      str = rb_str_buf_append( str, rb_inspect(tmp) );
	    }
	  else
	    {
	      str = rb_str_buf_append( str, rb_inspect(vals) );
	    }
	}
      str = rb_str_cat2( str, "}" );
      return str;
    }

  VALUE to_a()
    {
      MultiMap::const_iterator i = $self->begin();
      MultiMap::const_iterator e = $self->end();
      VALUE ary = rb_ary_new2( std::distance( i, e ) );
      VALUE tmp;
      while ( i != e )
	{
	  const MultiMap::key_type& key    = i->first;
	  const MultiMap::key_type& oldkey = key;
	  tmp = swig::from( key );
	  rb_ary_push( ary, tmp );

	  VALUE vals = rb_ary_new();
	  for ( ; i != e && key == oldkey; ++i )
	    {
	      const MultiMap::mapped_type& val = i->second;
	      tmp = swig::from( val );
	      rb_ary_push( vals, tmp );
	    }

	  if ( RARRAY_LEN(vals) == 1 )
	    {
	      rb_ary_push( ary, tmp );
	    }
	  else
	    {
	      rb_ary_push( ary, vals );
	    }
	}
      return ary;
    }

  VALUE to_s()
    {
      MultiMap::iterator i = $self->begin();
      MultiMap::iterator e = $self->end();
      VALUE str = rb_str_new2( "" );
      VALUE tmp;
      while ( i != e )
	{
	  const MultiMap::key_type& key    = i->first;
	  const MultiMap::key_type& oldkey = key;
	  tmp = swig::from( key );
	  tmp = rb_obj_as_string( tmp );
	  str = rb_str_buf_append( str, tmp );

	  VALUE vals = rb_ary_new();
	  for ( ; i != e && key == oldkey; ++i )
	    {
	      const MultiMap::mapped_type& val = i->second;
	      tmp = swig::from( val );
	      rb_ary_push( vals, tmp );
	    }

	  tmp = rb_obj_as_string( vals );
	  str = rb_str_buf_append( str, tmp );
	}
      return str;
    }
  }
%enddef


%mixin std::multimap "Enumerable";

%rename("delete")     std::multimap::__delete__;
%rename("reject!")    std::multimap::reject_bang;
%rename("map!")       std::multimap::map_bang;
%rename("empty?")     std::multimap::empty;
%rename("include?" )  std::multimap::__contains__ const;
%rename("has_key?" )  std::multimap::has_key const;

%alias  std::multimap::push          "<<";

%include <std/std_multimap.i>

