// Copyright (c) 2000-2019 Ericsson Telecom AB                                                       //
// All rights reserved. This program and the accompanying materials are made available under the     //
// terms of the Eclipse Public License v2.0 which accompanies this distribution, and is available at //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html                                                         //
///////////////////////////////////////////////////////////////////////////////////////////////////////
function PlaylistEditor_View(p_viewModel, p_parentId, p_viewId) {
    "use strict";

    var HTML = "WebApplications/Playlist/Views/View.html";
    var CSS = "WebApplications/Playlist/Views/View.css";

    var v_parentId = p_parentId;
    var v_viewId = p_viewId;
    var v_viewmodel = p_viewModel;
    var v_this = this;

    // TODO
    var v_editorContainer = new PlaylistEditor_EditorContainer_View(v_viewmodel, v_this);
    var v_focused_obj;

    ///////////////////// GETTER FOR SUBVIEWS //////////////////////////////

    this.getRequestEditorView = function() {
        return v_requestEditorView;
    };

    ///////////////////// GENERAL VIEW FUNCTIONS //////////////////////////////

    this.init = function(p_callback) {
        $("#" + v_parentId).append('<div id="' + v_viewId + '"></div>');

        function htmlLoaded(ok, data) {
            if (ok) {
                $("#" + v_viewId).append(data);
                v_this.toggleButtons(false);
                $("#PlaylistEditor_WebAppStyle").load(CSS, function() {
                    p_callback(true);
                });
            } else {
                p_callback(false, "Error loading " + HTML);
            }
        }

        v_viewmodel.loadFile(HTML, htmlLoaded);
    };

    function onWindowResize(event) {
        if (event.target == window) {
            $("#PlaylistEditor_MainView").height(ViewUtils.getSuggestedHeight("PlaylistEditor_MainView"));
        }
    }

    this.applicationCreated = function() {
        $("#PlaylistEditor_Button_New").on("click", newPlaylist);
        $("#PlaylistEditor_Button_Load").on("click", loadPlaylist);
        $("#PlaylistEditor_Button_Save").on("click", savePlaylist);
        $("#PlaylistEditor_Button_SaveAs").on("click", savePlaylistAs);
        $(document).on("keydown", keyPressed);

        $(window).on("resize", onWindowResize);
        $("#PlaylistEditor_MainView").height(ViewUtils.getSuggestedHeight("PlaylistEditor_MainView"));

        v_editorContainer.applicationCreated();
    };

    this.destroy = function() {
        v_editorContainer.destroy();
        $("#" + v_viewId).remove();
        $(document).off("keydown", keyPressed);
        $(window).off("resize", onWindowResize);
    };

    this.fullRefresh = function() {
        v_editorContainer.fullRefresh();
        v_this.toggleButtons(true);
        v_this.updatePlaylistName();
        v_focused_obj = undefined;
    };

    ///////////////////// EVENT HANDLING FUNCTIONS //////////////////////////////

    function keyPressed(event) {
        if(event.keyCode === 46 && v_focused_obj != undefined && v_focused_obj.deletePressed != undefined) {
            v_focused_obj.deletePressed();
        }

        if(event.keyCode === 83 && event.ctrlKey == true && $("#PlaylistEditor_Button_Save").attr("disabled") != true) {
            savePlaylist();
            event.preventDefault();
            event.stopPropagation();
        }
    }

    function newPlaylist() {
        v_this.toggleButtons(false);
        v_viewmodel.newPlaylist();
        v_this.fullRefresh();
    }

    function deletePlaylist(value) {
        var text = "Are you sure your want to delete " + value + "?";
        if (v_viewmodel.currentlyEdited() == value) {
            text += "<br><b>Warning! This is currently oepn!</b>";
        }

        function playlistDeleted(ok) {
            if (!ok) {
                alert("Failed to delete " + value);
            }
            v_this.updatePlaylistName();
            loadPlaylist();
        }

        var dialog = new ConfirmationDialog(v_viewId, "PlaylistEditor_Dialog_DeletePlaylist", {
            "header": "Delete",
            "text": text,
            "callback": function() {
                v_viewmodel.deletePlaylist(value, playlistDeleted);
            }
        });
        dialog.open();
    }

    function loadPlaylist() {
        function gotPlaylistName(p_Playlist) {
            v_this.toggleButtons(false);
            v_viewmodel.loadPlaylist(p_Playlist, function callback(ok) {
                if (!ok) {
                    alert("Loading failed");
                }
                v_this.fullRefresh();
            });
        }

        function optionsArrived(options) {
            var dialog = new ChoiceDialogWithButton(v_viewId, "PlaylistEditor_Dialog_LoadPlaylist", {
                "header": "Load",
                "text": "Please select an entry from the table below.",
                "choices": options,
                "callback": gotPlaylistName,
                "buttonHandler": deletePlaylist,
                "buttonText": "X",
                "buttonStyle": "color: red;",
                "closeOnButtonPress": true
            });
            dialog.open();
        }

        v_viewmodel.listPlaylists(optionsArrived);
    }

    function savePlaylist() {
        function playlistSaved(ok) {
            if (!ok) {
                alert("Failed to save " + v_viewmodel.currentlyEdited());
            }
            v_this.toggleButtons(true);
        }

        if (v_viewmodel.currentlyEdited() != undefined) {
            v_this.toggleButtons(false);
            v_viewmodel.savePlaylist(playlistSaved);
        } else {
            savePlaylistAs();
        }
    }

    function savePlaylistAs() {
        var groupName;
        var newPlaylistName;

        function PlaylistSaved(ok) {
            if (!ok) {
                alert("Failed to save " + newPlaylistName);
            }
            v_this.updatePlaylistName();
            v_this.toggleButtons(true);
        }

        function gotPlaylistName(value) {
            newPlaylistName = value;
            v_viewmodel.playlistExists(groupName, newPlaylistName, function(exists) {
                if (exists) {
                    var confirmDialog = new ConfirmationDialog(v_viewId, "PlaylistEditor_Dialog_OverWrite", {
                        "header": "Already exists",
                        "text": "Overwrite?",
                        "callback": function() {
                            v_this.toggleButtons(false);
                            v_viewmodel.savePlaylistAs(groupName, newPlaylistName, PlaylistSaved);
                        }
                    });
                    confirmDialog.open();
                } else {
                    v_this.toggleButtons(false);
                    v_viewmodel.savePlaylistAs(groupName, newPlaylistName, PlaylistSaved);
                }
            });
        }

        var date = new Date();
        var dialog = new InputDialog(v_viewId, "PlaylistEditor_Dialog_SavePlaylistAs", {
            "header": "Save As...",
            "text": "Please enter the new name.",
            "defaultValue": "" + date.getFullYear() + "-" + mpad((date.getMonth() + 1), 2) + "-" + mpad(date.getDate(), 2) + "_" + mpad(date.getHours(), 2) + "-" + mpad(date.getMinutes(), 2) + "-" + mpad(date.getSeconds(), 2),
            "validator": function(value) {
                var error = "";
                var pattern = /^([A-Za-z0-9-_.])+$/;
                if (!pattern.test(value))
                    error += "The name can only con&shy;tain upper and lower case eng&shy;lish let&shy;ters, num&shy;bers, under&shy;scores, dots and dashes!";
                if (error.length > 0)
                  error += "<br/>";
                if (value.length > 132)
                    error += "The name is too long (max. 132 char&shy;ac&shy;ters allo&shy;wed)!";
                return error;
            },
            "callback": gotPlaylistName
        });

        function optionsArrived(options) {
            new ChoiceDialog(v_viewId, "PlaylistEditor_Dialog_SelectGroup", {
                "header": "Select group",
                "text": "Please select a group from the table below.",
                "choices": options,
                "callback": function(p_groupName) {
                    groupName = p_groupName;
                    dialog.open();
                }
            }).open();
        }

        v_viewmodel.listGroups(optionsArrived);
    }

    ///////////////////// USEFUL FUNCTION FOR VIEWS //////////////////////////////

    this.toggleButtons = function(on) {
        $(".PlaylistEditor_Button_Left").prop("disabled", !on);
        $(".PlaylistEditor_Button_Right").prop("disabled", !on);
    };

    this.setFocusedObj = function(p_object) {
        if (v_focused_obj != undefined) {
            v_focused_obj.setDefaultZidx();
        }
        if (p_object != undefined) {
            p_object.setZidx();
        }
        v_focused_obj = p_object;
    };

    this.updatePlaylistName = function() {
        var name = v_viewmodel.currentlyEdited();
        document.getElementById("PlaylistEditor_PlaylistNameLabel").innerHTML = (name == undefined ? "new playlist" : name);
    };
}
//# sourceURL=PlaylistEditor\Views\View.js
