'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _index = require('../index.js');

var _index2 = _interopRequireDefault(_index);

var _extent = require('../extent.js');

var _extent2 = _interopRequireDefault(_extent);

var _ows = require('../format/ows.js');

var _ows2 = _interopRequireDefault(_ows);

var _xlink = require('../format/xlink.js');

var _xlink2 = _interopRequireDefault(_xlink);

var _xml = require('../format/xml.js');

var _xml2 = _interopRequireDefault(_xml);

var _xsd = require('../format/xsd.js');

var _xsd2 = _interopRequireDefault(_xsd);

var _xml3 = require('../xml.js');

var _xml4 = _interopRequireDefault(_xml3);

function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : { default: obj };
}

/**
 * @classdesc
 * Format for reading WMTS capabilities data.
 *
 * @constructor
 * @extends {ol.format.XML}
 * @api
 */
var _ol_format_WMTSCapabilities_ = function () {
    _xml2.default.call(this);

    /**
     * @type {ol.format.OWS}
     * @private
     */
    this.owsParser_ = new _ows2.default();
};

_index2.default.inherits(_ol_format_WMTSCapabilities_, _xml2.default);

/**
 * Read a WMTS capabilities document.
 *
 * @function
 * @param {Document|Node|string} source The XML source.
 * @return {Object} An object representing the WMTS capabilities.
 * @api
 */
_ol_format_WMTSCapabilities_.prototype.read;

/**
 * @inheritDoc
 */
_ol_format_WMTSCapabilities_.prototype.readFromDocument = function (doc) {
    for (var n = doc.firstChild; n; n = n.nextSibling) {
        if (n.nodeType == Node.ELEMENT_NODE) {
            return this.readFromNode(n);
        }
    }
    return null;
};

/**
 * @inheritDoc
 */
_ol_format_WMTSCapabilities_.prototype.readFromNode = function (node) {
    var version = node.getAttribute('version').trim();
    var WMTSCapabilityObject = this.owsParser_.readFromNode(node);
    if (!WMTSCapabilityObject) {
        return null;
    }
    WMTSCapabilityObject['version'] = version;
    WMTSCapabilityObject = _xml4.default.pushParseAndPop(WMTSCapabilityObject, _ol_format_WMTSCapabilities_.PARSERS_, node, []);
    return WMTSCapabilityObject ? WMTSCapabilityObject : null;
};

/**
 * @private
 * @param {Node} node Node.
 * @param {Array.<*>} objectStack Object stack.
 * @return {Object|undefined} Attribution object.
 */
_ol_format_WMTSCapabilities_.readContents_ = function (node, objectStack) {
    return _xml4.default.pushParseAndPop({}, _ol_format_WMTSCapabilities_.CONTENTS_PARSERS_, node, objectStack);
};

/**
 * @private
 * @param {Node} node Node.
 * @param {Array.<*>} objectStack Object stack.
 * @return {Object|undefined} Layers object.
 */
_ol_format_WMTSCapabilities_.readLayer_ = function (node, objectStack) {
    return _xml4.default.pushParseAndPop({}, _ol_format_WMTSCapabilities_.LAYER_PARSERS_, node, objectStack);
};

/**
 * @private
 * @param {Node} node Node.
 * @param {Array.<*>} objectStack Object stack.
 * @return {Object|undefined} Tile Matrix Set object.
 */
_ol_format_WMTSCapabilities_.readTileMatrixSet_ = function (node, objectStack) {
    return _xml4.default.pushParseAndPop({}, _ol_format_WMTSCapabilities_.TMS_PARSERS_, node, objectStack);
};

/**
 * @private
 * @param {Node} node Node.
 * @param {Array.<*>} objectStack Object stack.
 * @return {Object|undefined} Style object.
 */
_ol_format_WMTSCapabilities_.readStyle_ = function (node, objectStack) {
    var style = _xml4.default.pushParseAndPop({}, _ol_format_WMTSCapabilities_.STYLE_PARSERS_, node, objectStack);
    if (!style) {
        return undefined;
    }
    var isDefault = node.getAttribute('isDefault') === 'true';
    style['isDefault'] = isDefault;
    return style;
};

