<!-- Main Visualization View -->

<template>
  <div>
    <b-container fluid class="bv-example-row">
      <b-row class="md-3">
        <b-col cols="3">
          <mdb-card>
            <mdb-card-header color="primary-color" tag="h5" class="text-center">Data Set Selection and Execution</mdb-card-header>
            <mdb-card-body>
              <mdb-card-text class="text-center" >
                <DataSetExecController
                v-on:InitializeEnsembleLearningEvent="DataBaseRequestDataSetName()"
                />
              </mdb-card-text>
            </mdb-card-body>
          </mdb-card>
        </b-col>
        <b-col cols="6">
          <mdb-card>
            <mdb-card-header color="primary-color" tag="h5" class="text-center">Per Class Metrics Exploration</mdb-card-header>
              <mdb-card-body>
                  <BarChart/>
              </mdb-card-body>
          </mdb-card>
        </b-col>
        <b-col cols="3">
          <mdb-card-header color="primary-color" tag="h5" class="text-center">Data Space Visualization</mdb-card-header>
          <mdb-card-body>
            <mdb-card-text class="text-center">
              <DataSpace/>
            </mdb-card-text>
          </mdb-card-body>
        </b-col>
      </b-row>
      <b-row class="mb-3 mt-3">
        <b-col cols="3">
          <mdb-card>
            <mdb-card-header color="primary-color" tag="h5" class="text-center">Algorithms Selection and HyperParameters Search</mdb-card-header>
              <mdb-card-body>
                  <Algorithms/>
                  <AlgorithmHyperParam/>
              </mdb-card-body>
          </mdb-card>
        </b-col>
        <b-col cols="6">
          <mdb-card>
            <mdb-card-header color="primary-color" tag="h5" class="text-center">Models, Features, and Classes Connection</mdb-card-header>
            <mdb-card-body>        
              <StretchedChord/>
            </mdb-card-body>
            <mdb-card-body>        
              <Heatmap/>
            </mdb-card-body>
          </mdb-card>
        </b-col>
        <b-col cols="3">
          <mdb-card >
            <mdb-card-header color="primary-color" tag="h5" class="text-center">Predictions Space Visualization</mdb-card-header>
            <mdb-card-body>
              <mdb-card-text class="text-center">
                <PredictionsSpace/>
              </mdb-card-text>
            </mdb-card-body>
          </mdb-card>
        </b-col>
      </b-row>
      <b-row>
          <b-col cols="3">
            <mdb-card>
              <mdb-card-header color="primary-color" tag="h5" class="text-center">Base Models Overview</mdb-card-header>
              <mdb-card-body>
                <ScatterPlot/>
              </mdb-card-body>
            </mdb-card>
          </b-col>
          <b-col cols="6">
            <mdb-card>
                <mdb-card-header color="primary-color" tag="h5" class="text-center">Subset Feature Selection</mdb-card-header>
                    <mdb-card-body>
                      <FeatureSelection/>
                    </mdb-card-body>
            </mdb-card>
          </b-col>
          <b-col cols="3">
            <mdb-card>
              <mdb-card-header color="primary-color" tag="h5" class="text-center">Meta-Model Performance</mdb-card-header>
              <mdb-card-body>
                <FinalResultsLinePlot/>
              </mdb-card-body>
            </mdb-card>
          </b-col>
      </b-row>
    </b-container>
  </div>
</template>

<script>

import Vue from 'vue'
import DataSetExecController from './DataSetExecController.vue'
import Algorithms from './Algorithms.vue'
import AlgorithmHyperParam from './AlgorithmHyperParam.vue'
import ScatterPlot from './ScatterPlot.vue'
import DataSpace from './DataSpace.vue'
import PredictionsSpace from './PredictionsSpace.vue'
import BarChart from './BarChart.vue'
import StretchedChord from './StretchedChord.vue'
import Heatmap from './Heatmap.vue'
import FeatureSelection from './FeatureSelection.vue'
import FinalResultsLinePlot from './FinalResultsLinePlot.vue'
import axios from 'axios'
import { loadProgressBar } from 'axios-progress-bar'
import 'axios-progress-bar/dist/nprogress.css'
import { mdbCard, mdbCardBody, mdbCardText, mdbCardHeader } from 'mdbvue'
import { EventBus } from '../main.js'
import * as jQuery from 'jquery' 
import $ from 'jquery'

