/*
 * call-seq:
 *   new(...)
 *
 * Note:
 * * It is _not_ recommended to create instances of Queue directly, rather user Queue.open. Which
 *   creates the queue, opens the queue, executes a supplied code block and then ensures the queue
 *   is closed.
 *
 * Parameters:
 * * Since the number of parameters can vary dramatically, all parameters are passed by name in a hash
 * * See Queue.open for details on all parameters
 *
 */
VALUE Queue_initialize(VALUE self, VALUE hash)
{
    VALUE   str;
    size_t  size;
    size_t  length;
    VALUE   val;
    VALUE   q_name;
    PQUEUE  pq;

    Check_Type(hash, T_HASH);

    Data_Get_Struct(self, QUEUE, pq);

    val = rb_hash_aref(hash, ID2SYM(ID_queue_manager));    /* :queue_manager */
    if (NIL_P(val))
    {
        rb_raise(rb_eArgError, "Mandatory parameter :queue_manager missing from WMQ::Queue::new");
    }
    else
    {
        PQUEUE_MANAGER pqm;
        Data_Get_Struct(val, QUEUE_MANAGER, pqm);
        pq->exception_on_error = pqm->exception_on_error;  /* Copy exception_on_error from Queue Manager setting */
        pq->trace_level        = pqm->trace_level;  /* Copy trace_level from Queue Manager setting */

        rb_iv_set(self, "@queue_manager", val);
    }

    q_name = rb_hash_aref(hash, ID2SYM(ID_q_name));            /* :q_name */
    if (NIL_P(q_name))
    {
        rb_raise(rb_eArgError, "Mandatory parameter :q_name missing from WMQ::Queue::new");
    }

    /* --------------------------------------------------
     * If :q_name is a hash, extract :q_name and :q_mgr_name
     * --------------------------------------------------*/
    if(TYPE(q_name) == T_HASH)
    {
        if(pq->trace_level)
            printf ("WMQ::Queue::new q_name is a hash\n");

        WMQ_HASH2MQCHARS(q_name,q_mgr_name, pq->od.ObjectQMgrName)

        q_name = rb_hash_aref(q_name, ID2SYM(ID_q_name));
        if (NIL_P(q_name))
        {
            rb_raise(rb_eArgError,
                        "Mandatory parameter :q_name missing from :q_name hash passed to WMQ::Queue::new");
        }
    }

    str = StringValue(q_name);
    rb_iv_set(self, "@original_name", str);           /* Store original queue name */
    strncpy(pq->q_name, RSTRING(str)->ptr, sizeof(pq->q_name));

    pq->open_options = Queue_extract_open_options(hash, q_name);

    if(pq->trace_level > 1) printf("WMQ::Queue::new Queue:%s\n", pq->q_name);

    val = rb_hash_aref(hash, ID2SYM(ID_dynamic_q_name));   /* :dynamic_q_name */
    if (!NIL_P(val))
    {
        rb_iv_set(self, "@dynamic_q_name", val);
    }

    WMQ_HASH2MQBYTES(hash,alternate_security_id,         pq->od.AlternateSecurityId)
    WMQ_HASH2MQLONG(hash,close_options,                 pq->close_options)
    WMQ_HASH2BOOL(hash,fail_if_exists,                pq->fail_if_exists)

    val = rb_hash_aref(hash, ID2SYM(ID_alternate_user_id)); /* :alternate_user_id */
    if (!NIL_P(val))
    {
        WMQ_HASH2MQCHARS(hash,alternate_user_id,         pq->od.AlternateUserId)
        pq->open_options |= MQOO_ALTERNATE_USER_AUTHORITY;
    }

    return Qnil;
}