/**
 * @private
 * @param {Node} node Node.
 * @param {Array.<*>} objectStack Object stack.
 * @return {Object|undefined} Tile Matrix Set Link object.
 */
_ol_format_WMTSCapabilities_.readTileMatrixSetLink_ = function (node, objectStack) {
    return _xml4.default.pushParseAndPop({}, _ol_format_WMTSCapabilities_.TMS_LINKS_PARSERS_, node, objectStack);
};

/**
 * @private
 * @param {Node} node Node.
 * @param {Array.<*>} objectStack Object stack.
 * @return {Object|undefined} Dimension object.
 */
_ol_format_WMTSCapabilities_.readDimensions_ = function (node, objectStack) {
    return _xml4.default.pushParseAndPop({}, _ol_format_WMTSCapabilities_.DIMENSION_PARSERS_, node, objectStack);
};

/**
 * @private
 * @param {Node} node Node.
 * @param {Array.<*>} objectStack Object stack.
 * @return {Object|undefined} Resource URL object.
 */
_ol_format_WMTSCapabilities_.readResourceUrl_ = function (node, objectStack) {
    var format = node.getAttribute('format');
    var template = node.getAttribute('template');
    var resourceType = node.getAttribute('resourceType');
    var resource = {};
    if (format) {
        resource['format'] = format;
    }
    if (template) {
        resource['template'] = template;
    }
    if (resourceType) {
        resource['resourceType'] = resourceType;
    }
    return resource;
};

/**
 * @private
 * @param {Node} node Node.
 * @param {Array.<*>} objectStack Object stack.
 * @return {Object|undefined} WGS84 BBox object.
 */
_ol_format_WMTSCapabilities_.readWgs84BoundingBox_ = function (node, objectStack) {
    var coordinates = _xml4.default.pushParseAndPop([], _ol_format_WMTSCapabilities_.WGS84_BBOX_READERS_, node, objectStack);
    if (coordinates.length != 2) {
        return undefined;
    }
    return _extent2.default.boundingExtent(coordinates);
};

/**
 * @private
 * @param {Node} node Node.
 * @param {Array.<*>} objectStack Object stack.
 * @return {Object|undefined} Legend object.
 */
_ol_format_WMTSCapabilities_.readLegendUrl_ = function (node, objectStack) {
    var legend = {};
    legend['format'] = node.getAttribute('format');
    legend['href'] = _xlink2.default.readHref(node);
    return legend;
};

/**
 * @private
 * @param {Node} node Node.
 * @param {Array.<*>} objectStack Object stack.
 * @return {Object|undefined} Coordinates object.
 */
_ol_format_WMTSCapabilities_.readCoordinates_ = function (node, objectStack) {
    var coordinates = _xsd2.default.readString(node).split(' ');
    if (!coordinates || coordinates.length != 2) {
        return undefined;
    }
    var x = +coordinates[0];
    var y = +coordinates[1];
    if (isNaN(x) || isNaN(y)) {
        return undefined;
    }
    return [x, y];
};

/**
 * @private
 * @param {Node} node Node.
 * @param {Array.<*>} objectStack Object stack.
 * @return {Object|undefined} TileMatrix object.
 */
_ol_format_WMTSCapabilities_.readTileMatrix_ = function (node, objectStack) {
    return _xml4.default.pushParseAndPop({}, _ol_format_WMTSCapabilities_.TM_PARSERS_, node, objectStack);
};

/**
 * @private
 * @param {Node} node Node.
 * @param {Array.<*>} objectStack Object stack.
 * @return {Object|undefined} TileMatrixSetLimits Object.
 */
_ol_format_WMTSCapabilities_.readTileMatrixLimitsList_ = function (node, objectStack) {
    return _xml4.default.pushParseAndPop([], _ol_format_WMTSCapabilities_.TMS_LIMITS_LIST_PARSERS_, node, objectStack);
};

/**
 * @private
 * @param {Node} node Node.
 * @param {Array.<*>} objectStack Object stack.
 * @return {Object|undefined} TileMatrixLimits Array.
 */
_ol_format_WMTSCapabilities_.readTileMatrixLimits_ = function (node, objectStack) {
    return _xml4.default.pushParseAndPop({}, _ol_format_WMTSCapabilities_.TMS_LIMITS_PARSERS_, node, objectStack);
};

