(function($) {

    // "global" variables
    var ApiUrl = "index.php?P=AMSER--JsonApi";
    var ResourceId = G_ResourceId;  // G_ResourceId in AMSER--ResourceFrame.php

    // used to apply certain actions to all Get* functions
    function GetValue(obj) {
        return $.trim($(obj).val());
    };

    // execute when the document has fully loaded
    $(document).ready(function(){
        // init object variables
        var $TopFrame = $("#top-frame");
        var $FrameSeparator = $("#frame-separator");
        var $RemoveFrame = $("#top-frame .actions .remove-frame a");
        var $AddResource = $("#top-frame .actions .add-to-folder");
        var $RemoveResource = $("#top-frame .actions .remove-from-folder");
        var $DoLogin = $("#top-frame .actions .login");
        var $Modals = $(".modal");
        var $ModalInputs = $("input[type=text], input[type=password], textarea", $Modals);
        var $NoteModal = $("#note");
        var $Note = $("#note .text");
        var $AddNote = $("#note .buttons .add-note");
        var $AddNoteCancel = $("#note .buttons .dont-add-note");
        var $LoginModal = $("#login");
        var $Username = $("#login .username");
        var $Password = $("#login .password");
        var $Login = $("#login .buttons .login");
        var $LoginCancel = $("#login .buttons .cancel");

        // center the modals when first loaded
        centerModals();

        // re-center all modals when the window is resized
        $(window).resize(function(){  centerModals();  });

        // slide up top frame when removing it
        $RemoveFrame.click(function(){
            // close all modals
            closeModals();

            // and slide up top frame/frame separator
            var $obj = $(this);
            $.combine($TopFrame, $FrameSeparator).slideUp("fast", function(){
                window.location = $obj.attr("href");
            });

            return false;
        });

        // add the resource to the current folder
        $AddResource.click(function(){
            closeModals();

            // send ajax request to the API
            ApiRequest({
                "method": "resource.addToFolder",
                "resourceId": ResourceId
            }, function(data){
                if (data.status.state == "OK") {
                    // show "remove from folder"
                    toggleResourceLinks(-1);

                    // show note modal if successful
                    $NoteModal.fadeIn(200);
                    $Note.focus();
                } else {
                    alert(data.status.message);
                }
            });

            return false;
        });

        // remove the resource from the current folder
        $RemoveResource.click(function(){
            closeModals();

            // send ajax request to the API
            ApiRequest({
                "method": "resource.removeFromFolder",
                "resourceId": ResourceId
            }, function(data){
                if (data.status.state == "OK") {
                    // show "add to folder"
                    toggleResourceLinks(1);
                } else {
                    alert(data.status.message);
                }
            });

            return false;
        });

        // show the login modal when clicking the "log in..." link (if hidden)
        $DoLogin.click(function(){
            if ($LoginModal.is(":hidden")) {
                $LoginModal.fadeIn(200, function(){  $Username.focus();  });
            }
            return false;
        });

        // close modals when esc key is pressed in a modal input
        $ModalInputs.keydown(function(e){
            if ((e.which && e.which == 27) || (e.keyCode && e.keyCode == 27)) {
                closeModals();
            }
        });

        // disable "Login" button until valid input received
        $.combine($Username, $Password).onvaluechange(function(){
            $Login.buttonToggle(function(){
                return (GetUsername().length > 0 && GetPassword().length > 0);
            });
        });

        // trigger the login button if enter is pressed within a login input
        $.combine($Username, $Password).keydown(function(e){
            if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
                $Login.click();
            }
        });

        // login canceled: close modals and revert login text
        $LoginCancel.click(function(){
            closeModals(function(){  $Login.html("Login");  });
        });

        // log user in when the login button is pressed
        $Login.click(function(){
            var username = GetUsername();
            var password = GetPassword();

            // reduce useless ajax requests: require length > 0
            if (username.length > 0 && password.length > 0) {
                // let user know they're being logged in
                $Login.html("Logging In...");
                $Login.attr("disabled", true);

                // send ajax request to the API
                ApiRequest({
                    "method": "user.login",
                    "username": username,
                    "password": password
                }, function(data){
                    if (data.status.state == "OK") {
                        // reload page on successful login
                        location.reload(true);
                        closeModals(function(){  $Login.html("Logged In");  });
                    } else {
                        alert(data.status.message);
                        $Login.html("Try Again");
                        $Login.attr("disabled", false);
                    }
                }, null, "POST");
            }
        });

        // disable "AddNote" button until valid input received
        $Note.onvaluechange(function(){
            $AddNote.buttonToggle(function(){ return (GetNote().length > 0); });
        });

        // add note to resource
        $AddNote.click(function(){
            // reduce useless ajax requests: require note length > 0
            var note = GetNote();
            if (note.length > 0) {
                // let user know it's saving
                $AddNote.html("Saving Note...");
                $AddNote.attr("disabled", true);

                // send ajax request to the API
                ApiRequest({
                    "method": "resource.updateNote",
                    "resourceId": ResourceId,
                    "note": note
                }, function(data){
                    if (data.status.state != "OK") {
                        alert(data.status.message);
                    }
                }, function(){
                    // close modals, revert button
                    closeModals(function(){
                        $AddNote.html("Add Note");
                        $AddNote.attr("disabled", false);
                    });
                });
            }
        });

        // close modals when the user cancels adding a note
        $AddNoteCancel.click(function(){  closeModals();  });

        /** Helper Functions **/

        // close all modals, clear their text inputs, and disable buttons
        function closeModals(done) {
            $Modals.fadeOut(100, function(){
                $ModalInputs.val("");
                $.combine($AddNote, $Login).attr("disabled", true);
                if ($.isFunction(done)) {  setTimeout(done, 120);  } // delay
            });
        };

        // center all modals
        function centerModals() {
            // get window height/width once per call
            var winHeight = $(window).height();
            var winWidth = $(window).width();

            // center each modal
            $Modals.each(function(){
                var $modal = $(this);

                // offset top higher than center if it's not too close to top
                var height = $modal.height();
                var top = winHeight-height-150;
                if (top - 50 < 0) {  top = winHeight - height;  }

                // position modal
                $modal.css({
                    "position": "absolute",
                    "top": Math.round(top/2)+"px",
                    "left": Math.round((winWidth - $modal.width())/2)+"px"
                });
            });
        };

        // toggle the add/remove resource links
        function toggleResourceLinks(value) {
            var effect = function($show, $hide){
                $hide.hide(75, function(){  $show.show(75);  });
            };

            if (value == -1) {
                // show "remove from folder"
                effect($RemoveResource, $AddResource);
            } else {
                // show "add to folder"
                effect($AddResource, $RemoveResource);
            }
        };

        // do an API request
        function ApiRequest(data, callback, complete, type) {
            $.ajax({
                "cache": false,
                "complete": ($.isFunction(complete)) ? complete : null,
                "data": data,
                "dataType": "json",
                "error": function() {
                    var message = "Failed to send data, your input was too large,"+
                        " or it is taking abnormally long for it to respond."+
                        " Please try again later.";
                    alert(message);
                },
                "success": ($.isFunction(callback)) ? callback : null,
                "timeout": 15000,
                "type": (type == "GET" || type == "POST") ? type : "GET",
                "url": ApiUrl
            });
        };

        // get input values
        function GetNote() {  return GetValue($Note);  };
        function GetUsername() {  return GetValue($Username);  };
        function GetPassword() {  return GetValue($Password);  };

    });

})(jQuery);
