<template>
<div id="main-container">
    <div id="editor-left-container" :style="{width: leftContainerSize + '%'}" v-if="!shared.isMobile">
        <el-tabs v-model="currentTab" type="border-card">
            <el-tab-pane :label="$t('editor.tabEditor')" name="code-editor">
                <el-container>
                    <el-header id="editor-control-panel">
                        <div id="code-info">
                            <template v-if="shared.editorStatus.message">
                                <span class="code-info-time">{{currentTime}}</span>
                                <span :class="'code-info-type-' + shared.editorStatus.type">{{shared.editorStatus.message}}</span>
                            </template>
                        </div>
                        <div class="editor-controls">
                            <!-- <el-switch v-model="shared.typeCheck"
                                :active-text="$t('editor.monacoMode')"
                                :inactive-text="''"
                            ></el-switch> -->
                            <a href="javascript:;" class='btn btn-default btn-sm' @click='disposeAndRun'>{{$t('editor.run')}}</a>
                        </div>
                    </el-header>
                    <el-main>
                        <CodeMonaco v-if="shared.typeCheck" id="code-panel" :initialCode="initialCode"></CodeMonaco>
                        <CodeAce v-else id="code-panel" :initialCode="initialCode"></CodeAce>
                    </el-main>
                </el-container>
            </el-tab-pane>

            <el-tab-pane :label="$t('editor.tabFullCodePreview')" name="full-code" :lazy="true">
                <el-container style="width: 100%; height: 100%">
                    <el-header id="full-code-generate-config">
                        <span class="full-code-generate-config-label">
                            <!-- <i class="el-icon-setting"></i> 配置 -->
                        </span>
                        <el-switch
                            class="enable-decal"
                            v-model="fullCodeConfig.minimal"
                            :active-text="$t('editor.minimalBundle')"
                            :inactive-text="''">
                        </el-switch>
                        <el-switch
                            class="enable-decal"
                            v-model="fullCodeConfig.esm"
                            active-text="ES Modules"
                            :inactive-text="''">
                        </el-switch>
                    </el-header>
                    <el-main>
                        <FullCodePreview :code="fullCode"></FullCodePreview>
                    </el-main>
                </el-container>
            </el-tab-pane>
            <el-tab-pane :label="$t('editor.tabOptionPreview')" name="full-option">
                <div id="option-outline"></div>
            </el-tab-pane>
        </el-tabs>
    </div>
    <div class="handler" id="h-handler" @mousedown="onSplitterDragStart" :style="{left: leftContainerSize + '%'}" v-if="!shared.isMobile"></div>
    <Preview :inEditor="true" class="right-container" ref="preview" :style="{
        width: (100 - leftContainerSize) + '%',
        left: leftContainerSize + '%'
    }"></Preview>
</div>
</template>

<script>

import CodeAce from './CodeAce.vue';
import CodeMonaco from './CodeMonaco.vue';
import FullCodePreview from './FullCodePreview.vue';
import Preview from './Preview.vue';
import {store, loadExampleCode, parseSourceCode} from '../common/store';
import {collectDeps, buildExampleCode} from '../../common/buildCode';
import { mount } from "@lang/object-visualizer";

import './object-visualizer.css';

export default {
    components: {
        CodeAce,
        CodeMonaco,
        FullCodePreview,
        Preview
    },

    data() {
        return {
            mousedown: false,
            leftContainerSize: 40,
            mobileMode: false,
            shared: store,
            initialCode: '',

            currentTab: 'code-editor',

            fullCode: '',

            fullCodeConfig: {
                mimimal: false,
                esm: true,
                node: false // If is in node
            }
        };
    },

    computed: {
        currentTime() {
            // Update time when message updated.
            const message = this.shared.message;

            const time = new Date();
            const digits = [time.getHours(), time.getMinutes(), time.getSeconds()];
            let timeStr = '';
            for (let i = 0, len = digits.length; i < len; ++i) {
                timeStr += (digits[i] < 10 ? '0' : '') + digits[i];
                if (i < len - 1) {
                    timeStr += ':';
                }
            }
            return timeStr;
        }
    },

    mounted() {

        if (store.isMobile) {
            this.leftContainerSize = 0;
            loadExampleCode().then(code => {
                // No editor available. Set to runCode directly.
                store.runCode = parseSourceCode(code);
            });
        }
        else {
            loadExampleCode().then(code => {
                // Only set the code in editor. editor will sync to the store.
                this.initialCode = parseSourceCode(code);
            });

            window.addEventListener('mousemove', (e) => {
                if (this.mousedown) {
                    let percentage = e.clientX / window.innerWidth;
                    percentage = Math.min(0.9, Math.max(0.1, percentage));
                    this.leftContainerSize = percentage * 100;
                }
            });

            window.addEventListener('mouseup', (e) => {
                this.mousedown = false;
            });
        }
    },

    methods: {
        onSplitterDragStart() {
            this.mousedown = true;
        },
        disposeAndRun() {
            this.$refs.preview.refreshAll();
        },
        updateFullCode() {
            const option = this.$refs.preview.getOption();
            if (!option) {
                return;
            }
            const deps = collectDeps(option);
            deps.push(store.renderer === 'svg' ? 'SVGRenderer' : 'CanvasRenderer');
            this.fullCode = buildExampleCode(store.sourceCode, deps, {
                minimal: this.fullCodeConfig.minimal,
                ts: false,
                esm: this.fullCodeConfig.esm,
                // legacy: true,
                theme: store.darkMode ? 'dark' : '',
                ROOT_PATH: store.cdnRoot
            });
        },
        updateOptionOutline() {
            const option = Object.freeze(this.$refs.preview.getOption());
            if (!option) {
                return;
            }
            mount(
                option,
                this.$el.querySelector('#option-outline'),
                {
                    getKeys(object, path) {
                        return Object.keys(object).filter(key => {
                            if (Array.isArray(object[key]) && !object[key].length) {
                                return false;
                            }
                            return true;
                        });
                    },
                    expandOnCreatedAndUpdated(path) {
                        return path.length === 0
                            || (path[0] === 'series' && path.length <= 1);
                    },
                }
            );
        },
        updateTabContent(tab) {
            if (tab === 'full-code') {
                this.updateFullCode();
            }
            else if (tab === 'full-option') {
                this.updateOptionOutline();
            }
        }
    },

    watch: {
        'shared.typeCheck'(enableTypeCheck) {
            // Update initialCode to avoid code changed when switching editor
            this.initialCode = store.sourceCode;
            this.updateFullCode();
        },
        'currentTab'(tab) {
            this.updateTabContent(tab);
        },
        'shared.runHash'() {
            this.updateTabContent(this.currentTab);
        },
        fullCodeConfig: {
            deep: true,
            handler() {
                this.updateFullCode();
            }
        }
    }
}
</script>

