<template>
    <div>
        <div class="sidebar" id="activitySideBar">
            <div class="accordion" id="accordionActivities">
                <div class="card" v-for="activity in selectedActStats.activities" style="width:100%">
                    <div class="card-header" :id="combinedStr('heading', selectedActStats.model + activity.activity)">
                        <button type="button" style="width:100%" class="btn btn-outline-success" data-toggle="collapse" :data-target="combinedStr('#collapse', selectedActStats.model + activity.activity)" aria-expanded="false" aria-controls="combinedStr('#collapse', selectedActStats.model + activity.activity)">
                            {{activity.activity}}
                        </button>
                    </div>

                    <div :id="combinedStr('collapse', selectedActStats.model + activity.activity)" class="collapse" :aria-labelledby="combinedStr('#heading', selectedActStats.model + activity.activity)" data-parent="#accordionActivities">
                        <div class="card-body">

                            <div class="accordion" id="accordionColumns">
                                <div class="card" v-for="column in activity.columns">
                                    <div class="card-header" :id="combinedStr('heading', selectedActStats.model + activity.activity + column.column)">
                                        <button type="button" style="width:100%" class="btn btn-outline-info" data-toggle="collapse" :data-target="combinedStr('#collapse', selectedActStats.model + activity.activity + column.column)" aria-expanded="false" aria-controls="combinedStr('#collapse', selectedActStats.model + activity.activity + column.column)">
                                            {{column.column}}
                                        </button>
                                    </div>

                                    <div :id="combinedStr('collapse', selectedActStats.model + activity.activity + column.column)" class="collapse" :aria-labelledby="combinedStr('#heading', selectedActStats.model + activity.activity + column.column)" data-parent="#accordionColumns">
                                        <div class="card-body">
                                            <ul style="list-style-type:none;">
                                                <li v-for="value in column.values">{{value.value}} : {{value.count}}</li>
                                            </ul>
                                        </div>
                                    </div>
                                </div>
                            </div>

                        </div>
                    </div>
                </div>
            </div>
        </div>

        <div id="main">
            <div style="margin-right:-96%;">
                <button class="btn btn-success" v-on:click="openCloseSidebar()" style="border-radius:20px; padding-right:80px">< Activities</button>
            </div>

            <transition name="modal">
                <div v-if="modalIsOpen">
                    <div class="overlay" @click.self="modalIsOpen = false;">
                        <div class="modalDiv">
                            <discovery @settingsChanged="handleData($event)"></discovery>
                            <input type="submit" class="btn btn-success" value="Start" name="submit" v-on:click="submit" />
                            <input type="button" class="btn btn-primary" value="Cancel" @click.self="modalIsOpen = false;" style="margin-left:50px;"/>
                        </div>
                    </div>
                </div>
            </transition>

            <table style="margin-left: 5%;">
                <tr>
                    <td style="width: 1%; height:1%" colspan="2">
                        <select size="10" class="form-control" v-model="modelSelected">
                            <option v-for="item in modelList" :value="item.name">{{item.name}}</option>
                        </select>
                    </td>
                    <td rowspan="4" style="width: 80%" class="table-bordered">
                        <vue-bpmn
                            :key="selectedData.url"
                            :url="selectedData.url"
                            v-on:error="handleError"
                            v-on:shown="handleShown"
                        ></vue-bpmn>
                    </td>
                </tr>
                <tr style="width: 1%; height:1%">
                    <td>
                        <input type="button" value="Download" v-on:click="downloadModel" class="btn btn-outline-success"/>
                    </td>
                    <td>
                        <input type="button" value="Copy link" v-on:click="copyToClipboard" class="btn btn-outline-primary"/>
                        <input type="hidden" id="copyTb" :value="selectedData.url"/>
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        <table class="table table-sm">
                            <tr>
                                <td>Traces:</td>
                                <td>{{selectedData.traces}}</td>
                            </tr>
                            <tr>
                                <td>Nodes:</td>
                                <td>{{selectedData.nodes}}</td>
                            </tr>
                            <tr>
                                <td>Density</td>
                                <td>{{selectedData.density}}</td>
                            </tr>
                            <tr>
                                <td>Cohesion:</td>
                                <td>{{selectedData.cohesion}}</td>
                            </tr>
                            <tr>
                                <td>Coupling</td>
                                <td>{{selectedData.coupling}}</td>
                            </tr>
                            <tr>
                                <td>CNC:</td>
                                <td>{{selectedData.cnc}}</td>
                            </tr>
                        </table>
                        <input type="button" value="Change settings" v-on:click="openModal" class="btn btn-success"/>
                    </td>
                </tr>
            </table>
        </div>

    </div>
