/*
 * L.TimeDimension.Layer:  an abstract Layer that can be managed/synchronized with a TimeDimension.
 * The constructor recieves a layer (of any kind) and options.
 * Any children class should implement `_onNewTimeLoading`, `isReady` and `_update` functions
 * to react to time changes.
 */

L.TimeDimension.Layer = (L.Layer || L.Class).extend({

    includes: L.Mixin.Events,
    options: {
        opacity: 1
    },

    initialize: function(layer, options) {
        L.setOptions(this, options || {});
        this._map = null;
        this._baseLayer = layer;
        this._currentLayer = null;
        this._timeDimension = this.options.timeDimension || null;
        this.setOpacity(this.options.opacity);
    },

    addTo: function(map) {
        map.addLayer(this);
        return this;
    },

    onAdd: function(map) {
        this._map = map;
        if (!this._timeDimension && map.timeDimension) {
            this._timeDimension = map.timeDimension;
        }
        this._timeDimension.on("timeloading", this._onNewTimeLoading, this);
        this._timeDimension.on("timeload", this._update, this);
        this._timeDimension.registerSyncedLayer(this);
        this._update();
    },

    onRemove: function(map) {
        this._timeDimension.unregisterSyncedLayer(this);
        this._timeDimension.off("timeloading", this._onNewTimeLoading, this);
        this._timeDimension.off("timeload", this._update, this);
        this.eachLayer(map.removeLayer, map);
        this._map = null;
    },

    eachLayer: function(method, context) {
        method.call(context, this._baseLayer);
        return this;
    },

    setZIndex: function(zIndex) {
        if (this._baseLayer.setZIndex) {
            this._baseLayer.setZIndex(zIndex);
        }
        if (this._currentLayer && this._currentLayer.setZIndex) {
            this._currentLayer.setZIndex(zIndex);
        }
    },
	
	setOpacity: function(opacity) {
        this.options.opacity = opacity;
        if (this._baseLayer.setOpacity) {
            this._baseLayer.setOpacity(opacity);
        }
        if (this._currentLayer && this._currentLayer.setOpacity) {
            this._currentLayer.setOpacity(opacity);
        }
    },

    bringToBack: function() {
        if (!this._currentLayer) {
            return;
        }
        this._currentLayer.bringToBack();
    },

    bringToFront: function() {
        if (!this._currentLayer) {
            return;
        }
        this._currentLayer.bringToFront();
    },

    _onNewTimeLoading: function(ev) {
        // to be implemented for each type of layer
        this.fire('timeload', {
            time: ev.time
        });
        return;
    },

    isReady: function(time) {
        // to be implemented for each type of layer
        return true;
    },

    _update: function() {
        // to be implemented for each type of layer
        return true;
    },

    getBaseLayer: function(){
        return this._baseLayer;
    }

});

L.timeDimension.layer = function(layer, options) {
    return new L.TimeDimension.Layer(layer, options);
};

@@ -403,16 +403,35 @@
 opacity:
+ 1,%0A        zIndex:
  1%0A    %7D
@@ -683,55 +683,8 @@
 ll;%0A
-        this.setOpacity(this.options.opacity);%0A
     
@@ -1626,32 +1626,70 @@
 ction(zIndex) %7B%0A
+        this.options.zIndex = zIndex;%0A
         if (this
@@ -1904,14 +1904,37 @@
     
-%7D,%0A%09%0A%09
+    return this;%0A    %7D,%0A%0A    
 setO
@@ -2227,24 +2227,45 @@
 ;%0A        %7D%0A
+        return this;%0A
     %7D,%0A%0A    
@@ -2393,24 +2393,45 @@
 ngToBack();%0A
+        return this;%0A
     %7D,%0A%0A    
@@ -2561,24 +2561,45 @@
 gToFront();%0A
+        return this;%0A
     %7D,%0A%0A    
@@ -3024,16 +3024,17 @@
 nction()
+ 
 %7B%0A      
@@ -3178,9 +3178,8 @@
 ons);%0A%7D;
-%0A

Remove setOpacity in initialize