<template>
  <div :ref="generateId" :style="{width,height}"></div>
</template>
<script>
// 引入全局实例
import ace from 'ace-builds'
// 主题风格，引入主题后还需要在 options 中指定主题才会生效
import 'ace-builds/src-min-noconflict/theme-monokai'
import 'ace-builds/src-min-noconflict/theme-chrome'
import 'ace-builds/src-min-noconflict/theme-dracula'
// 支持代码格式， 需要引入具体的语法高亮库才会有对应的语法高亮效果
import 'ace-builds/src-min-noconflict/mode-javascript'
import 'ace-builds/src-min-noconflict/mode-json'
import 'ace-builds/src-min-noconflict/mode-css'
import 'ace-builds/src-min-noconflict/ext-language_tools'
import jsWorkerUrl from 'file-loader!ace-builds/src-noconflict/worker-javascript'
import jsonWorkerUrl from 'file-loader!ace-builds/src-noconflict/worker-json'
import cssWorkerUrl from 'file-loader!ace-builds/src-noconflict/worker-css'

ace.config.setModuleUrl('ace/mode/javascript_worker', jsWorkerUrl)
ace.config.setModuleUrl('ace/mode/json_worker', jsonWorkerUrl)
ace.config.setModuleUrl('ace/mode/css_worker', cssWorkerUrl)
ace.config.setModuleUrl('ace/snippets/javascript', require('file-loader!ace-builds/src-noconflict/snippets/javascript.js'))
ace.config.setModuleUrl('ace/snippets/css', require('file-loader!ace-builds/src-noconflict/snippets/css.js'))

export default {
  name: 'y-edit-ace',
  model: {
    event: 'change'
  },
  props: {
    // 编辑器内容
    value: String,
    // 默认语言
    language: {
      type: String,
      default: 'javascript'
    },
    // 主题，对应主题库 JS 需要提前引入
    theme: {
      type: String,
      default: 'chrome'
    },
    // 是否只读
    readonly: {
      type: Boolean,
      default: false
    },
    // 最大行数
    maxLines: Number,
    // 是否显示全屏按钮
    withFullscreenBtn: {
      type: Boolean,
      default: false
    },
    withFooterBtns: {
      type: Boolean,
      default: false
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '200px'
    }
  },
  data () {
    return {
      editor: null,
      generateId:
          'id_' +
          Math.random()
              .toString(36)
              .substr(2, 4),
      isVisible: false,
      dialogValue: ''
    }
  },
  mounted () {
    // 引入所有样式、语言
    const requireContext = require.context('ace-builds/src-min-noconflict', true, /(theme|mode)\-[\w]+\.js$/)
    const requireAll = context => context.keys().map(context)
    requireAll(requireContext)
    // 初始化
    this.initEditor()
  },
  watch: {
    value (val) {
      if (this.editor.getValue() !== val) {
        this.editor.setValue(val)
        this.editor.clearSelection()
      }
    },
    theme: {
      handler (newTheme) {
        this.editor.setTheme('ace/theme/' + newTheme)
      },
    }
  },
  methods: {
    // 初始化
    initEditor () {
      // 创建实例
      this.editor = ace.edit(this.$refs[this.generateId], {
        mode: `ace/mode/${this.language}`,
        theme: `ace/theme/${this.theme}`,
        fontSize: 12,
        tabSize: 2,
        value: this.value,
        selectionStyle: 'text',
        maxLines: this.maxLines,
        readOnly: this.readonly
      })
      // 设置属性等，具体需要可根据官方参数自行设置
      this.editor.setOptions({
        enableBasicAutocompletion: true,
        enableSnippets: true,
        enableLiveAutocompletion: true,
        wrap: false,
        setShowPrintMargin: false
      })
      // 设置值改变监听
      this.editor.on('change', () => {
        this.$emit('change', this.editor.getValue())
      })
    },
    // 实例方法，高亮某一行
    gotoLine (lineNumber) {
      this.editor.gotoLine(lineNumber)
    },
    // 全屏编辑
    fullscreen () {
      this.isVisible = true
    },
    closeEditCode () {
      this.editor.setValue(this.dialogValue)
      this.editor.clearSelection()
    },
    // resize编辑器
    resize () {
      this.editor.resize(true)
    },
    destroy () {
      if (this.editor) {
        this.editor.destroy()
        this.editor = null
      }
    }
  },
  beforeDestroy () {
    this.destroy()
  }
}
</script>
<style scoped>
.wrap {
  position: relative;
}

.wrap .code-editor {
  min-height: 200px;
  height: 100%;
  border: 1px solid #282f3a;
  background-color: #0e1013;
}

.wrap .icon-fullscreen {
  position: absolute;
 /*color: #fff;*/
  right: 10px;
  font-size: 16px;
  z-index: 9999;
  cursor: pointer;
}

/deep/ .code-dialog ::before {
  content: '';
  position: absolute;
  display: block;
  top: 0;
  left: 0;
  right: 0;
  width: 100%;
  height: 2px;
  background-image: linear-gradient(270deg, #00deff, #2483ff 74%);
}

/deep/ .code-dialog {

  display: flex;
  flex-direction: column;
  background-color: #303640;
}

/deep/ .code-dialog .el-dialog__body {
  flex: 1 1 0;
  padding-top: 10px;
}

/deep/ .code-dialog .el-dialog__header {
  border: none;
}

/deep/ .code-dialog .el-dialog__header .el-dialog__title {
  color: #ccc;
}
</style>

