"use strict";

/**
 * Load node based libraries
 */
try {
    let $ = require('jquery');
    window.$ = window.jQuery = $;
    window._ = require('lodash');
    window.moment = require('moment');
    window.swal = require('sweetalert2');
} catch (e) {
    console.log(e);
}

/**
 * We'll load the axios HTTP library which allows us to easily issue requests
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
window.axios.defaults.withCredentials = true;

/**
 * Next we will register the CSRF Token as a common header with Axios so that
 * all outgoing HTTP requests automatically have it attached. This is just
 * a simple convenience so we don't have to attach every token manually.
 */
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': token.content
        }
    });
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

/**
 * Next we will register the API Token as a common header with Axios so that
 * all incoming HTTP requests for a logged-in user automatically have it attached. This is just
 * a simple convenience so we don't have to attach every token manually.
 */
let api_token = document.head.querySelector('meta[name="api-token"]');
if (api_token) {
    window.axios.defaults.headers.common['Authorization'] = 'Bearer ' + api_token.content;
}

/* Redactor WYSIWYG */
require('./vendor/redactor');
require('./vendor/redactor-alignment');
require('./vendor/redactor-definedlinks');
require('./vendor/redactor-fontcolor');
require('./vendor/redactor-source');
require('./vendor/redactor-table');
require('./vendor/redactor-video');

/* Classes & Handlers */
require('./vendor/PasswordStrength');
require('./vendor/SEOHandler');
require('./vendor/WysiwygHandler');
require('./vendor/SweetAlertHandler');

/**
 * VUE.js Application Logic
 */
import Vue from 'vue';
import VTooltip from 'v-tooltip';

/* Tooltip config */
VTooltip.enabled = window.innerWidth > 768;
Vue.use(VTooltip);

/* Vue global event bus */
window.EventBus = new Vue();

/* Global Filters */
Vue.filter('date', function (val) {
    return window.moment(val).format('MMM Do YYYY');
});
Vue.filter('percent', function (val) {
    return val * 100 + '%';
});
Vue.filter('currency', function (val) {
    if (! val) {
        return 0.00;
    }
    val = parseFloat(val);
    return val.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');
});
Vue.filter('truncate', function (text, length, suffix) {
    if (! text) {
        return;
    }
    if (text.length < length) {
        return text;
    }
    return text.substring(0, length) + suffix;
});
Vue.filter('uppercase', function (text) {
    return text.toUpperCase();
});
Vue.filter('lowercase', function (text) {
    return text.toLowerCase();
});
Vue.filter('ucwords', function (text) {
    return text.replace(/^(.)|\s+(.)/g, function ($1) {
        return $1.toUpperCase();
    });
});
Vue.filter('plaintext', function (text) {
    return text.replace(/-/g, ' ').replace(/_/g, ' ');
});

/* Global Directives */
Vue.directive('uppercase', {
    bind: function (el, binding, vnode) {
        el.addEventListener("input", (e) => e.target.value = el.value.toUpperCase());
    }
});
Vue.directive('alpha', {
    bind: function (el, binding, vnode) {
        el.addEventListener("input", (e) => e.target.value = el.value.replace(/[^a-zA-Z]+/g, ''));
    }
});
Vue.directive('numeric', {
    bind: function (el, binding, vnode) {
        el.addEventListener("input", (e) => e.target.value = el.value.replace(/[^0-9.]+/g, ''));
    }
});
Vue.directive('alphanumeric', {
    bind: function (el, binding, vnode) {
        el.addEventListener("input", (e) => e.target.value = el.value.replace(/[^a-zA-Z0-9!*%]+/g, ''));
    }
});
Vue.directive('currency', {
    bind: function (el, binding, vnode) {
        el.addEventListener("input", (e) => e.target.value = el.value.replace(/[^0-9,.]+/g, ''));
    }
});
Vue.directive('date', {
    bind: function (el, binding, vnode) {
        el.addEventListener("input", function (e) {
            e.target.value = el.value
                .replace(/^(\d\d)(\d)$/g, '$1/$2')
                .replace(/^(\d\d\/\d\d)(\d+)$/g, '$1/$2')
                .replace(/[^\d\/]/g, '')
        });
    }
});
Vue.directive("maxnumber", {
    bind: function (el, binding, vnode) {
        let maxNumber = binding.expression;
        let handler = function (e) {
            if (parseInt(e.target.value) > parseInt(maxNumber)) {
                e.target.value = maxNumber;
            }
        };
        el.addEventListener("input", handler);
    }
});
Vue.directive("maxchars", {
    bind: function (el, binding, vnode) {
        let max_chars = binding.expression;
        let handler = function (e) {
            if (e.target.value.length > max_chars) {
                e.target.value = e.target.value.substr(0, max_chars);
            }
        };
        el.addEventListener("input", handler);
    }
});

/* Global Layout */
Vue.component('v-container', require('./layout/Container.vue').default);
Vue.component('v-header', require('./layout/Header.vue').default);
Vue.component('v-header-menu', require('./layout/HeaderMenu.vue').default);
Vue.component('v-main', require('./layout/Main.vue').default);
Vue.component('v-sidebar', require('./layout/Sidebar.vue').default);

/* Global UI elements */
Vue.component('v-alert', require('./components/Alert').default);
Vue.component('v-button', require('./components/Button').default);
Vue.component('v-card', require('./components/Card').default);
Vue.component('v-combobox', require('./components/ComboBox').default);
Vue.component('v-colorpicker', require('./components/ColorPicker').default);
Vue.component('v-datepicker', require('./components/DatePicker').default);
Vue.component('v-error', require('./components/Error').default);
Vue.component('v-label', require('./components/Label').default);
Vue.component('dropdown', require('./components/Dropdown').default);
Vue.component('tabs', require('./components/Tabs/Tabs.vue').default);
Vue.component('tab', require('./components/Tabs/Tab.vue').default);

/* Global Components */
Vue.component('data-table', require('./components/DataTable/DataTable').default);
Vue.component('data-table-filter', require('./components/DataTable/DataTableFilter').default);
Vue.component('editor', require('./components/Editor').default);
Vue.component('css-editor', require('./components/CssEditor').default);
Vue.component('css-editor-button', require('./components/CssEditorButton').default);
Vue.component('custom-css-editor', require('./components/CustomCssEditor').default);
Vue.component('custom-js-editor', require('./components/CustomJsEditor').default);
Vue.component('js-editor', require('./components/JsEditor').default);
Vue.component('js-editor-button', require('./components/JsEditorButton').default);
Vue.component('schema-editor', require('./components/SchemaEditor').default);
Vue.component('schema-editor-button', require('./components/SchemaEditorButton').default);
Vue.component('custom-schema-editor', require('./components/CustomSchemaEditor').default);
Vue.component('document-manager', require('./components/DocumentManager/DocumentManager').default);
Vue.component('gallery-builder', require('./components/GalleryBuilder/GalleryBuilder').default);
Vue.component('image-manager', require('./components/ImageManager/ImageManager').default);
Vue.component('file-uploader', require('./components/FileUploader').default);
Vue.component('form-builder', require('./components/FormBuilder/FormBuilder').default);
Vue.component('menu-builder', require('./components/MenuBuilder/MenuBuilder').default);
Vue.component('estimate-plan-builder', require('./components/EstimatePlanBuilder/EstimatePlanBuilder').default);
Vue.component('preview', require('./components/Preview').default);


/* Vue Instance */
const app = new Vue({
    el: '#app'
});