/**
 * @const
 * @private
 * @type {Array.<string>}
 */
_ol_format_WMTSCapabilities_.NAMESPACE_URIS_ = [null, 'http://www.opengis.net/wmts/1.0'];

/**
 * @const
 * @private
 * @type {Array.<string>}
 */
_ol_format_WMTSCapabilities_.OWS_NAMESPACE_URIS_ = [null, 'http://www.opengis.net/ows/1.1'];

/**
 * @const
 * @type {Object.<string, Object.<string, ol.XmlParser>>}
 * @private
 */
_ol_format_WMTSCapabilities_.PARSERS_ = _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.NAMESPACE_URIS_, {
    'Contents': _xml4.default.makeObjectPropertySetter(_ol_format_WMTSCapabilities_.readContents_)
});

/**
 * @const
 * @type {Object.<string, Object.<string, ol.XmlParser>>}
 * @private
 */
_ol_format_WMTSCapabilities_.CONTENTS_PARSERS_ = _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.NAMESPACE_URIS_, {
    'Layer': _xml4.default.makeObjectPropertyPusher(_ol_format_WMTSCapabilities_.readLayer_),
    'TileMatrixSet': _xml4.default.makeObjectPropertyPusher(_ol_format_WMTSCapabilities_.readTileMatrixSet_)
});

/**
 * @const
 * @type {Object.<string, Object.<string, ol.XmlParser>>}
 * @private
 */
_ol_format_WMTSCapabilities_.LAYER_PARSERS_ = _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.NAMESPACE_URIS_, {
    'Style': _xml4.default.makeObjectPropertyPusher(_ol_format_WMTSCapabilities_.readStyle_),
    'Format': _xml4.default.makeObjectPropertyPusher(_xsd2.default.readString),
    'TileMatrixSetLink': _xml4.default.makeObjectPropertyPusher(_ol_format_WMTSCapabilities_.readTileMatrixSetLink_),
    'Dimension': _xml4.default.makeObjectPropertyPusher(_ol_format_WMTSCapabilities_.readDimensions_),
    'ResourceURL': _xml4.default.makeObjectPropertyPusher(_ol_format_WMTSCapabilities_.readResourceUrl_)
}, _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.OWS_NAMESPACE_URIS_, {
    'Title': _xml4.default.makeObjectPropertySetter(_xsd2.default.readString),
    'Abstract': _xml4.default.makeObjectPropertySetter(_xsd2.default.readString),
    'WGS84BoundingBox': _xml4.default.makeObjectPropertySetter(_ol_format_WMTSCapabilities_.readWgs84BoundingBox_),
    'Identifier': _xml4.default.makeObjectPropertySetter(_xsd2.default.readString)
}));

/**
 * @const
 * @type {Object.<string, Object.<string, ol.XmlParser>>}
 * @private
 */
_ol_format_WMTSCapabilities_.STYLE_PARSERS_ = _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.NAMESPACE_URIS_, {
    'LegendURL': _xml4.default.makeObjectPropertyPusher(_ol_format_WMTSCapabilities_.readLegendUrl_)
}, _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.OWS_NAMESPACE_URIS_, {
    'Title': _xml4.default.makeObjectPropertySetter(_xsd2.default.readString),
    'Identifier': _xml4.default.makeObjectPropertySetter(_xsd2.default.readString)
}));

/**
 * @const
 * @type {Object.<string, Object.<string, ol.XmlParser>>}
 * @private
 */
_ol_format_WMTSCapabilities_.TMS_LINKS_PARSERS_ = _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.NAMESPACE_URIS_, {
    'TileMatrixSet': _xml4.default.makeObjectPropertySetter(_xsd2.default.readString),
    'TileMatrixSetLimits': _xml4.default.makeObjectPropertySetter(_ol_format_WMTSCapabilities_.readTileMatrixLimitsList_)
});

/**
 * @const
 * @type {Object.<string, Object.<string, ol.XmlParser>>}
 * @private
 */
