(function($) {
    jQuery.fn.attrs = function (names) {
        if(typeof names == "string") {
            return $(this).map(function() {return $(this).attr(names);});
        } else {
            var attributes = {};
            jQuery.each(names, function(i, key) {
                attributes[key] = $(this).attr(key);
            });
            return attributes;
        }
    };
})(jQuery);

(function($) {
    var extractIds  = function (item) { 
        return $(item).attrs("id").map(function() { 
            return this.replace(/^sub-/, ""); 
        });
    };
    var $id = function (identifier) { return "#sub-" + identifier; };
    
    jQuery.fn.zincLookup = function (options) {
        // Default options (callback is defined after)
        options = jQuery.extend(true, {}, {
            url:            window.zinc.root+"/zinc-lookup.php",
            type:           "json+html",
            getSubIds:      extractIds,
            buildQuery:     null,               // Will go to url with type
            callback:       null,               // Will insert into destination
            wrapper:        null,
            summary:        ".summary",
            destination:    $id,
            buildData:      null,               // Will insert html in to wrapper
            insertData:     null,               // Will append to target
            afterInsert:    null,               // Will add tooltip effects
            chunkSize:      null,
            filters:        null,
            tooltip: {
                effect:         "slide", 
                position:       "top center",
                predelay:       1000,
                delay:          150,
                onBeforeShow:   function () { 
                    this.getTip().find(".catalogs .catalog-items a.external.lookup").supplierItemQuery(); 
                },
                dynamic: {
                    left: {
                        direction:  'down',
                        offset: [-200, 0],
                        bounce:     true}}}
        }, options);
        
        // Wraps in "body if provided or simply returns html
        var build = options.buildData || function (body) {
            var wrapper = options.wrapper || null;
            return wrapper ? $(wrapper).html(body) : $(body);
        };
        
        
        // How an insertion is done
        var insert = options.insertData || function (element, target, options) {
            return element.appendTo($(target));
        };
        
        // What will take place after the insert is done
        // Defines tooltip actions
        var after = options.afterInsert || function (element, target, options) {
            $(element).parent().children(options.summary)
                .tooltip(options.tooltip)
                .dynamic(options.tooltip.dynamic)
        };
        
        // Default callback, appends a wrapped version of the body to the 
        // corresponding ID element
        var callback = options.callback || function (data) {
            jQuery.each(data, function(id, body) {
                var target = typeof options.destination == "function" ?
                                options.destination(id) : options.destination;
                var wrapper = typeof options.wrapper == "function" ?
                                options.wrapper(id) : options.wrapper;
                var element = build(body);
                insert(element, target, options);
                after(element, target, options);
            });
        };
        
        var buildQuery = options.buildQuery || function (sub_ids) {
            return {
                "sub_id": jQuery.makeArray(sub_ids).join(" "),
                "type":   options.type,
                "filter": options.filter
            };
        };
        
        var chunks    = [];
        var sub_ids   = options.getSubIds(this);    // Extract sub_ids
        var chunkSize = options.chunkSize || sub_ids.length;
        
        // Chunk out requests to decreate tooltip appearance time
        // Right shifts act as a quick cast to integers... javascript only uses
        // doubles by "default"
        for(var i = 0, chunk = 0; i < sub_ids.length; i++, chunk = i / chunkSize >> 0) {
            if(i % chunkSize >> 0){
                chunks[chunk].push(sub_ids[i])
            } else {
                chunks[chunk] = [sub_ids[i]];
            }
        }
        
        for(var i = 0; i < chunks.length; i++) {
            jQuery.getJSON(options.url, buildQuery(chunks[i]), callback);
        }
    };
})(jQuery);





