<!-- Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->

<template>
  <div class="log">
    <div class="log-header">
      <template v-for="(item, index) in columns">
        <div class="method" :style="`width: ${item.method}px`" v-if="item.drag" :key="index">
          <span class="r cp" ref="dragger" :data-index="index">
            <rk-icon icon="settings_ethernet" />
          </span>
          {{ $t(item.value) }}
        </div>
        <div v-else :class="item.label" :key="index">
          {{ $t(item.value) }}
        </div>
      </template>
    </div>
    <div v-if="type === 'browser'">
      <BrowserItem v-for="(item, index) in tableData" :data="item" :key="'browser' + index" />
    </div>
    <div v-else>
      <ServiceItem v-for="(item, index) in tableData" :data="item" :key="'service' + index" :noLink="noLink" />
    </div>
    <slot></slot>
  </div>
</template>
<script lang="js">
  import { ServiceLogConstants, BrowserLogConstants } from './log-constant';
  import BrowserItem from './log-browser-item';
  import ServiceItem from './log-service-item';

  export default {
    components: { ServiceItem, BrowserItem },
    name: 'LogContainer',
    props: ['type', 'tableData', 'noLink'],
    data() {
      return {
        method: 380,
        columns: this.type === 'browser' ? BrowserLogConstants : ServiceLogConstants,
      };
    },
    created() {
      switch (this.type) {
        case 'browser':
          this.data = BrowserLogConstants;
          break;
        case 'service':
          this.data = ServiceLogConstants;
          break;
        default:
          break;
      }
    },
    mounted() {
      const drags = this.$refs.dragger || [];
      drags.forEach((drag) => {
        drag.onmousedown = (event) => {
          const diffX = event.clientX;
          const index = +drag.dataset.index;

          const item = this.data[index];
          const copy = item.method;
          document.onmousemove = (documentEvent) => {
            const moveX = documentEvent.clientX - diffX;
            const method = copy + moveX;
            this.$set(this.data, index, { ...item, method });
          };
          document.onmouseup = () => {
            document.onmousemove = null;
            document.onmouseup = null;
          };
        };
      });

    },
  };
</script>
<style lang="scss" scoped>
  /*@import './trace.scss';*/
  .log {
    font-size: 12px;
    height: 100%;
    overflow: auto;
  }

  .log-header {
    /*display: flex;*/
    white-space: nowrap;
    user-select: none;
    border-left: 0;
    border-right: 0;
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
    /*background-color: #f3f4f9;*/
    .traceId {
      width: 390px;
    }
    .content,
    .tags {
      width: 300px;
    }
    .serviceInstanceName,
    .serviceName {
      width: 200px;
    }
  }

  .log-header div {
    /*min-width: 140px;*/
    width: 140px;
    /*flex-grow: 1;*/
    display: inline-block;
    padding: 0 4px;
    border: 1px solid transparent;
    border-right: 1px dotted silver;
    line-height: 30px;
    background-color: #f3f4f9;
    padding: 0 4px;
    border: 1px solid transparent;
    border-right: 1px dotted silver;
    overflow: hidden;
    line-height: 30px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
</style>
