var _ = require('underscore')._;

module.exports = function(app, settings) {
    /**
     * Map loader, express route middleware.
     */
    function loadMap(req, res, next) {
        if (req.param('mapfile_64')) {
            var path = require('path');
            var Map = require('tilelive.js').Map;
            var map = new Map(req.param('mapfile_64'), path.join(__dirname, settings.mapfile_dir), true);
            map.localize(function() {
                res.map = map.mapnik_map();
                next();
            });
        }
        else {
            next(new Error('Map could not be loaded.'));
        }
    }

    /**
     * Layer loader, express route middleware.
     */
    function loadLayer(req, res, next) {
        res.layers = [];
        var layers = res.map.layers();
        var data = res.map.describe_data();
        for (var i = 0; i < layers.length; i++) {
            var id = layers[i].datasource.id;
            var layer = {
                id: id,
                fields: data[id] ? data[id].fields : {}
            };
            for (var field in layer.fields) {
                layer.fields[field] = {
                    type: layer.fields[field],
                    values: [],
                };
            }
            var values = res.map.features(i);
            for (var j = 0; j < values.length; j++) {
                for (var field in values[j]) {
                    var layerValues = layer.fields[field].values;
                    var fieldValue = values[j][field];
                    if (
                        _.indexOf(layerValues, fieldValue)  === -1 &&
                        fieldValue !== ''
                    ) {
                        layerValues.push(fieldValue);
                    }
                }
            }
            for (var field in layer.fields) {
                if (layer.fields[field].values.length) {
                    if (layer.fields[field].type === 'Number') {
                        layer.fields[field].min = _.min(
                            layer.fields[field].values,
                            function(object) { return object; }
                        );
                        layer.fields[field].max = _.max(
                            layer.fields[field].values,
                            function(object) { return object; }
                        );
                    }
                    else if (layer.fields[field].type === 'String') {
                        layer.fields[field].min = _.min(
                            layer.fields[field].values,
                            function(object) { return object.length; }
                        );
                        layer.fields[field].max = _.max(
                            layer.fields[field].values,
                            function(object) { return object.length; }
                        );
                    }
                }
            }

            if (!req.param('layer_id')) {
                res.layers.push(layer);
            }
            else if (req.param('layer_id') === layer.id) {
                res.layers.push(layer);
            }
        }
        if (req.param('layer_id') && res.layers.length === 0) {
            next(new Error('Layer could not be loaded.'));
        }
        next();
    }

    /**
     * Inspect abilities.
     */
    app.get('/abilities', function(req, res) {
        var mapnik = require('mapnik');
        res.send(
            {
                fonts: mapnik.fonts(),
                datasources: mapnik.datasources()
            }
        );
    });

    /**
     * Load layer model.
     */
    app.get('/:mapfile_64/:layer_id?', loadMap, loadLayer, function(req, res, next) {
        if (req.param('layer_id')) {
            res.send(res.layers.pop());
        }
        else {
            res.send(res.layers);
        }
    });

    /**
     * @TODO datasource SRS autodetection endpoint.
     */
    /*
    app.get('/:datasource_64', loadDatasource, function(req, res, next) {
        res.send({});
    });
    */
};

@@ -1039,16 +1039,17 @@
 lds : %7B%7D
+,
 %0A       
@@ -1045,39 +1045,32 @@
 %7B%7D,%0A        
-    %7D;%0A
         
     for (var
@@ -1061,222 +1061,17 @@
     
-    for (var field in layer.fields) %7B%0A                layer.fields%5Bfield%5D = %7B%0A                    type: layer.fields%5Bfield%5D,%0A                    values: %5B%5D,%0A                %7D;%0A            %7D%0A            var values =
+features:
  res
@@ -1086,17 +1086,16 @@
 tures(i)
-;
 %0A       
@@ -1103,1631 +1103,10 @@
     
-for (var j = 0; j %3C values.length; j++) %7B%0A                for (var field in values%5Bj%5D) %7B%0A                    var layerValues = layer.fields%5Bfield%5D.values;%0A                    var fieldValue = values%5Bj%5D%5Bfield%5D;%0A                    if (%0A                        _.indexOf(layerValues, fieldValue)  === -1 &&%0A                        fieldValue !== ''%0A                    ) %7B%0A                        layerValues.push(fieldValue);%0A                    %7D%0A                %7D%0A            %7D%0A            for (var field in layer.fields) %7B%0A                if (layer.fields%5Bfield%5D.values.length) %7B%0A                    if (layer.fields%5Bfield%5D.type === 'Number') %7B%0A                        layer.fields%5Bfield%5D.min = _.min(%0A                            layer.fields%5Bfield%5D.values,%0A                            function(object) %7B return object; %7D%0A                        );%0A                        layer.fields%5Bfield%5D.max = _.max(%0A                            layer.fields%5Bfield%5D.values,%0A                            function(object) %7B return object; %7D%0A                        );%0A                    %7D%0A                    else if (layer.fields%5Bfield%5D.type === 'String') %7B%0A                        layer.fields%5Bfield%5D.min = _.min(%0A                            layer.fields%5Bfield%5D.values,%0A                            function(object) %7B return object.length; %7D%0A                        );%0A                        layer.fields%5Bfield%5D.max = _.max(%0A                            layer.fields%5Bfield%5D.values,%0A                            function(object) %7B return object.length; %7D%0A                        );%0A                    %7D%0A                %7D%0A            %7D%0A
+%7D;
 %0A   

Send all features directly rather than a digest.