<template>
    <v-app :dark="darkTheme">
        <v-toolbar app>
            <v-toolbar-title class="headline text-uppercase">
                <span v-if="appNet !== ''">{{ appNet }}:</span>
                <span class="font-weight-light">{{ appName }}</span>
            </v-toolbar-title>

            <v-progress-circular
                indeterminate
                v-if="isLoading"
                class="loading-progress"
            ></v-progress-circular>

            <v-spacer></v-spacer>

            <v-menu bottom left>
                <template v-slot:activator="{ on }">
                    <v-btn
                        flat
                        icon
                        v-on="on"
                    >
                        <v-icon>mdi-bookmark</v-icon>
                    </v-btn>
                </template>

                <v-list>
                    <v-list-tile
                        @click="setBookmark(false)"
                    >
                        <v-list-tile-action>
                            <v-icon>mdi-bookmark-plus</v-icon>
                        </v-list-tile-action>
                        <v-list-tile-title>{{ locale.SetBookmark }}</v-list-tile-title>
                    </v-list-tile>
                    <v-list-tile
                        @click="removeBookmark(false)"
                    >
                        <v-list-tile-action>
                            <v-icon>mdi-bookmark-minus</v-icon>
                        </v-list-tile-action>
                        <v-list-tile-title>{{ locale.RemoveBookmark }}</v-list-tile-title>
                    </v-list-tile>
                </v-list>
            </v-menu>

            <v-menu bottom left>
                <template v-slot:activator="{ on }">
                    <v-btn
                        flat
                        icon
                        v-on="on"
                    >
                        <v-icon>more_vert</v-icon>
                    </v-btn>
                </template>

                <v-list>
                    <v-list-tile>
                        <v-list-tile-action>
                            <v-switch v-model="darkTheme" color="blue"></v-switch>
                        </v-list-tile-action>
                        <v-list-tile-title>{{ locale.DarkTheme }}</v-list-tile-title>
                    </v-list-tile>
                    <v-list-tile>
                        <v-list-tile-action>
                            <v-switch v-model="autoBookmark" color="blue"></v-switch>
                        </v-list-tile-action>
                        <v-list-tile-title>{{ locale.AutoBookmarks }}</v-list-tile-title>
                    </v-list-tile>

                    <v-divider></v-divider>

                    <v-list-tile @click="showAboutDialog">
                        <v-list-tile-action>
                            <v-icon>mdi-information-variant</v-icon>
                        </v-list-tile-action>
                        <v-list-tile-title>{{ locale.About }}</v-list-tile-title>
                    </v-list-tile>

                </v-list>
            </v-menu>
        </v-toolbar>

        <v-content>
            <v-tabs
                v-model="activeTab"
                align-with-title
                centered
                fixed-tabs
            >
                <v-tab ripple>{{ locale.Authors }}</v-tab>
                <v-tab-item>
                    <Authors ref="Authors" v-on:author_selected="openBooks" />
                </v-tab-item>
                <v-tab ripple>{{ locale.Books }}</v-tab>
                <v-tab-item>
                    <Books ref="Books" v-on:book_selected="openBook" />
                </v-tab-item>
                <v-tab ripple>{{ locale.Book }}</v-tab>
                <v-tab-item>
                    <Book ref="Book" v-on:progress_updated="updateProgress" />
                </v-tab-item>
            </v-tabs>
        </v-content>

        <v-card tile class="player-interface">
            <v-flex xs12>
                <v-slider
                    v-model="progress"
                    min="0"
                    max="100"
                    height="30px"
                    :disabled="isOff"
                    :inverse-label="true"
                    :label="`${currentTime}/${duration}`"
                    class="time-slider px-2"
                ></v-slider>
            </v-flex>

            <v-list>
                <v-list-tile>
                    <v-list-tile-content v-if="$vuetify.breakpoint.smAndUp">
                        <v-list-tile-title>{{ authorName }}</v-list-tile-title>
                        <v-list-tile-sub-title>{{ bookTitle }}<span v-if="currentChapter !== ''"> - {{ currentChapter }}</span></v-list-tile-sub-title>
                    </v-list-tile-content>

                    <v-spacer></v-spacer>

                    <v-list-tile-action @click="prevChapter">
                        <v-btn icon>
                            <v-icon>mdi-skip-backward</v-icon>
                        </v-btn>
                    </v-list-tile-action>

                    <v-list-tile-action :class="{ 'mx-5': $vuetify.breakpoint.mdAndUp }">
                        <v-btn icon @click="toggleStatus">
                            <v-icon>mdi-{{ isPlaying ? "pause" : "play" }}</v-icon>
                        </v-btn>
                    </v-list-tile-action>

                    <v-list-tile-action
                        @click="nextChapter"
                    >
                        <v-btn icon>
                            <v-icon>mdi-skip-forward</v-icon>
                        </v-btn>
                    </v-list-tile-action>
                    <v-flex xs6 sm3 md2>
                        <v-slider
                            :class="{ 'mr-3 ml-5': $vuetify.breakpoint.mdAndUp, 'ml-3' : $vuetify.breakpoint.mdAndDown }"
                            :min="0"
                            :max="10"
                            v-model="volume"
                            append-icon="volume_up"
                            prepend-icon="volume_down"
                        ></v-slider>
                    </v-flex>
                </v-list-tile>
            </v-list>
        </v-card>
        <MessageDialog ref="MessageDialog" />
    </v-app>