<style lang="scss">

@import '../style/color.scss';

$code-info-height: 25px;
$control-panel-height: 30px;
$pd-basic: 10px;
$handler-width: 5px;

#main-container {
    .handler {
        position: absolute;
        left: 50%;

        top: 0;
        bottom: 0;
        width: $handler-width;

        cursor: col-resize;
        z-index: 100;
        background-color: transparent;
        border-left: 1px solid #ececec;
        // border-right: 1px solid $clr-border;
    }

}

#editor-left-container {
    position: absolute;
    left: 0;
    bottom: 0;
    top: 0;

    width: 50%;

    .el-tab-pane {
        height: 100%;

        .el-container {
            width: 100%;
            height: 100%;
        }

        .el-header {
            height: $control-panel-height!important;
            position: relative;
            z-index: 10;
            padding: 0;
        }
        .el-main {
            padding: 0;
            position: relative;

            ::-webkit-scrollbar {
                height:8px;
                width:8px;
                transition:all 0.3s ease-in-out;
                border-radius:2px;
            }

            ::-webkit-scrollbar-button {
                display:none;
            }

            ::-webkit-scrollbar-thumb {
                width:8px;
                min-height:15px;
                background:rgba(50, 50, 50, 0.6) !important;
                transition:all 0.3s ease-in-out;border-radius:2px;
            }

            ::-webkit-scrollbar-thumb:hover {
                background:rgba(0, 0, 0, 0.5) !important;
            }
        }
    }

    .el-tabs {
        box-shadow: none;
    }

    .el-tabs--border-card>.el-tabs__header {
        border-bottom: none;
    }

    .el-tabs__content {
        position: absolute;
        top: 34px;
        left: 0;
        right: 0;
        bottom: 0;
        padding: 0;
    }

    .el-tabs__item {
        height: 34px;
        line-height: 34px;
    }
}

#editor-control-panel, #full-code-generate-config {
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

#option-outline {
    // height: 100%;
    // Fix safari
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    right: 0;

    font-size: 13px;

    font-family: 'Source Code Pro', 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
}

#full-code-generate-config {
    .full-code-generate-config-label {
        height: $control-panel-height;
        line-height: $control-panel-height;
        vertical-align: middle;
        margin: 0 0 0 20px;
    }

    .el-switch {
        margin-right: 10px;
    }

    .el-switch__label {
        margin-left: 8px;
        margin-top: -2px;
    }
    .el-switch__label * {
        font-size: 12px;
    }
}

#editor-control-panel {
    .setting-panel {
        display: inline-block;

        .btn-group + .btn-group {
            margin-left: $pd-basic;
        }
    }

    .editor-controls  {
        float: right;

        .el-switch__label {
            margin-top: -3px;
        }
        .el-switch__label * {
            font-size: 12px;
        }

        .btn {
            color: #FFF;
            border-radius: 0;
            background-color: #409eff;
            margin-left: $pd-basic;
            border: none;
            height: 30px;
            width: 50px;
        }
        .btn:hover {
            background-color: lighten($color: #409eff, $amount: 5);
        }
    }
}

#code-info {
    position: absolute;
    bottom: 0;
    overflow: hidden;

    height: $control-panel-height;
    line-height: $control-panel-height;
    padding: 0px 10px;

    // border-top: 1px solid $clr-border;
    font-size: 0.9rem;

    .code-info-time {
        color: $clr-text;
        display: inline-block;
        margin-right: 10px;
        font-size: 12px;
    }

    .code-info-type-info {
        color: $clr-text;
        font-size: 12px;
    }

    .code-info-type-warn {
        color: $clr-warn;
    }

    .code-info-type-error {
        color: $clr-error;
    }
}

.right-container {
    position: absolute;
    right: 0;

    width: 50%;
    height: 100%;
    padding: 0;
    padding-left: $handler-width;
    border: none;
    z-index: 30;

    background: $clr-bg;
}


</style>