'use strict';

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

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _service = require('../service');

var _utils = require('./utils');

var ThemeUtils = _interopRequireWildcard(_utils);

var _vue = require('vue');

var _vue2 = _interopRequireDefault(_vue);

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

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* eslint-disable no-multi-spaces */
// Extensions

// Utilities

// Types


var Theme = exports.Theme = function (_Service) {
    _inherits(Theme, _Service);

    function Theme() {
        var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

        _classCallCheck(this, Theme);

        var _this = _possibleConstructorReturn(this, (Theme.__proto__ || Object.getPrototypeOf(Theme)).call(this));

        _this.disabled = false;
        _this.themes = {
            light: {
                primary: '#1976D2',
                secondary: '#424242',
                accent: '#82B1FF',
                error: '#FF5252',
                info: '#2196F3',
                success: '#4CAF50',
                warning: '#FB8C00' // amber.base
            },
            dark: {
                primary: '#2196F3',
                secondary: '#424242',
                accent: '#FF4081',
                error: '#FF5252',
                info: '#2196F3',
                success: '#4CAF50',
                warning: '#FB8C00' // amber.base
            }
        };
        _this.defaults = _this.themes;
        _this.isDark = null;
        _this.vueInstance = null;
        if (options.disable) {
            _this.disabled = true;
            return _possibleConstructorReturn(_this);
        }
        _this.options = _extends({}, _this.options, options.options);
        _this.dark = Boolean(options.dark);
        var themes = options.themes || {};
        _this.themes = {
            dark: _this.fillVariant(themes.dark, true),
            light: _this.fillVariant(themes.light, false)
        };
        return _this;
    }
    // When setting css, check for element
    // and apply new values


    _createClass(Theme, [{
        key: 'applyTheme',

        // Apply current theme default
        // only called on client side
        value: function applyTheme() {
            if (this.disabled) return this.clearCss();
            this.css = this.generatedStyles;
        }
    }, {
        key: 'clearCss',
        value: function clearCss() {
            this.css = '';
        }
        // Initialize theme for SSR and SPA
        // Attach to ssrContext head or
        // apply new theme to document

    }, {
        key: 'init',
        value: function init(root, ssrContext) {
            if (this.disabled) return;
            var meta = Boolean(root.$meta); // TODO: don't import public types from /src
            var ssr = Boolean(ssrContext);
            /* istanbul ignore else */
            if (meta) {
                this.initNuxt(root);
            } else if (ssr) {
                this.initSSR(ssrContext);
            }
            this.initTheme();
        }
        // Allows for you to set target theme

    }, {
        key: 'setTheme',
        value: function setTheme(theme, value) {
            this.themes[theme] = Object.assign(this.themes[theme], value);
            this.applyTheme();
        }
        // Reset theme defaults

    }, {
        key: 'resetThemes',
        value: function resetThemes() {
            this.themes.light = Object.assign({}, this.defaults.light);
            this.themes.dark = Object.assign({}, this.defaults.dark);
            this.applyTheme();
        }
        // Check for existence of style element

    }, {
        key: 'checkStyleElement',
        value: function checkStyleElement() {
            /* istanbul ignore next */
            if (this.styleEl) return true;
            this.genStyleElement(); // If doesn't have it, create it
            this.styleEl = document.getElementById('vuetify-theme-stylesheet');
            return Boolean(this.styleEl);
        }
    }, {
        key: 'fillVariant',
        value: function fillVariant() {
            var theme = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
            var dark = arguments[1];

            var defaultTheme = this.themes[dark ? 'dark' : 'light'];
            return Object.assign({}, defaultTheme, theme);
        }
        // Generate the style element
        // if applicable

    }, {
        key: 'genStyleElement',
        value: function genStyleElement() {
            if (typeof document === 'undefined') return;
            /* istanbul ignore next */
            var options = this.options || {};
            this.styleEl = document.createElement('style');
            this.styleEl.type = 'text/css';
            this.styleEl.id = 'vuetify-theme-stylesheet';
            if (options.cspNonce) {
                this.styleEl.setAttribute('nonce', options.cspNonce);
            }
            document.head.appendChild(this.styleEl);
        }
    }, {
        key: 'initNuxt',
        value: function initNuxt(root) {
            var options = this.options || {};
            var metaInfo = {
                style: [{
                    cssText: this.generatedStyles,
                    type: 'text/css',
                    id: 'vuetify-theme-stylesheet',
                    nonce: options.cspNonce
                }]
            };
            root.$children.push({
                $children: [],
                $options: {
                    metaInfo: metaInfo,
                    head: metaInfo
                },
                $vnode: { data: {} }
            });
        }
    }, {
        key: 'initSSR',
        value: function initSSR(ssrContext) {
            var options = this.options || {};
            // SSR
            var nonce = options.cspNonce ? ' nonce="' + options.cspNonce + '"' : '';
            ssrContext.head = ssrContext.head || '';
            ssrContext.head += '<style type="text/css" id="vuetify-theme-stylesheet"' + nonce + '>' + this.generatedStyles + '</style>';
        }
    }, {
        key: 'initTheme',
        value: function initTheme() {
            var _this2 = this;

            // Only watch for reactivity on client side
            if (typeof document === 'undefined') return;
            // If we get here somehow, ensure
            // existing instance is removed
            if (this.vueInstance) this.vueInstance.$destroy();
            // Use Vue instance to track reactivity
            // TODO: Update to use RFC if merged
            // https://github.com/vuejs/rfcs/blob/advanced-reactivity-api/active-rfcs/0000-advanced-reactivity-api.md
            this.vueInstance = new _vue2.default({
                data: { themes: this.themes },
                watch: {
                    themes: {
                        immediate: true,
                        deep: true,
                        handler: function handler() {
                            return _this2.applyTheme();
                        }
                    }
                }
            });
        }
    }, {
        key: 'css',
        set: function set(val) {
            this.checkStyleElement() && (this.styleEl.innerHTML = val);
        }
    }, {
        key: 'dark',
        set: function set(val) {
            var oldDark = this.isDark;
            this.isDark = val;
            // Only apply theme after dark
            // has already been set before
            oldDark != null && this.applyTheme();
        },
        get: function get() {
            return Boolean(this.isDark);
        }
    }, {
        key: 'currentTheme',
        get: function get() {
            var target = this.dark ? 'dark' : 'light';
            return this.themes[target];
        }
    }, {
        key: 'generatedStyles',
        get: function get() {
            var theme = this.parsedTheme;
            /* istanbul ignore next */
            var options = this.options || {};
            var css = void 0;
            if (options.themeCache != null) {
                css = options.themeCache.get(theme);
                /* istanbul ignore if */
                if (css != null) return css;
            }
            css = ThemeUtils.genStyles(theme, options.customProperties);
            if (options.minifyTheme != null) {
                css = options.minifyTheme(css);
            }
            if (options.themeCache != null) {
                options.themeCache.set(theme, css);
            }
            return css;
        }
    }, {
        key: 'parsedTheme',
        get: function get() {
            /* istanbul ignore next */
            var theme = this.currentTheme || {};
            return ThemeUtils.parse(theme);
        }
    }]);

    return Theme;
}(_service.Service);

Theme.property = 'theme';
//# sourceMappingURL=index.js.map