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

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

    template <class ValueType>
    struct from_key_oper 
    {
      typedef const ValueType& argument_type;
      typedef  VALUE result_type;
      result_type operator()(argument_type v) const
      {
	return swig::from(v.first);
      }
    };

    template <class ValueType>
    struct from_value_oper 
    {
      typedef const ValueType& argument_type;
      typedef  VALUE result_type;
      result_type operator()(argument_type v) const
      {
	return swig::from(v.second);
      }
    };

    template<class OutIterator, class FromOper, 
	     class ValueType = typename OutIterator::value_type>
    struct MapIterator_T : ConstIteratorClosed_T<OutIterator, ValueType, FromOper>
    {
      MapIterator_T(OutIterator curr, OutIterator first, OutIterator last, VALUE seq)
	: ConstIteratorClosed_T<OutIterator,ValueType,FromOper>(curr, first, last, seq)
      {
      }
    };


    template<class OutIterator,
	     class FromOper = from_key_oper<typename OutIterator::value_type> >
    struct MapKeyIterator_T : MapIterator_T<OutIterator, FromOper>
    {
      MapKeyIterator_T(OutIterator curr, OutIterator first, OutIterator last, VALUE seq)
	: MapIterator_T<OutIterator, FromOper>(curr, first, last, seq)
      {
      }
    };

    template<typename OutIter>
    inline ConstIterator*
    make_output_key_iterator(const OutIter& current, const OutIter& begin, 
			     const OutIter& end, VALUE seq = 0)
    {
      return new MapKeyIterator_T<OutIter>(current, begin, end, seq);
    }

    template<class OutIterator,
	     class FromOper = from_value_oper<typename OutIterator::value_type> >
    struct MapValueIterator_T : MapIterator_T<OutIterator, FromOper>
    {
      MapValueIterator_T(OutIterator curr, OutIterator first, OutIterator last, VALUE seq)
	: MapIterator_T<OutIterator, FromOper>(curr, first, last, seq)
      {
      }
    };
    

    template<typename OutIter>
    inline ConstIterator*
    make_output_value_iterator(const OutIter& current, const OutIter& begin, 
			       const OutIter& end, VALUE seq = 0)
    {
      return new MapValueIterator_T<OutIter>(current, begin, end, seq);
    }
  }
}

%define %swig_map_common(Map...)
  %swig_container_methods(%arg(Map));
  // %swig_sequence_iterator(%arg(Map));

  %extend {
    
    VALUE __delete__(const key_type& key) {
      Map::iterator i = self->find(key);
      if (i != self->end()) {
	self->erase(i);
	return swig::from( key );
      }
      else {
	return Qnil;
      }
    }
    
    bool has_key(const key_type& key) const {
      Map::const_iterator i = self->find(key);
      return i != self->end();
    }
    
    VALUE keys() {
      Map::size_type size = self->size();
      int rubysize = (size <= (Map::size_type) INT_MAX) ? (int) size : -1;
      if (rubysize < 0) {
	SWIG_RUBY_THREAD_BEGIN_BLOCK;
	rb_raise(rb_eRuntimeError, "map size not valid in Ruby");
	SWIG_RUBY_THREAD_END_BLOCK;
	return Qnil;
      }
      VALUE ary = rb_ary_new2(rubysize);
      Map::const_iterator i = self->begin();
      Map::const_iterator e = self->end();
      for ( ; i != e; ++i ) {
	rb_ary_push( ary, swig::from(i->first) );
      }
      return ary;
    }

    Map* each()
      {
	if ( !rb_block_given_p() )
	  rb_raise( rb_eArgError, "no block given");

	VALUE k, v;
	Map::iterator i = self->begin();
	Map::iterator e = self->end();
	for ( ; i != e; ++i )
	  {
	    const Map::key_type&    key = i->first;
	    const Map::mapped_type& val = i->second;

	    k = swig::from<Map::key_type>(key);
	    v = swig::from<Map::mapped_type>(val);
	    rb_yield_values(2, k, v);
	  }
	
	return self;
      }

    %newobject select;
    Map* select() {
      if ( !rb_block_given_p() )
	rb_raise( rb_eArgError, "no block given" );

      Map* r = new Map;
      Map::iterator i = $self->begin();
      Map::iterator e = $self->end();
      for ( ; i != e; ++i )
	{
	  VALUE k = swig::from<Map::key_type>(i->first);
	  VALUE v = swig::from<Map::mapped_type>(i->second);
	  if ( RTEST( rb_yield_values(2, k, v) ) )
	    $self->insert(r->end(), *i);
	}
	
      return r;
    }

  %typemap(in) (int argc, VALUE* argv) {
    $1 = argc;
    $2 = argv;
  }

  VALUE values_at(int argc, VALUE* argv, ...) {
    
    VALUE r = rb_ary_new();
    ID   id = rb_intern("[]");
    swig_type_info* type = swig::type_info< Map >();
    VALUE me = SWIG_NewPointerObj( $self, type, 0 );
    for ( int i = 0; i < argc; ++i )
      {
	VALUE key = argv[i];
	VALUE tmp = rb_funcall( me, id, 1, key );
	rb_ary_push( r, tmp );
      }
    
    return r;
  }


    Map* each_key()
      {
	if ( !rb_block_given_p() )
	  rb_raise( rb_eArgError, "no block given");

	VALUE r;
	Map::iterator i = self->begin();
	Map::iterator e = self->end();
	for ( ; i != e; ++i )
	  {
	    r = swig::from( i->first );
	    rb_yield(r);
	  }
	
	return self;
      }
    
    VALUE values() {
      Map::size_type size = self->size();
      int rubysize = (size <= (Map::size_type) INT_MAX) ? (int) size : -1;
      if (rubysize < 0) {
	SWIG_RUBY_THREAD_BEGIN_BLOCK;
	rb_raise(rb_eRuntimeError, "map size not valid in Ruby");
	SWIG_RUBY_THREAD_END_BLOCK;
	return Qnil;
      }
      VALUE ary = rb_ary_new2(rubysize);
      Map::const_iterator i = self->begin();
      Map::const_iterator e = self->end();
      for ( ; i != e; ++i ) {
	rb_ary_push( ary, swig::from(i->second) );
      }
      return ary;
    }
    
    Map* each_value()
      {
	if ( !rb_block_given_p() )
	  rb_raise( rb_eArgError, "no block given");

	VALUE r;
	Map::iterator i = self->begin();
	Map::iterator e = self->end();
	for ( ; i != e; ++i )
	  {
	    r = swig::from( i->second );
	    rb_yield(r);
	  }
	
	return self;
      }

    VALUE entries() {
      Map::size_type size = self->size();
      int rubysize = (size <= (Map::size_type) INT_MAX) ? (int) size : -1;
      if (rubysize < 0) {
	SWIG_RUBY_THREAD_BEGIN_BLOCK;
	rb_raise(rb_eRuntimeError, "map size not valid in Ruby");
	SWIG_RUBY_THREAD_END_BLOCK;
	return Qnil;
      }
      VALUE ary = rb_ary_new2(rubysize);
      Map::const_iterator i = self->begin();
      Map::const_iterator e = self->end();
      for ( ; i != e; ++i ) {
	rb_ary_push( ary, swig::from<std::pair<Map::key_type, 
		     Map::mapped_type> >(*i) );
      }
      return ary;
    }
    
    bool __contains__(const key_type& key) {
      return self->find(key) != self->end();
    }

    %newobject key_iterator(VALUE *RUBY_SELF);
    swig::ConstIterator* key_iterator(VALUE *RUBY_SELF) {
      return swig::make_output_key_iterator($self->begin(), $self->begin(), 
					    $self->end(), *RUBY_SELF);
    }

    %newobject value_iterator(VALUE *RUBY_SELF);
    swig::ConstIterator* value_iterator(VALUE *RUBY_SELF) {
      return swig::make_output_value_iterator($self->begin(), $self->begin(), 
					      $self->end(), *RUBY_SELF);
    }

  }
