﻿<template>
  <ui-property v-if="!isHidden" :field="config.path" :label="label" :hide-label="config.options.hideLabel" 
               :description="description" :required="isRequired" :disabled="isDisabled" 
               :vertical="config.options.vertical"
               :class="{'is-disabled': isDisabled, 'has-block': !!blockComponent }">
    <component :is="config.component" v-bind="config.componentOptions" :value="model" :entity="value" @input="onChange" :disabled="isDisabled" />
    <p v-if="config.options.helpText" class="ui-property-help" v-localize="config.options.helpText"></p>
    <template v-if="blockComponent && loaded" v-slot:after>
      <component :is="blockComponent" v-bind="{ config, editor, value, model }" />
    </template>
  </ui-property>
</template>


<script>
  import Strings from 'zero/helpers/strings.js';
  import Objects from 'zero/helpers/objects.js';
  import Editor from 'zero/core/editor.ts';
  import EditorField from 'zero/core/editor-field.ts';
  import Localization from 'zero/helpers/localization.js';

  export default {
    name: 'uiEditorComponent',

    inject: [ 'meta' ],

    props: {
      config: {
        type: Object,
        required: true
      },
      editor: {
        type: Object,
        required: true
      },
      value: {
        type: Object,
        required: true
      }
    },

    watch: {
      value: {
        deep: true,
        handler: function ()
        {
          this.rebuildModel();
        }
      }
    },

    data: () => ({
      model: null,
      loaded: false,
      blockComponent: null,
      manualDisabled: false,
      selector: null
    }),

    mounted()
    {
      this.rebuildModel();
      this.loaded = true;
    },

    computed: {
      isHidden()
      {
        return this.loaded && typeof this.config.options.condition === 'function' && !this.config.options.condition(this.value, this);
      },
      isRequired()
      {
        return typeof this.config.isRequired === 'function' ? this.config.isRequired(this.value) : this.config.isRequired;
      },
      isDisabled()
      {
        return this.manualDisabled || (typeof this.config.options.disabled === 'boolean' && this.config.options.disabled) || (typeof this.config.options.disabled === 'function' && this.config.options.disabled(this.value, this.model));
      },
      label()
      {
        return this.config.options.label || this.editor.templateLabel(this.config.path);
      },
      description()
      {
        return Localization.localize(this.config.options.description || this.editor.templateDescription(this.config.path), { hideEmpty: true });
      }
    },

    methods: {

      rebuildModel()
      {
        this.selector = Strings.selectorToArray(this.config.path);
        let currentValue = this.value;
        let found = false;

        if (!this.selector || !this.selector.length || !currentValue)
        {
          found = true;
          this.model = null;
        }
        else
        {
          for (var key of this.selector)
          {
            if (key in currentValue)
            {
              found = true;
              currentValue = currentValue[key];
            }
            else
            {
              break;
            }
          }

          this.model = found ? currentValue : null;
        }
      },


      onChange(value)
      {
        if (typeof value === 'function')
        {
          value(this.value);
        }
        else
        {
          Objects.setValue(this.value, this.selector, value);
        }
        this.$emit('input', this.value);
      },


      setDisabled(disabled)
      {
        this.manualDisabled = disabled;
      },


      setBlock(component)
      {
        this.blockComponent = component;
      }
    }
  }
</script>