L.DNC = L.DNC || {};
/*
**
** AppController is the primary point of app initialization. It basically 'ties
** every together'
**
*/
L.DNC.AppController = L.Class.extend({

    statics: {},

    // default options
    options: {},

    // L.Class.extend automatically executes 'initialize'
    initialize : function( options ) {

        // override defaults with passed options
        L.setOptions(this, options);

        this.mapView = new L.DNC.MapView();
        this.dropzone = new L.DNC.DropZone( this.mapView._map, {} );
        this.layerlist = new L.DNC.LayerList( this.mapView._map, { layerContainerId: 'sidebar' } );
        this.menubar = new L.DNC.MenuBar(
            { id: 'menu-bar' }
        ).addTo( document.body );
        this.bottom_menu = new L.DNC.MenuBar(
            { id: 'add-remove', classList: ["bottom", "menu"] }
        ).addTo( document.getElementById('sidebar') );

        // build out menus
        this.menus = {
            geo: new L.DNC.Menu('Geoprocessing', {  // New dropdown menu
                items: ['bezier', 'buffer', 'center', 'centroid', 'envelope', 'union', 'tin']
            }).addTo( this.menubar ),               // Append to menubar

            addLayer: new L.DNC.Menu('Add', {       // New dropdown menu
                items: ['upload', 'load from url'],
                menuDirection: 'above'
            }).addTo( this.bottom_menu ),           // Append to menubar

            removeLayer: new L.DNC.Menu('Remove', {}).addTo( this.bottom_menu ),
        };
        this.geoOpsConfig = {
            operations: new L.DNC.Geo(),        // Configurations of GeoOperations
            executor: new L.DNC.GeoExecute()    // Executor of GeoOperations
        };

        this.FileOpsConfig = {
            operations: new L.DNC.File(),       // Configurations of FileOperations
            executor: new L.DNC.FileExecute()    // Executor of GeoOperations
        };


        this.forms = new L.DNC.Forms();

        this.notification = new L.DNC.Notifications();
        this._addEventHandlers();

    },

    _addEventHandlers: function(){
        this.dropzone.fileReader.on( 'fileparsed', this._handleParsedFile.bind( this ) );

        // Handle clicks on items within geoMenu
        // NOTE: This is where an operation is tied to a menu item
        this.menus.geo.on( 'clickedOperation', this._handleOperationClick.bind( this, this.geoOpsConfig ) );
        this.menus.removeLayer.on( 'clickedOperation', this._handleOperationClick.bind( this, this.FileOpsConfig ) );
    },

    /*
    **
    ** Lookup operation by name from operations configuration, validate selection,
    ** and render appropriate form
    **
    */
    _handleOperationClick: function( opsConfig, e ) {
        var config = opsConfig.operations[e.action];

        // Validate selection
        try {
            opsConfig.executor.validate( e.action, this.getLayerSelection(), config );
        }
        catch(err) {
            this.notification.add({
                text: err.message,
                type: 'alert',
                time: 2500
            });
            console.error(err);
            return;
        }

        var form = this.forms.render( e.action, config );
        form.on( 'submit', this._handleFormSubmit.bind( this, opsConfig ) );
    },

    /*
    **
    ** Take input from an options form, use input to execute operation, get new
    ** layer, pass new layer off to be added to map.
    **
    */
    _handleFormSubmit: function( opsConfig, e ) {
        var config = opsConfig.operations[e.action];
        var results = opsConfig.executor.execute(
            e.action,
            e.parameters,
            config,
            this.getLayerSelection()
        );

        if (config.createsLayer) {
            this._handleGeoResult(results);
        } else {
            // TODO: Handle non-geo results
        }
    },

    /*
    **
    ** Take newly parsed file, add to make and layerlist
    **
    */
    _handleParsedFile: function( e ) {
        var layer = L.mapbox.featureLayer( e.file );
        this.layerlist.addLayer( layer, e.fileInfo.name );
        this.mapView.numLayers++;

        this.notification.add({
            text: '<strong>' + e.fileInfo.name + '</strong> added successfully.',
            type: 'success',
            time: 2500
        });
    },

    /*
    **
    ** Take new layer, add to map and layerlist
    **
    */
    _handleGeoResult: function( layer ) {
        var mapLayer = L.mapbox.featureLayer( layer.geometry );
        this.layerlist.addLayer( mapLayer, layer.name );

        this.notification.add({
            text: '<strong>' + layer.name + '</strong> created successfully.',
            type: 'success',
            time: 2500
        });
    },

    getLayerSelection: function(){
        return this.layerlist.selection.list || [];
    }

});

@@ -2793,17 +2793,16 @@
 ction%5D;%0A
-%0A
         
@@ -3163,16 +3163,130 @@
      %7D%0A%0A
+        if (config.disableForm) %7B%0A            return this._handleFormSubmit( opsConfig, e );%0A        %7D else %7B%0A    
         
@@ -3327,32 +3327,36 @@
 tion, config );%0A
+    
         form.on(
@@ -3408,32 +3408,42 @@
  opsConfig ) );%0A
+        %7D%0A
     %7D,%0A%0A    /*%0A 

Allow form to be skipped