%enddef

%define %swig_map_methods(Map...)
  %swig_map_common(Map)
  %extend {
    VALUE __getitem__(const key_type& key) const {
      Map::const_iterator i = self->find(key);
      if ( i != self->end() )
	return swig::from<Map::mapped_type>( i->second );
      else
	return Qnil;
    }

    void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) {
      (*self)[key] = x;
    }

  VALUE inspect()
    {
      Map::const_iterator i = $self->begin();
      Map::const_iterator e = $self->end();
      VALUE str = rb_str_new2( swig::type_name< Map >() );
      str = rb_str_cat2( str, " {" );
      bool comma = false;
      VALUE tmp;
      for ( ; i != e; ++i, comma = true )
	{
	  if (comma) str = rb_str_cat2( str, "," );
	  tmp = swig::from< Map::key_type >( i->first );
	  tmp = rb_inspect( tmp );
	  str = rb_str_buf_append( str, tmp );
	  str = rb_str_cat2( str, "=>" );
	  tmp = swig::from< Map::mapped_type >( i->second );
	  tmp = rb_inspect( tmp );
	  str = rb_str_buf_append( str, tmp );
	}
      str = rb_str_cat2( str, "}" );
      return str;
    }

  VALUE to_a()
    {
      Map::const_iterator i = $self->begin();
      Map::const_iterator e = $self->end();
      VALUE ary = rb_ary_new2( std::distance( i, e ) );
      VALUE tmp;
      for ( ; i != e; ++i )
	{
	  // @todo: improve -- this should just be swig::from(*i)
	  tmp = swig::from< std::pair<Map::key_type, 
	    Map::mapped_type> >( *i );
	  rb_ary_push( ary, tmp );
	}
      return ary;
    }

  VALUE to_s()
    {
      Map::iterator i = $self->begin();
      Map::iterator e = $self->end();
      VALUE str = rb_str_new2( "" );
      VALUE tmp;
      for ( ; i != e; ++i )
	{
	  // @todo: improve -- this should just be swig::from(*i)
	  tmp = swig::from< std::pair<Map::key_type, 
	    Map::mapped_type> >( *i );
	  tmp = rb_obj_as_string( tmp );
	  str = rb_str_buf_append( str, tmp );
	}
      return str;
    }

  }
%enddef


%mixin std::map "Enumerable";


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

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


%include <std/std_map.i>
