/**
 * DevExtreme (framework/browser_adapters.js)
 * Version: 18.2.16
 * Build date: Fri Dec 03 2021
 *
 * Copyright (c) 2012 - 2021 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
"use strict";
require("../integration/jquery");
var $ = require("jquery"),
    Class = require("../core/class"),
    Callbacks = require("../core/utils/callbacks"),
    window = require("../core/utils/window").getWindow(),
    queue = require("../core/utils/queue");
var ROOT_PAGE_URL = "__root__",
    BUGGY_ANDROID_BUFFER_PAGE_URL = "__buffer__";
var DefaultBrowserAdapter = Class.inherit({
    ctor: function(options) {
        options = options || {};
        this._window = options.window || window;
        this.popState = Callbacks();
        $(this._window).on("hashchange", this._onHashChange.bind(this));
        this._tasks = queue.create();
        this.canWorkInPureBrowser = true
    },
    replaceState: function(uri) {
        var that = this;
        return this._addTask(function() {
            uri = that._normalizeUri(uri);
            that._window.history.replaceState(null, null, "#" + uri);
            that._currentTask.resolve()
        })
    },
    pushState: function(uri) {
        var that = this;
        return this._addTask(function() {
            uri = that._normalizeUri(uri);
            that._window.history.pushState(null, null, "#" + uri);
            that._currentTask.resolve()
        })
    },
    createRootPage: function() {
        return this.replaceState(ROOT_PAGE_URL)
    },
    _onHashChange: function() {
        if (this._currentTask) {
            this._currentTask.resolve()
        }
        this.popState.fire()
    },
    back: function() {
        var that = this;
        return this._addTask(function() {
            that._window.history.back()
        })
    },
    getHash: function() {
        return this._normalizeUri(this._window.location.hash)
    },
    isRootPage: function() {
        return this.getHash() === ROOT_PAGE_URL
    },
    _normalizeUri: function(uri) {
        return (uri || "").replace(/^#+/, "")
    },
    _addTask: function(task) {
        var that = this,
            d = $.Deferred();
        this._tasks.add(function() {
            that._currentTask = d;
            task();
            return d
        });
        return d.promise()
    }
});
var OldBrowserAdapter = DefaultBrowserAdapter.inherit({
    ctor: function() {
        this._innerEventCount = 0;
        this.callBase.apply(this, arguments);
        this._skipNextEvent = false
    },
    replaceState: function(uri) {
        var that = this;
        uri = that._normalizeUri(uri);
        if (that.getHash() !== uri) {
            that._addTask(function() {
                that._skipNextEvent = true;
                that._window.history.back()
            });
            return that._addTask(function() {
                that._skipNextEvent = true;
                that._window.location.hash = uri
            })
        }
        return $.Deferred().resolve().promise()
    },
    pushState: function(uri) {
        var that = this;
        uri = this._normalizeUri(uri);
        if (this.getHash() !== uri) {
            return that._addTask(function() {
                that._skipNextEvent = true;
                that._window.location.hash = uri
            })
        }
        return $.Deferred().resolve().promise()
    },
    createRootPage: function() {
        return this.pushState(ROOT_PAGE_URL)
    },
    _onHashChange: function() {
        var currentTask = this._currentTask;
        this._currentTask = null;
        if (this._skipNextEvent) {
            this._skipNextEvent = false
        } else {
            this.popState.fire()
        }
        if (currentTask) {
            currentTask.resolve()
        }
    }
});
var BuggyAndroidBrowserAdapter = OldBrowserAdapter.inherit({
    createRootPage: function() {
        this.pushState(BUGGY_ANDROID_BUFFER_PAGE_URL);
        return this.callBase()
    }
});
var HistorylessBrowserAdapter = DefaultBrowserAdapter.inherit({
    ctor: function(options) {
        options = options || {};
        this._window = options.window || window;
        this.popState = Callbacks();
        $(this._window).on("dxback", this._onHashChange.bind(this));
        this._currentHash = this._window.location.hash
    },
    replaceState: function(uri) {
        this._currentHash = this._normalizeUri(uri);
        return $.Deferred().resolve().promise()
    },
    pushState: function(uri) {
        return this.replaceState(uri)
    },
    createRootPage: function() {
        return this.replaceState(ROOT_PAGE_URL)
    },
    getHash: function() {
        return this._normalizeUri(this._currentHash)
    },
    back: function() {
        return this.replaceState(ROOT_PAGE_URL)
    },
    _onHashChange: function() {
        var promise = this.back();
        this.popState.fire();
        return promise
    }
});
var BuggyCordovaWP81BrowserAdapter = DefaultBrowserAdapter.inherit({
    ctor: function(options) {
        this.callBase(options);
        this.canWorkInPureBrowser = false
    }
});
exports.DefaultBrowserAdapter = DefaultBrowserAdapter;
exports.OldBrowserAdapter = OldBrowserAdapter;
exports.BuggyAndroidBrowserAdapter = BuggyAndroidBrowserAdapter;
exports.HistorylessBrowserAdapter = HistorylessBrowserAdapter;
exports.BuggyCordovaWP81BrowserAdapter = BuggyCordovaWP81BrowserAdapter;
