/*
 *  call-seq:
 *     PriorityQueue.new(capacity = 32) -> new_pq
 *     PriorityQueue.new({:capacity => 32,
 *                        :less_than_proc => lambda{|a, b| a < b}) -> new_pq
 *     PriorityQueue.new({:capacity => 32}) {|a, b| a < b} -> new_pq
 *  
 *  Returns a new empty priority queue object with an optional capacity.
 *  Once the capacity is filled, the lowest valued elements will be
 *  automatically popped off the top of the queue as more elements are
 *  inserted into the queue.
 */
static VALUE 
frb_pq_init(int argc, VALUE *argv, VALUE self)
{
    if (argc >= 1) {
        PriQ *pq;
        VALUE options = argv[0];
        VALUE param;
        int capa = PQ_START_CAPA;
        GET_PQ(pq, self);
        switch (TYPE(options)) {
            case T_FIXNUM:
                capa = FIX2INT(options);
                break;
            case T_HASH:
                if (!NIL_P(param = rb_hash_aref(options,
                                                ID2SYM(id_capacity)))) {
                    capa = FIX2INT(param);
                }
                if (!NIL_P(param = rb_hash_aref(options,
                                                ID2SYM(id_less_than)))) {
                    pq->proc = param;
                }
                break;
            default:
                rb_raise(rb_eArgError,
                         "PriorityQueue#initialize only takes a Hash or "
                         "an integer");
                
                break;
        }
        if (capa < 0) {
            rb_raise(rb_eIndexError,
                     "PriorityQueue must have a capacity > 0. %d < 0",
                     capa);
        }
        pq->capa = capa;
        if (rb_block_given_p()) {
            pq->proc = rb_block_proc();
        }
        if (argc > 1) {
            rb_raise(rb_eArgError,
                     "PriorityQueue#initialize only takes one parameter");
        }
    }

    return self;
}