/**
 * DevExtreme (ui/map/provider.js)
 * Version: 19.2.5 (build 19359-1956)
 * Build date: Wed Dec 25 2019
 *
 * Copyright (c) 2012 - 2019 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
"use strict";
var Promise = require("../../core/polyfills/promise"),
    Class = require("../../core/class"),
    map = require("../../core/utils/iterator").map,
    typeUtils = require("../../core/utils/type"),
    eventUtils = require("../../events/utils"),
    isPlainObject = typeUtils.isPlainObject,
    isNumeric = typeUtils.isNumeric;
var abstract = Class.abstract;
var Provider = Class.inherit({
    _defaultRouteWeight: function() {
        return 5
    },
    _defaultRouteOpacity: function() {
        return .5
    },
    _defaultRouteColor: function() {
        return "#0000FF"
    },
    ctor: function(map, $container) {
        this._mapWidget = map;
        this._$container = $container
    },
    render: function(markerOptions, routeOptions) {
        return this._renderImpl().then(function() {
            return Promise.all([this._applyFunctionIfNeeded("addMarkers", markerOptions), this._applyFunctionIfNeeded("addRoutes", routeOptions)]).then(function() {
                return true
            })
        }.bind(this))
    },
    _renderImpl: abstract,
    updateDimensions: abstract,
    updateMapType: abstract,
    updateBounds: abstract,
    updateCenter: abstract,
    updateZoom: abstract,
    updateControls: abstract,
    updateMarkers: function(markerOptionsToRemove, markerOptionsToAdd) {
        return new Promise(function(resolve) {
            return this._applyFunctionIfNeeded("removeMarkers", markerOptionsToRemove).then(function(removeValue) {
                this._applyFunctionIfNeeded("addMarkers", markerOptionsToAdd).then(function(addValue) {
                    resolve(addValue ? addValue : removeValue)
                })
            }.bind(this))
        }.bind(this))
    },
    addMarkers: abstract,
    removeMarkers: abstract,
    adjustViewport: abstract,
    updateRoutes: function(routeOptionsToRemove, routeOptionsToAdd) {
        return new Promise(function(resolve) {
            return this._applyFunctionIfNeeded("removeRoutes", routeOptionsToRemove).then(function(removeValue) {
                this._applyFunctionIfNeeded("addRoutes", routeOptionsToAdd).then(function(addValue) {
                    resolve(addValue ? addValue : removeValue)
                })
            }.bind(this))
        }.bind(this))
    },
    addRoutes: abstract,
    removeRoutes: abstract,
    clean: abstract,
    map: function() {
        return this._map
    },
    isEventsCanceled: function() {
        return false
    },
    _option: function(name, value) {
        if (void 0 === value) {
            return this._mapWidget.option(name)
        }
        this._mapWidget.setOptionSilent(name, value)
    },
    _keyOption: function(providerName) {
        var key = this._option("key");
        return void 0 === key[providerName] ? key : key[providerName]
    },
    _parseTooltipOptions: function(option) {
        return {
            text: option.text || option,
            visible: option.isShown || false
        }
    },
    _getLatLng: function(location) {
        if ("string" === typeof location) {
            var coords = map(location.split(","), function(item) {
                    return item.trim()
                }),
                numericRegex = /^[-+]?[0-9]*\.?[0-9]*$/;
            if (2 === coords.length && coords[0].match(numericRegex) && coords[1].match(numericRegex)) {
                return {
                    lat: parseFloat(coords[0]),
                    lng: parseFloat(coords[1])
                }
            }
        } else {
            if (Array.isArray(location) && 2 === location.length) {
                return {
                    lat: location[0],
                    lng: location[1]
                }
            } else {
                if (isPlainObject(location) && isNumeric(location.lat) && isNumeric(location.lng)) {
                    return location
                }
            }
        }
        return null
    },
    _areBoundsSet: function() {
        return this._option("bounds.northEast") && this._option("bounds.southWest")
    },
    _addEventNamespace: function(name) {
        return eventUtils.addNamespace(name, this._mapWidget.NAME)
    },
    _applyFunctionIfNeeded: function(fnName, array) {
        if (!array.length) {
            return Promise.resolve()
        }
        return this[fnName](array)
    },
    _fireAction: function(name, actionArguments) {
        this._mapWidget._createActionByOption(name)(actionArguments)
    },
    _fireClickAction: function(actionArguments) {
        this._fireAction("onClick", actionArguments)
    },
    _fireMarkerAddedAction: function(actionArguments) {
        this._fireAction("onMarkerAdded", actionArguments)
    },
    _fireMarkerRemovedAction: function(actionArguments) {
        this._fireAction("onMarkerRemoved", actionArguments)
    },
    _fireRouteAddedAction: function(actionArguments) {
        this._fireAction("onRouteAdded", actionArguments)
    },
    _fireRouteRemovedAction: function(actionArguments) {
        this._fireAction("onRouteRemoved", actionArguments)
    }
});
module.exports = Provider;
