<template>
  <div class="flow-main" :class="{dark:dark}">
    <div class="app-header">
      Flow
      <button @click="dark=!dark">{{ dark?'light':'dark' }}</button>
    </div>
    <div class="app-horizontal">
      <div class="app-flow-container">
        <div class="app-watermark">PROTOTYPE</div>
        <div class="app-info">
          <h4>HELP</h4>
          <ul>
            <li><b>Pan</b>: Drag with Middle Mouse button</li>
            <li><b>Zoom</b>: Mouse wheel up and down to zoom in and out</li>
            <li><b>New Node</b>: Create a node by dragging a fn from left panel into area</li>
            <li><b>Remove Node</b>: Middle click in a node to remove a node</li>
            <li><b>Move Node</b>: Mouse click and drag</li>
            <li><b>Links</b>: Press [shift] and Drag from a node/socket to a socket highlighted in green</li>
            <li><b>Links(alternative)</b>: Toggle socket visualisation in the panel and Drag from a socket to a socket highlighted in green</li>
            <li><b>Remove Link</b>: Simple click on the link when it turns red</li>
          </ul>

          <h4>TODO:</h4>
          <ul>
            <li>UX/UI: Undo changes</li>
            <li>UX/UI: Special nodes with display capabilities (images,datatables,...)</li>
            <li>UX/UI: Group nodes into a single box, exposing inputs and outputs</li>
            <li>UX/UI: Implement touch</li>
            <li>UX/UI: drop link in node to link to next compatible available input</li>
            <li>Registry: Synchronize registry with server(GET)</li>
            <li>Collaboration: Better concurrent editing/message passing (testing)</li>
            <li>Collaboration: Improve document synchronization</li>
            <li>FlowServer: Build the graph on the server and run</li>
            <li>FlowPkg: Create training mechanism</li>
            <li>FlowPkg: matrix pooling function example</li>
          </ul>
          <br>
          <small>&copy; Luis Figueiredo (luisf@hexasoftware.com)</small>
        </div>

        <!--:value="nodeData"
        @input="documentUpdate"-->
        <hx-split
          dir="horizontal"
          :resizeable="funcsActive && funcsResizeable"
          :split="funcsActive?funcsSize:'0px'"
          @onSplitResize="funcsSizeUpdate"

        >
          <flow-panel
            :registry="registry"
            @toggleResizeable="funcsResizeable=!funcsResizeable"
            @toggleStickySockets="managerStickySockets=!managerStickySockets"
          />

          <flow-manager
            ref="flowManager"
            :registry="registry"
            @funcsPanelToggle="funcsActive=!funcsActive"
            @nodeInspect="nodeInspect(...arguments)"

            width="100%"
            height="100%"/>
        </hx-split>
      </div>
      <div class="app-chat">
        <app-chat/>
      </div>
      <!-- Node inspector -->
      <!-- Move this to a different place -->
      <!-- And rename it to inspector -->
      <hx-modal class="flow-modal" v-if="nodeInspectTarget" @close="nodeInspectTarget=null">
        <div slot="header">Node inspector:</div>
        <div slot="body" class="flow-modal__body">
          <div class="flow-modal__info">
            <svg class="flow-view preview activity flow-detail flow-linking" width="300" height="200" viewBox="0 0 300 200">
              <flow-panzoom>
                <flow-node
                  style="pointer-events:none"
                  ref="modalPreviewNode"
                  transform="translate(150,100)"
                  :id="nodeInspectTarget.id"
                  :match="{}"
                  :label="nodeInspectTarget.label"
                  :inputs= "registry[nodeInspectTarget.src].inputs"
                  :output= "registry[nodeInspectTarget.src].output"
                  :nodeStyle= "registry[nodeInspectTarget.src].style"
              /></flow-panzoom>
            </svg>
            <div class="flow-modal__sockets-properties">
              <label>Description</label>
              <div class="property">Bogus description</div>
              <label>Help</label>
              <div class="property">Connect to input a thing and goes to output another thing</div>
              <div class="flow-modal__params" v-if="nodeInspectTarget.prop" @keydown.enter="nodeInspectTarget=null">
                <div class="flow-modal__param" v-for="(v,k) in nodeInspectTarget.prop">
                  <label>{{ k }}</label>
                  <input type="text" v-model="nodeInspectTarget.prop[k]">
                </div>
              </div>
            </div>
          </div>
          <label>label</label>
          <input
            ref="modalInput"
            type="text"
            v-model="nodeInspectTarget.label"
            @keydown.esc="nodeInspectTarget=null"
            @keydown.enter="nodeInspectTarget=null"
          >
        </div>
        <div slot="footer">
          <button class="primary-invert" @click="nodeProcess(nodeInspectTarget)">Run</button>
          <button @click="nodeInspectTarget=false">OK</button>
        </div>
      </hx-modal>

    </div>
  </div>
</template>
<script>
import AppChat from '@/components/chat'
import FlowManager from '@/components/flow/manager'
import FlowNode from '@/components/flow/node'
import FlowPanzoom from '@/components/flow/panzoom'
import FlowPanel from './panel'
import HxSplit from '@/components/shared/hx-split'
import HxModal from '@/components/shared/hx-modal'
import 'reset-css/reset.css'

import '@/assets/dark-theme.css'
import '@/assets/style.css'
// import nodeData from './nodedata'