</template>

<script>
    import Authors from './components/Authors'
    import Books from './components/Books'
    import Book from './components/Book'
    import MessageDialog from './components/MessageDialog'

    export default {
        name: 'App',

        components: {
            Authors,
            Books,
            Book,
            MessageDialog
        },

        data () {
            return {
                appNet: "CAINet",
                appName: "Аудиотека",
                activeTab: null,
                autoBookmark: false,
                darkTheme: false,
                isLoading: false,
                isMounted: false,
                volume: 5,
                locale: []
            }
        },

        mounted () {
            this.isMounted = true;
            this.darkTheme = localStorage.darkTheme ? JSON.parse(localStorage.darkTheme) : false;
            this.autoBookmark = localStorage.autoBookmark ? JSON.parse(localStorage.autoBookmark) : false;
            this.volume = localStorage.volume ? JSON.parse(localStorage.volume) : 5;

            this.isLoading = true;

            let userLocale = navigator.language || navigator.userLanguage;

            this.axios.get("locales/locales.json")
                .then(response => {
                    let localeLoaded = false;
                    response.data.forEach(element => {
                        if (element.code == userLocale.toLowerCase()) {
                            this.loadLocale(element.file);
                            localeLoaded = true;
                        }
                    });
                    if (!localeLoaded) { this.loadLocale("en"); }
                })
                .catch(error => {
                    console.log(error);
                    this.showMessage("Error", error);
                });

            this.axios.get("config.json")
                .then(response => {
                    this.appNet = response.data.AppNet;
                    this.appName = response.data.AppName;
                })
                .catch(error => {
                    console.log(error);
                    this.showMessage(this.locale.Error, error);
                });

            this.axios.get("lib/authors.json")
                .then(response => {
                    this.$refs.Authors.items = response.data;
                    this.isLoading = false;
                })
                .catch(error => {
                    console.log(error);
                    this.showMessage(this.locale.Error, error);
                });
        },

        computed: {
            authorName () {
                return !this.isMounted ? "" : this.$refs.Book.authorName;
            },

            bookOpened () {
                return !this.isMounted ? false : this.$refs.Book.items.length > 0;
            },

            bookTitle () {
                return !this.isMounted ? "" : this.$refs.Book.bookTitle;
            },

            currentChapter () {
                let curChapter = !this.isMounted
                    ? ""
                    : this.$refs.Book.items[this.$refs.Book.currentChapter];
                return curChapter ? curChapter.title : "";
            },

            currentTime () {
                return !this.isMounted ? "00:00" : this.$refs.Book.currentTime;
            },

            duration () {
                return !this.isMounted ? "00:00" : this.$refs.Book.duration;
            },

            isOff () {
                return !this.isMounted ? true : this.$refs.Book.isOff;
            },

            isPlaying () {
                return !this.isMounted ? false : this.$refs.Book.isPlaying;
            },

            progress: {
                get () {
                    return !this.isMounted ? "" : this.$refs.Book.progress;
                },

                set (newVal) {
                    if (newVal !== Math.round(this.$refs.Book.progress)) {
                        this.$refs.Book.audioElement.currentTime = this.$refs.Book.audioElement.duration * newVal / 100;
                    }
                }
            }
        },

        watch: {
            autoBookmark (val) { localStorage.autoBookmark = val; },
            darkTheme (val) { localStorage.darkTheme = val; },
            volume (val) {
                localStorage.volume = val;
                this.$refs.Book.volume = val;
            }
        },

        methods: {
            getHash (val) {
                let CryptoJS = require("crypto-js");
                let hash = CryptoJS.MD5(val);
                return hash.toString(CryptoJS.enc.Hex);
            },

            loadLocale (langFile) {
                this.axios.get("locales/" + langFile)
                    .then(response => {
                        this.locale = response.data;
                    })
                    .catch(error => {
                        console.log(error);
                        this.showMessage("Error", error);
                    });
            },

            nextChapter () { this.$refs.Book.nextChapter(); },

            openBook (val) {
                this.$refs.Book.authorName = this.$refs.Books.authorName;
                this.$refs.Book.authorImg = this.$refs.Books.authorImg;
                this.$refs.Book.bookImg = val.image;
                this.$refs.Book.bookTitle = val.title;

                this.isLoading = true;

                this.axios.get(val.book)
                    .then(response => {
                        this.$refs.Book.items = response.data;

                        let bmKey = this.getHash(JSON.stringify(this.$refs.Book.items));
                        let bookmark = localStorage.getItem(bmKey) ? JSON.parse(localStorage.getItem(bmKey)) : null;

                        if (bookmark !== null) {
                            this.$refs.Book.loadChapter(bookmark.chapter, bookmark.progress);
                        } else {
                            this.$refs.Book.loadChapter();
                        }

                        this.activeTab = 2;
                        this.isLoading = false;
                    })
                    .catch(error => {
                        this.isLoading = false;
                        console.log(error);
                        this.showMessage(this.locale.Error, error);
                    });

                this.activeTab = 2;
            },

            openBooks (val) {
                this.isLoading = true;

                this.axios.get(val.books)
                    .then(response => {
                        this.$refs.Books.authorName = val.author;
                        this.$refs.Books.authorImg = val.image;
                        this.$refs.Books.items = response.data;
                        this.activeTab = 1;
                        this.isLoading = false;
                    })
                    .catch(error => {
                        this.isLoading = false;
                        console.log(error);
                        this.showMessage(this.locale.Error, error);
                    });
            },

            prevChapter () { this.$refs.Book.prevChapter(); },

            progressClick (event) {
                if (!this.isMounted) { return; }

                if (this.$refs.Book.audioElement !== null) {
                    let elLeft = this.$refs.playProgress.$el.getBoundingClientRect().left;
                    let elWidth = this.$refs.playProgress.$el.getBoundingClientRect().width;

                    this.$refs.Book.audioElement.currentTime = this.$refs.Book.audioElement.duration * (event.clientX - elLeft) / elWidth;
                }
            },

            removeBookmark (silent = true) {
                if (this.$refs.Book.items.length == 0) { return; }
                localStorage.removeItem(this.getHash(this.$refs.Book.items));
                if (!silent) { this.showMessage(this.locale.Information, this.locale.BookmarkRemoved); }
            },

            setBookmark (silent = true) {
                if (this.$refs.Book.items.length == 0) { return; }

                let data = {
                    chapter: this.$refs.Book.currentChapter,
                    progress: this.$refs.Book.progress
                };

                localStorage.setItem(
                    this.getHash(JSON.stringify(this.$refs.Book.items)),
                    JSON.stringify(data)
                );

                if (!silent) { this.showMessage(this.locale.Information, this.locale.BookmarkSaved); }
            },

            showAboutDialog () {
                let userLocale = navigator.language || navigator.userLanguage;
                userLocale = userLocale.indexOf("-") > 0
                    ? userLocale.substring(0, userLocale.indexOf("-")).toLowerCase()
                    : userLocale.toLowerCase();

                let aboutText = "";
                if (userLocale == "ru") {
                    aboutText = "<p><center>Аудиотека</center></p>" +
                        "<p><center>&copy; Александр Чебыкин, 2019</center></p>" +
                        "<p><center>Опубликовано под лицензией <a href=\"https://opensource.org/licenses/MIT\" target=\"_blank\">MIT license</a></center></p>" +
                        "<p><center>Git: <a href=\"https://home.cainet.info:3000/cai/AudioLib\" target=\"_blank\">https://home.cainet.info:3000/cai/AudioLib</a></center></p>";
                } else {
                    aboutText = "<p><center>Audiobooks library</center></p>" +
                        "<p><center>&copy; Alexander I Chebykin, 2019</center></p>" +
                        "<p><center>Published under <a href=\"https://opensource.org/licenses/MIT\" target=\"_blank\">MIT license</a></center></p>" +
                        "<p><center>Git: <a href=\"https://home.cainet.info:3000/cai/AudioLib\" target=\"_blank\">https://home.cainet.info:3000/cai/AudioLib</a></center></p>";
                }
                this.showMessage(this.locale.About, aboutText);
            },

            showMessage (title, text) {
                this.$refs.MessageDialog.title = title;
                this.$refs.MessageDialog.text = text;
                this.$refs.MessageDialog.dialog = true;
            },

            toggleStatus () {
                this.$refs.Book.toggleStatus();
                if (this.autoBookmark && this.$refs.Book.isPaused) { this.setBookmark(); }
            },

            updateProgress (val) { this.progress = val; }
        }
    }
</script>

<style>
    .loading-progress { margin: auto 15px; }

    .player-interface {
        position: fixed;
        bottom: 0;
        width: 100%;
    }
    .player-interface .time-slider {
        width: 100%;
        margin: 0 0 -25px 0;
    }
</style>