export default Vue.extend({
  name: 'Main',
  components: {
    DataSetExecController,
    Algorithms,
    AlgorithmHyperParam,
    ScatterPlot,
    DataSpace,
    PredictionsSpace,
    BarChart,
    StretchedChord,
    Heatmap,
    FeatureSelection,
    FinalResultsLinePlot,
    mdbCard,
    mdbCardBody,
    mdbCardHeader,
    mdbCardText
  },
  data () {
    return {
      Collection: 0,
      OverviewResults: 0,
      RetrieveValueFile: 'IrisC',
      ClassifierIDsList: '',
      SelectedFeaturesPerClassifier: '',
      FinalResults: 0,
      Algorithms: ['KNN','RF'],
      selectedAlgorithm: '',
      PerformancePerModel: '',
      brushed: 0,
      ExecutionStart: false,
    }
  },
  methods: {
    DataBaseRequestDataSetName () {
      this.ExecutionStart = true
      this.getOverviewResults()
    },
    getCollection () {
      this.Collection = this.getCollectionFromBackend()
    },
    getCollectionFromBackend () {
      const path = `http://localhost:5000/data/ClientRequest`

      const axiosConfig = {
        headers: {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token',
          'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS'
        }
      }
      axios.get(path, axiosConfig)
        .then(response => {
          this.Collection = response.data.Collection
          EventBus.$emit('emittedEventCallingDataPlot', this.Collection)
          console.log('Collection was overwritten with new data sent by the server!')
        })
        .catch(error => {
          console.log(error)
        })
    },
    getOverviewResults () {
      this.OverviewResults = this.getScatterplotDataFromBackend()
    },
    getScatterplotDataFromBackend () {
      const path = `http://localhost:5000/data/PlotClassifiers`

      const axiosConfig = {
        headers: {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token',
          'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS'
        }
      }
      axios.get(path, axiosConfig)
        .then(response => {
          this.OverviewResults = response.data.OverviewResults
          console.log('Server successfully sent all the data related to visualizations!')
          EventBus.$emit('emittedEventCallingScatterPlot', this.OverviewResults)
          var length = JSON.parse(this.OverviewResults[0]).length
          if (length < 64) {
            this.OverviewResults.push(JSON.stringify(this.ClassifierIDsList))
            EventBus.$emit('emittedEventCallingBarChart', this.OverviewResults)
            /*EventBus.$emit('emittedEventCallingChordView', this.OverviewResults)
            EventBus.$emit('emittedEventCallingHeatmapView', this.OverviewResults)
            EventBus.$emit('emittedEventCallingTableView', this.OverviewResults)
            EventBus.$emit('emittedEventCallingDataSpacePlotView', this.OverviewResults)
            EventBus.$emit('emittedEventCallingPredictionsSpacePlotView', this.OverviewResults)*/
            this.OverviewResults.pop()
          }
          this.getFinalResults()
        })
        .catch(error => {
          console.log(error)
        })
    },
    getModelsPerformance () {
      this.ModelsPerformance = this.getModelsPerformanceFromBackend()
    },
    getModelsPerformanceFromBackend () {
      const path = `http://localhost:5000/data/PerformanceForEachModel`

      const axiosConfig = {
        headers: {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token',
          'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS'
        }
      }
      axios.get(path, axiosConfig)
        .then(response => {
          this.PerformancePerModel = response.data.PerformancePerModel
          console.log('Server successfully sent all the performance data related to models!')
          EventBus.$emit('emittedEventCallingAllAlgorithms', this.PerformancePerModel)
        })
        .catch(error => {
          console.log(error)
        })
    },
    SendSelectedPointsToServer () {
      const path = `http://127.0.0.1:5000/data/ServerRequestSelPoin`
      const postData = {
        ClassifiersList: this.ClassifierIDsList
      }
      const axiosConfig = {
        headers: {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token',
          'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS'
        }
      }
      axios.post(path, postData, axiosConfig)
        .then(response => {
          console.log('Sent the selected points to the server (scatterplot)!')
          if (this.ClassifierIDsList.length < 64) {
            this.OverviewResults.push(JSON.stringify(this.ClassifierIDsList))
            EventBus.$emit('emittedEventCallingBarChart', this.OverviewResults)
            /*EventBus.$emit('emittedEventCallingChordView', this.OverviewResults)
            EventBus.$emit('emittedEventCallingHeatmapView', this.OverviewResults)
            EventBus.$emit('emittedEventCallingTableView', this.OverviewResults)
            EventBus.$emit('emittedEventCallingDataSpacePlotView', this.OverviewResults)
            EventBus.$emit('emittedEventCallingPredictionsSpacePlotView', this.OverviewResults)*/
            this.OverviewResults.pop()
          }
          this.getFinalResults()
        })
        .catch(error => {
          console.log(error)
        })
    },
    getFinalResults () {
      this.FinalResults = this.getFinalResultsFromBackend()
    },
    getFinalResultsFromBackend () {
      const path = `http://localhost:5000/data/SendFinalResultsBacktoVisualize`

      const axiosConfig = {
        headers: {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token',
          'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS'
        }
      }
      axios.get(path, axiosConfig)
        .then(response => {
          this.FinalResults = response.data.FinalResults
          EventBus.$emit('emittedEventCallingLinePlot', this.FinalResults)
        })
        .catch(error => {
          console.log(error)
        })
    },
    fileNameSend () {
        const path = `http://127.0.0.1:5000/data/ServerRequest`
          const postData = {
            fileName: this.RetrieveValueFile,
            featureSelection: this.SelectedFeaturesPerClassifier
          }
          const axiosConfig = {
            headers: {
              'Content-Type': 'application/json',
              'Access-Control-Allow-Origin': '*',
              'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token',
              'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS'
            }
          }
          axios.post(path, postData, axiosConfig)
            .then(response => {
              console.log('Send request to server! FileName was sent successfully!')
                this.SendAlgorithmsToServer()
            })
            .catch(error => {
              console.log(error)
            })
    },
    SendAlgorithmsToServer () {
      const path = `http://127.0.0.1:5000/data/ServerRequestSelParameters`
      const postData = {
        Algorithms: this.Algorithms,
      }
      const axiosConfig = {
        headers: {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token',
          'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS'
        }
      }
      axios.post(path, postData, axiosConfig)
        .then(response => {
          console.log('Send request to server! Algorithm name was sent successfully!')
          this.getModelsPerformance()
        })
        .catch(error => {
          console.log(error)
        })
    },
    SendBrushedParameters () {
      EventBus.$emit('emittedEventCallingModelBrushed')
      const path = `http://127.0.0.1:5000/data/SendBrushedParam`
      console.log(this.selectedAlgorithm)
      const postData = {
        brushed: this.brushed,
        algorithm: this.selectedAlgorithm
      }
      const axiosConfig = {
        headers: {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token',
          'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS'
        }
      }
      axios.post(path, postData, axiosConfig)
        .then(response => {
          console.log('Send request to server! Brushed parameters sent successfully!')
           if (!this.ExecutionStart) {
          } else {
            this.getCollection()
          }
        })
        .catch(error => {
          console.log(error)
        })
    },
    CallPCP () {
      EventBus.$emit('emittedEventCallingModelClear')
      EventBus.$emit('emittedEventCallingModelSelect', this.selectedAlgorithm)
      EventBus.$emit('emittedEventCallingModel', this.PerformancePerModel)
    }
  },
  mounted() {
    loadProgressBar()
    this.fileNameSend()
    window.onbeforeunload = function(e) {
      //put here the reset function!
      return 'Dialog text here.'
    }
     $(window).unload(function() {
      alert('Handler for .unload() called.')
    })
    EventBus.$on('ReturningBrushedPoints', data => { this.brushed = data })
    EventBus.$on('SendSelectedPointsToServerEvent', data => { this.ClassifierIDsList = data })
    EventBus.$on('SendSelectedPointsToServerEvent', this.SendSelectedPointsToServer)
    EventBus.$on('SendSelectedFeaturesEvent', data => { this.SelectedFeaturesPerClassifier = data })
    EventBus.$emit('SendToServerDataSetConfirmation', data => { this.RetrieveValueFile = data })
    EventBus.$emit('SendToServerDataSetConfirmation', data => { this.fileNameSend })
    EventBus.$on('PCPCall', data => { this.selectedAlgorithm = data })
    EventBus.$on('PCPCall', this.CallPCP)
    EventBus.$on('PCPCallDB', this.SendBrushedParameters)
    
    //Prevent double click to search for a word. 
    document.addEventListener('mousedown', function (event) {
      if (event.detail > 1) {
      event.preventDefault();
      // of course, you still do not know what you prevent here...
      // You could also check event.ctrlKey/event.shiftKey/event.altKey
      // to not prevent something useful.
      }
    }, false);
  },
})
</script>

<style>
#nprogress .bar {
background: red !important;
}

#nprogress .peg {
box-shadow: 0 0 10px red, 0 0 5px red !important;
}

#nprogress .spinner-icon {
border-top-color: red !important;
border-left-color: red !important;
}
</style>