const defRegistry = {
  'Input': {
    categories: ['core'],
    output: 'any',
    style: { color: '#686', textColor: '#fff', shape: 'circle' },
    props: {} // should be sent in the node
  },
  'Variable': {
    categories: ['core'],
    output: 'any',
    style: { color: '#88a', textColor: '#000' },
    props: {init: ''}
  },
  'Const': {
    categories: ['core'],
    output: 'any',
    style: {
      color: '#555',
      textColor: '#333',
      shape: 'circle'
    },
    props: {value: ''}
  }
}

export default {
  components: {FlowManager, FlowPanel, FlowNode, FlowPanzoom, HxSplit, HxModal, AppChat},
  data () {
    return {
      registry: JSON.parse(JSON.stringify(defRegistry)),

      /* {
        // Fixed default stuff
        'Test': {
          group: 'Generic',
          output: 'any',
          style: {
            shape: 'thing'
          }
        },

        'MatMul': { group: 'Machine learning', inputs: [ '[]float32', '[]float32' ], output: '[]float32', style: { color: '#a44', textColor: 'white' } },
        'Activator': { group: 'Machine learning', inputs: [ '[]float32' ], output: '[]float32', style: { color: '#a44', textColor: 'white', shape: 'circle' } },

        'test': { group: 'Text', inputs: [ '[]float32', 'string' ], output: 'string', style: {'color': '#a93'} },
        'reverse': { group: 'Text', inputs: [ 'string' ], output: 'string', style: {'color': '#a93'} },

        'fetch': { group: 'json', output: 'json', style: {'color': '#99a'} },
        'jsonExtract': { group: 'json', inputs: ['json'], output: 'string', style: {'color': '#99a'} },

        'string': { group: 'Visualization', inputs: ['string'], style: {'color': '#9a9'} },
        'lineGraph': { group: 'Visualization', inputs: ['[]float32', '[]float32'], style: {'color': '#9a9'} }
      }, */

      nodeInspectTarget: false,

      funcsSize: '250px',
      funcsActive: true,
      funcsResizeable: false,

      dark: false
    }
  },
  watch: {
    nodeInspectTarget: {
      handler (val, oldVal) {
        if (!val === null && !oldVal) { return }
        if (!val) {
          this.$refs.flowManager.sendDocumentUpdate()
          return
        }
        this.$refs.flowManager.sendFlowEvent('nodeUpdate', [this.nodeInspectTarget])
      },
      deep: true
    }
  },

  mounted () {
    // Handle incoming things
    this.$flowService.on('sessionJoin', (v) => {
      if (v.id !== this.$route.params.sessId) {
        this.$router.push('/' + v.id) // Swap to ID
      }
    })
    this.$flowService.on('registry', (v) => {
      this.registry = Object.assign({}, defRegistry, v.data)
    })
    // Connected
    this.$flowService.connected(() => {
      // Make this in a service
      if (this.$route.params.sessId === undefined) {
        this.$flowService.sessionNew()
        return
      }
      this.$flowService.sessionLoad(undefined, this.$route.params.sessId)
    })
  },
  methods: {
    nodeInspect (node) { // node
      this.nodeInspectTarget = node
      this.$nextTick(() => {
        if (!this.$refs.modalInput) return
        this.$refs.modalInput.setSelectionRange(0, this.$refs.modalInput.value.length)
        this.$refs.modalInput.focus()
      })
    },
    nodeProcess (node) {
      this.$flowService.nodeProcess(node.id)
    },
    funcsSizeUpdate (ev, size) {
      this.funcsSize = size
    }
    // Update individual nodes/links
  }
}

</script>
<style>
.flow-main {
  height:100%;
  display:flex;
  flex-direction: column;
}

.flow-main .app-flow-container {
  position:relative;
  flex:1;
}

.flow-main .flow-container {
  position:absolute;
  top:0;
  right:0;
  bottom:0;
  left:0;
}

.flow-main .app-header {
  padding:0 14px;
  height: 50px;
  display:flex;
  justify-content: space-between;
  align-items: center;
}

.flow-main  .app-info {
  color: #aaa;
  font-size:10px;
  margin:20px;
  padding:20px;
  position:absolute;
  right:0;
  bottom:3%;
}

.flow-main .app-watermark {
  position:absolute;
  top:40%;
  text-align:center;
  width:100%;
  font-size:100px;
  text-shadow: 1px 1px 1px rgba(255,255,255,0.5), -1px -1px 1px rgba(0,0,0,0.05);
}

.split .splitter{
  flex-basis:0;
  position:relative;
  background: rgba(208,208,208,0.9);
}

.split:not(.resizeable) .content:first-child {
  transition: all 0.3s;
}

.split.resizeable.horizontal .splitter::after {
  display:flex;
  justify-content: center;
  align-items: center;
  z-index:100;
  content:" ";
  position:absolute;
  top:20%;
  bottom:20%;
  left:0;
  width:10px;
  background: rgba(0,0,0,0.4);
  transition: all 0.3s;
}

.app-horizontal {
  height:100%;
  max-height:100%;
  display:flex;
  position:relative;
  flex-flow:row;
  overflow:hidden;
}

.app-chat {
  position:absolute;
  top:0;
  right:0;
  height:100%;
}

.flow-modal__info {
  padding-bottom:20px;
  display:flex;
  flex-flow:row;
}

.flow-modal__info > * {
  margin-right:10px;
}

.flow-modal__body label {
  font-size:14px;
  display:flex;
  flex-flow:row;
  font-weight:bold;
  padding-bottom:10px;
}

.flow-modal__info .property {
  padding-left:20px;
  font-size:12px;
}

</style>
