// @tag enterprise
/**
 * The AMF Reader is used by an {@link Ext.data.amf.Proxy AMF Proxy} to read 
 * records from a server response that contains binary data in either AMF0 or
 * AMF3 format. AMF Reader constructs an {@link Ext.data.amf.Packet AMF Packet}
 * and uses it to decode the binary data into javascript objects, then simply
 * allows its superclass ({@link Ext.data.reader.Json}) to handle converting the
 * raw javascript objects into {@link Ext.data.Model} instances.
 * 
 * For a more detailed tutorial see the
 * [AMF Guide](../guides/backend_connectors/amf.html).
 */
Ext.define('Ext.data.amf.Reader', {
    extend: 'Ext.data.reader.Json',
 
    alias: 'reader.amf',
 
    requires: [
        'Ext.data.amf.Packet'
    ],
 
    /**
     * @cfg {Number} messageIndex
     * AMF Packets can contain multiple messages. This config specifies the
     * 0-based index of the message that contains the record data.
     */
    messageIndex: 0,
    
    responseType: 'arraybuffer',
 
    /**
     * Reads records from a XMLHttpRequest response object containing a binary
     * AMF Packet and returns a ResultSet.
     * @param {Object} response The XMLHttpRequest response object
     * @return {Ext.data.ResultSet} 
     */
    read: function(response) {
        var me = this,
            bytes = response.responseBytes,
            packet, messages, resultSet;
 
        if (!bytes) {
            throw "AMF Reader cannot process the response because it does not contain " +
                  "binary data. Make sure the Proxy's 'binary' config is true.";
        }
            
        packet = new Ext.data.amf.Packet();
        packet.decode(bytes);
        messages = packet.messages;
 
        if (messages.length) {
            resultSet = me.readRecords(messages[me.messageIndex].body);
        }
        else {
            // no messages, return null result set
            resultSet = me.nullResultSet;
            
            if (packet.invalid) {
                // packet contains invalid data
                resultSet.success = false;
            }
        }
 
        return resultSet;
    }
});