</template>

<style scoped>
    .modalDiv{
        margin: 0px auto;
        padding: 20px;
        background-color: #fff;
        border-radius: 20px;
        box-shadow: 0 2px 8px 3px;
        transition: all 0.2s ease-in;
        font-family: Helvetica, Arial, sans-serif;
        max-height: 100%;
        overflow-y: auto;
    }

    .fadeIn-enter {
      opacity: 0;
    }

    .fadeIn-leave-active {
      opacity: 0;
      transition: all 0.2s step-end;
    }

    .fadeIn-enter .modal,
    .fadeIn-leave-active.modal {
      transform: scale(1.1);
    }

    .overlay {
      position: fixed;
      top: 0;
      left: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 100%;
      background: #00000094;
      z-index: 999;
      transition: opacity 0.2s ease;
    }

    /* The sidebar menu */
    .sidebar {
      height: 100%; /* 100% Full-height */
      width: 0; /* 0 width - change this with JavaScript */
      position: fixed; /* Stay in place */
      z-index: 1; /* Stay on top */
      top: 0;
      right: 0;
      overflow-x: auto; /* Disable horizontal scroll */
      transition: 0.5s; /* 0.5 second transition effect to slide in the sidebar */
    }

    /* Style page content - use this if you want to push the page content to the right when you open the side navigation */
    #main {
      transition: margin-right .5s; /* If you want a transition effect */
    }

    /* On smaller screens, where height is less than 450px, change the style of the sidenav (less padding and a smaller font size) */
    @media screen and (max-height: 450px) {
      .sidebar {padding-top: 15px;}
      .sidebar div {font-size: 18px;}
    }
</style>

