text: import {Renderer} from './Renderer';
  import * as DomUtil from '../../dom/DomUtil';
  import * as DomEvent from '../../dom/DomEvent';
  import Browser from '../../core/Browser';
  import {stamp} from '../../core/Util';
  import {svgCreate, pointsToPath} from './SVG.Util';
  export {pointsToPath};
  import {vmlMixin, vmlCreate} from './SVG.VML';
  
  export var create = Browser.vml ? vmlCreate : svgCreate;
  
  /*
   * @class SVG
   * @inherits Renderer
   * @aka L.SVG
   *
   * Allows vector layers to be displayed with [SVG](https://developer.mozilla.org/docs/Web/SVG).
   * Inherits `Renderer`.
   *
   * Due to [technical limitations](http://caniuse.com/#search=svg), SVG is not
   * available in all web browsers, notably Android 2.x and 3.x.
   *
   * Although SVG is not available on IE7 and IE8, these browsers support
   * [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language)
   * (a now deprecated technology), and the SVG renderer will fall back to VML in
   * this case.
   *
   * @example
   *
   * Use SVG by default for all paths in the map:
   *
   * ```js
   * var map = L.map('map', {
   * 	renderer: L.svg()
   * });
   * ```
   *
   * Use a SVG renderer with extra padding for specific vector geometries:
   *
   * ```js
   * var map = L.map('map');
   * var myRenderer = L.svg({ padding: 0.5 });
   * var line = L.polyline( coordinates, { renderer: myRenderer } );
   * var circle = L.circle( center, { renderer: myRenderer } );
   * ```
   */
  
  export var SVG = Renderer.extend({
  
  	getEvents: function () {
  		var events = Renderer.prototype.getEvents.call(this);
  		events.zoomstart = this._onZoomStart;
  		return events;
  	},
  
  	_initContainer: function () {
  		this._container = create('svg');
  
  		// makes it possible to click through svg root; we'll reset it back in individual paths
  		this._container.setAttribute('pointer-events', 'none');
  
  		this._rootGroup = create('g');
  		this._container.appendChild(this._rootGroup);
  	},
  
  	_destroyContainer: function () {
  		DomUtil.remove(this._container);
  		DomEvent.off(this._container);
  		delete this._container;
  		delete this._rootGroup;
  		delete this._svgSize;
  	},
  
  	_onZoomStart: function () {
  		// Drag-then-pinch interactions might mess up the center and zoom.
  		// In this case, the easiest way to prevent this is re-do the renderer
  		//   bounds and padding when the zooming starts.
  		this._update();
  	},
  
  	_update: function () {
  		if (this._map._animatingZoom && this._bounds) { return; }
  
  		Renderer.prototype._update.call(this);
  
  		var b = this._bounds,
  		    size = b.getSize(),
  		    container = this._container;
  
  		// set size of svg-container if changed
  		if (!this._svgSize || !this._svgSize.equals(size)) {
  			this._svgSize = size;
  			container.setAttribute('width', size.x);
  			container.setAttribute('height', size.y);
  		}
  
  		// movement: update container viewBox so that we don't have to change coordinates of individual layers
  		DomUtil.setPosition(container, b.min);
  		container.setAttribute('viewBox', [b.min.x, b.min.y, size.x, size.y].join(' '));
  
  		this.fire('update');
  	},
  
  	// methods below are called by vector layers implementations
  
  	_initPath: function (layer) {
  		var path = layer._path = create('path');
  
  		// @namespace Path
  		// @option className: String = null
  		// Custom class name set on an element. Only for SVG renderer.
  		if (layer.options.className) {
  			DomUtil.addClass(path, layer.options.className);
  		}
  
  		if (layer.options.interactive) {
  			DomUtil.addClass(path, 'leaflet-interactive');
  		}
  
  		this._updateStyle(layer);
  		this._layers[stamp(layer)] = layer;
  	},
  
  	_addPath: function (layer) {
  		if (!this._rootGroup) { this._initContainer(); }
  		this._rootGroup.appendChild(layer._path);
  		layer.addInteractiveTarget(layer._path);
  	},
  
  	_removePath: function (layer) {
  		DomUtil.remove(layer._path);
  		layer.removeInteractiveTarget(layer._path);
  		delete this._layers[stamp(layer)];
  	},
  
  	_updatePath: function (layer) {
  		layer._project();
  		layer._update();
  	},
  
  	_updateStyle: function (layer) {
  		var path = layer._path,
  		    options = layer.options;
  
  		if (!path) { return; }
  
  		if (options.stroke) {
  			path.setAttribute('stroke', options.color);
  			path.setAttribute('stroke-opacity', options.opacity);
  			path.setAttribute('stroke-width', options.weight);
  			path.setAttribute('stroke-linecap', options.lineCap);
  			path.setAttribute('stroke-linejoin', options.lineJoin);
  
  			if (options.dashArray) {
  				path.setAttribute('stroke-dasharray', options.dashArray);
  			} else {
  				path.removeAttribute('stroke-dasharray');
  			}
  
  			if (options.dashOffset) {
  				path.setAttribute('stroke-dashoffset', options.dashOffset);
  			} else {
  				path.removeAttribute('stroke-dashoffset');
  			}
  		} else {
  			path.setAttribute('stroke', 'none');
  		}
  
  		if (options.fill) {
  			path.setAttribute('fill', options.fillColor || options.color);
  			path.setAttribute('fill-opacity', options.fillOpacity);
  			path.setAttribute('fill-rule', options.fillRule || 'evenodd');
  		} else {
  			path.setAttribute('fill', 'none');
  		}
  	},
  
  	_updatePoly: function (layer, closed) {
  		this._setPath(layer, pointsToPath(layer._parts, closed));
  	},
  
  	_updateCircle: function (layer) {
  		var p = layer._point,
  		    r = Math.max(Math.round(layer._radius), 1),
  		    r2 = Math.max(Math.round(layer._radiusY), 1) || r,
  		    arc = 'a' + r + ',' + r2 + ' 0 1,0 ';
  
  		// drawing a circle with two half-arcs
  		var d = layer._empty() ? 'M0 0' :
  			'M' + (p.x - r) + ',' + p.y +
  			arc + (r * 2) + ',0 ' +
  			arc + (-r * 2) + ',0 ';
  
  		this._setPath(layer, d);
  	},
  
  	_setPath: function (layer, path) {
  		layer._path.setAttribute('d', path);
  	},
  
  	// SVG does not have the concept of zIndex so we resort to changing the DOM order of elements
  	_bringToFront: function (layer) {
  		DomUtil.toFront(layer._path);
  	},
  
  	_bringToBack: function (layer) {
  		DomUtil.toBack(layer._path);
  	}
  });
  
  if (Browser.vml) {
  	SVG.include(vmlMixin);
  }
  
  // @namespace SVG
  // @factory L.svg(options?: Renderer options)
  // Creates a SVG renderer with the given options.
  export function svg(options) {
  	return Browser.svg || Browser.vml ? new SVG(options) : null;
  }
  