_ol_format_WMTSCapabilities_.TMS_LIMITS_LIST_PARSERS_ = _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.NAMESPACE_URIS_, {
    'TileMatrixLimits': _xml4.default.makeArrayPusher(_ol_format_WMTSCapabilities_.readTileMatrixLimits_)
});

/**
 * @const
 * @type {Object.<string, Object.<string, ol.XmlParser>>}
 * @private
 */
_ol_format_WMTSCapabilities_.TMS_LIMITS_PARSERS_ = _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.NAMESPACE_URIS_, {
    'TileMatrix': _xml4.default.makeObjectPropertySetter(_xsd2.default.readString),
    'MinTileRow': _xml4.default.makeObjectPropertySetter(_xsd2.default.readNonNegativeInteger),
    'MaxTileRow': _xml4.default.makeObjectPropertySetter(_xsd2.default.readNonNegativeInteger),
    'MinTileCol': _xml4.default.makeObjectPropertySetter(_xsd2.default.readNonNegativeInteger),
    'MaxTileCol': _xml4.default.makeObjectPropertySetter(_xsd2.default.readNonNegativeInteger)
});

/**
 * @const
 * @type {Object.<string, Object.<string, ol.XmlParser>>}
 * @private
 */
_ol_format_WMTSCapabilities_.DIMENSION_PARSERS_ = _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.NAMESPACE_URIS_, {
    'Default': _xml4.default.makeObjectPropertySetter(_xsd2.default.readString),
    'Value': _xml4.default.makeObjectPropertyPusher(_xsd2.default.readString)
}, _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.OWS_NAMESPACE_URIS_, {
    'Identifier': _xml4.default.makeObjectPropertySetter(_xsd2.default.readString)
}));

/**
 * @const
 * @type {Object.<string, Object.<string, ol.XmlParser>>}
 * @private
 */
_ol_format_WMTSCapabilities_.WGS84_BBOX_READERS_ = _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.OWS_NAMESPACE_URIS_, {
    'LowerCorner': _xml4.default.makeArrayPusher(_ol_format_WMTSCapabilities_.readCoordinates_),
    'UpperCorner': _xml4.default.makeArrayPusher(_ol_format_WMTSCapabilities_.readCoordinates_)
});

/**
 * @const
 * @type {Object.<string, Object.<string, ol.XmlParser>>}
 * @private
 */
_ol_format_WMTSCapabilities_.TMS_PARSERS_ = _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.NAMESPACE_URIS_, {
    'WellKnownScaleSet': _xml4.default.makeObjectPropertySetter(_xsd2.default.readString),
    'TileMatrix': _xml4.default.makeObjectPropertyPusher(_ol_format_WMTSCapabilities_.readTileMatrix_)
}, _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.OWS_NAMESPACE_URIS_, {
    'SupportedCRS': _xml4.default.makeObjectPropertySetter(_xsd2.default.readString),
    'Identifier': _xml4.default.makeObjectPropertySetter(_xsd2.default.readString)
}));

/**
 * @const
 * @type {Object.<string, Object.<string, ol.XmlParser>>}
 * @private
 */
_ol_format_WMTSCapabilities_.TM_PARSERS_ = _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.NAMESPACE_URIS_, {
    'TopLeftCorner': _xml4.default.makeObjectPropertySetter(_ol_format_WMTSCapabilities_.readCoordinates_),
    'ScaleDenominator': _xml4.default.makeObjectPropertySetter(_xsd2.default.readDecimal),
    'TileWidth': _xml4.default.makeObjectPropertySetter(_xsd2.default.readNonNegativeInteger),
    'TileHeight': _xml4.default.makeObjectPropertySetter(_xsd2.default.readNonNegativeInteger),
    'MatrixWidth': _xml4.default.makeObjectPropertySetter(_xsd2.default.readNonNegativeInteger),
    'MatrixHeight': _xml4.default.makeObjectPropertySetter(_xsd2.default.readNonNegativeInteger)
}, _xml4.default.makeStructureNS(_ol_format_WMTSCapabilities_.OWS_NAMESPACE_URIS_, {
    'Identifier': _xml4.default.makeObjectPropertySetter(_xsd2.default.readString)
}));
exports.default = _ol_format_WMTSCapabilities_;
module.exports = exports['default'];