<script>
    import axios from "axios";
    import Request from '../components/request/request.js';
    import VueBpmn from '../components/vue-bpmn/vue-bpmn.vue';
    import Discovery from "../components/discovery/settings.vue";

    export default {
        name: "model",
        data: function () {
            return {
                token:this.$route.params.token,

                modelList:[],
                modelSelected:"Model #1",
                selectedData:{},
                modalIsOpen:false,
                sideIsOpen:false,
                actStats:[],
                selectedActStats:{},

                artifactFilterMap:new Map(),
                token:this.$route.params.token,
                nodes:null,
                density:null,
                cohesion:null,
                coupling:null,
                cnc:null,
                selectedDiscovery:'FREQUENCY',
                selectedMethod:'SPLITMINER',
                percentileFrequencyThreshold:1,
                parallelismsThreshold:1,
                filterType:'STD',
                parallelismsFirst:false,
                replaceIORs:false,
                removeLoopActivities:false,
                structuringTime:'NONE',
            }
        },
        components: {
            VueBpmn,
            Discovery
        },

        beforeMount() {
            Request.getAxios().get(
                this.$hostname + "/result/" + this.token,
            ).then((response) => {
                this.loadLinks(response);
                this.selectedData = this.modelList[0];
            });

            Request.getAxios().get(
                this.$hostname + "/activityStats/" + this.token,
            ).then((response) => {
                this.loadActivityStats(response.data.content);

                this.selectedActStats = this.actStats.find(obj => {
                    return obj.model === this.selectedData.url;
                });
            });

        },

        computed: {
          	combinedStr () {
            	return (str, item) => str + btoa(item).replace(/[^\w\s]|_/g, "").replace(/\s+/g, '');
            },
        },

        methods: {
            loadActivityStats: function(response){
                response.forEach(data => {
                    var key = data.key.split(data.keySeparator);

                    var modelObj = this.actStats.find(obj => {
                                            return obj.model === data.url;
                                        });

                    if(typeof modelObj !== "undefined"){
                        var activity = modelObj.activities.find(obj => {
                                        return obj.activity === key[0];
                                    });

                        if(typeof activity !== "undefined"){
                                var column = activity.columns.find(obj => {
                                    return obj.column === key[1];
                                });

                                if(typeof column !== "undefined"){
                                    activity.columns.forEach(obj => {
                                        if(obj.column === key[1]){
                                            obj.values.push({value:key[2], count: data.count});
                                        }
                                    });
                                }
                                else{
                                    column = {};
                                    column.column = key[1];
                                    var values = [];
                                    values.push({value:key[2], count: data.count});
                                    column.values = values;

                                    this.actStats.forEach(obj => {
                                        if(obj.model === data.url){
                                            obj.activities.forEach(obj2 => {
                                                if(obj2.activity === key[0])
                                                    obj2.columns.push(column);
                                            });
                                        }
                                    });
                                }
                        }
                        else{
                            activity = {};
                            activity.activity = key[0];
                            var columns = [];
                            columns.push({
                                column:key[1],
                                values:[{value:key[2], count: data.count}]
                            });
                            activity.columns = columns;

                            this.actStats.forEach(obj => {
                                if(obj.model === data.url)
                                    obj.activities.push(activity);
                            });
                        }
                    }
                    else{
                        modelObj = {};
                        modelObj.activities = [];
                        modelObj.activities.push({
                            activity:key[0],
                            columns:[{
                                column:key[1],
                                values:[{value:key[2], count: data.count}]
                            }]
                        });
                        modelObj.model = data.url;

                        this.actStats.push(modelObj);
                    }
                });

            },

            loadLinks: function(response){
                var counter = 1;
                this.modelList = [];
                response.data.content.forEach(data => {
                    this.modelList.push({url: data.url,
                                        name:"Model #" + counter,
                                        traces: data.traces,
                                        nodes: data.nodes,
                                        density: data.density,
                                        cohesion: data.cohesion,
                                        coupling: data.coupling,
                                        cnc: data.cnc});
                    counter++;
                });
            },

            handleError: function(err) {
                console.error('failed to show diagram', err);
            },
            handleShown: function() {
                console.log('diagram shown');
            },

            downloadModel(){
                axios.get(this.selectedData.url, { responseType: 'blob' })
                    .then(({ data }) => {
                        let blob = new Blob([data], { type: 'image/png' });
                        let link = document.createElement('a');
                        link.href = window.URL.createObjectURL(blob);
                        link.download = 'model.bpmn';
                        link.click();
                    })
            },

            copyToClipboard () {
                  let str = document.querySelector('#copyTb');
                  str.setAttribute('type', 'text');
                  str.select();

                  document.execCommand('copy');

                  str.setAttribute('type', 'hidden')
                  window.getSelection().removeAllRanges()
            },

            openModal () {
                if(this.modalIsOpen == true)
                    this.modalIsOpen = false;
                else
                    this.modalIsOpen = true;
            },

            openCloseSidebar () {
                if(this.sideIsOpen == true){
                    this.sideIsOpen = false;
                    document.getElementById("activitySideBar").style.width = "0";
                    document.getElementById("main").style.marginRight = "0";
                }
                else{
                    this.sideIsOpen = true;
                    document.getElementById("activitySideBar").style.width = "20%";
                    document.getElementById("main").style.marginRight = "20%";
                }
            },

            submit() {
                let formData = new FormData();

                var tmpFilterMap = Array.from(this.artifactFilterMap).map( ([k,v]) => {return {[k]:v}} );

                var mapStatMeasures = {
                    'nodes':this.nodes,
                    'density':this.density,
                    'cohesion':this.cohesion,
                    'coupling':this.coupling,
                    'cnc':this.cnc
                };

                var methodParams = {
                    'percentileFrequencyThreshold':this.percentileFrequencyThreshold,
                    'parallelismsThreshold':this.parallelismsThreshold,
                    'filterType':this.filterType,
                    'parallelismsFirst':this.parallelismsFirst,
                    'replaceIORs':this.replaceIORs,
                    'removeLoopActivities':this.removeLoopActivities,
                    'structuringTime':this.structuringTime,
                };

                formData.append('discovery', this.selectedDiscovery);
                formData.append('algorithm', this.selectedMethod);
                formData.append('statMeasures', JSON.stringify(mapStatMeasures));
                formData.append('methodParams', JSON.stringify(methodParams));
                formData.append('artifactFilterMap', JSON.stringify(tmpFilterMap));

                this.$router.push({name: "loading", params: {token: this.token, formData: formData}});
            },

            handleData: function(e) {
                [
                   this.artifactFilterMap,

                   this.nodes,
                   this.density,
                   this.cohesion,
                   this.coupling,
                   this.cnc,

                   this.selectedDiscovery,
                   this.selectedMethod,

                   this.percentileFrequencyThreshold,
                   this.parallelismsThreshold,
                   this.filterType,
                   this.parallelismsFirst,
                   this.replaceIORs,
                   this.removeLoopActivities,
                   this.structuringTime
                ] = e;
            }
        },

        watch: {
            modelSelected() {
                this.selectedData = this.modelList.find(obj => {
                    return obj.name === this.modelSelected;
                });

                this.selectedActStats = this.actStats.find(obj => {
                    return obj.model === this.selectedData.url;
                });
            }
        }
   }
</script>