﻿/* globals
    jQuery, CsLogger, anime
 */
/* exported
 */
"use strict";
; (function ($, window, document, undefined) {

    // default settings.
    var _pluginName = "gallery2";
    var _defaultsOptions = {
        debug: false,
    };
    var _logger = new CsLogger(_pluginName);

    // constructor.
    function Gallery2(element, options) {
        this._element = element;

        // $.extend to store user provided options.
        this._options = $.extend({}, _defaultsOptions, options);
        this._defaultOptions = _defaultsOptions;
        this._name = _pluginName;
        this.init();
    }

    // (void) ensure the selected element is valid.
    function validateElement(element) {
        _logger.log("validateElement()");
        if (element == undefined || $(element).length == 0) {
            _logger.error("selected element is not valid.");
            return;
        }
    }

    // (void) validate the options passed into the plugin.
    function validateOptions(options) {
        if (typeof (options.debug) == "boolean" && options.debug == true) {
            _logger.enable();
        }
        _logger.obj("validateOptions() | opts:", options);
    }

    // void set up enlarge image modal
    function setupModel(element) {

        // get the modal
        var modal = $(element).find("#enlargeModal");

        // get all image elements
        var btnImg = $(element).find('.slick-slide');

        // ** Detect dragging and is current image **
        // this is so the model doesn't pop up when it shouldn't        
        // we only want the modal to pop up if the image is current
        // and the users is not dragging.
        var isDragging = false;
        var moveCount = 0;
        var isCurrent = false;

        $(btnImg).on("mousedown", function () {
            console.log("mousedown");
            moveCount = 0;
            isDragging = false;
            isCurrent = $(this).hasClass("slick-current");
        })
            .on("mousemove", function () {
                isDragging = true;
                moveCount++;
            }).on("mouseup", function () {
                if (isCurrent && (!isDragging || moveCount < 5)) {
                    // get the index for the image
                    var idx = Number($(this).find("img")[0].attributes.getNamedItem("data-idx").value);
                    idx = isNaN(idx) ? 0 : idx;

                    // show the slide that matches the image clicked
                    showSlides(_slideIndex = idx + 1);

                    // show the enlarge image modal
                    $(modal).css("display", "block");
                }
            });

        // get the <span> element that closes the modal
        var btnClose = $(modal).find(".close");
        var btnNext = $(modal).find(".next");
        var btnPrev = $(modal).find(".prev");

        // when the user clicks on (x), close the modal
        $(btnClose).on("click", function () {
            $(modal).css("display", "none");
        });

        $(document).keyup(function (e) {
            if (e.key === "Escape") { // escape key maps to keycode `27`
                $(modal).css("display", "none");
            }
        })

        // when the user clicks on (>), got to the next image
        $(btnNext).on("click", function () {
            showSlides(_slideIndex += 1);
        });

        // when the user clicks on (<), go to the previous image
        $(btnPrev).on("click", function () {
            showSlides(_slideIndex -= 1);
        });

        // global slide index
        var _slideIndex = 1;

        // shows and hides slides based on the current slide index
        function showSlides(n) {
            // get all slides
            var slides = $(modal).find(".mySlides");

            // this will reset the slide index when the prev or next 
            // buttons reach the end of the loop on each end.
            if (n > slides.length) { _slideIndex = 1 }
            if (n < 1) { _slideIndex = slides.length }

            // hide all slides currently visible
            for (var i = 0; i < slides.length; i++) {
                $(slides[i]).css("display", "none");
            }

            // get the new current slide from the collection
            var currentSlide = slides[_slideIndex - 1];

            // add the correct caption
            var caption = currentSlide.firstElementChild.attributes.getNamedItem("alt").value;
            var captionText = $(modal).find("#caption");
            $(captionText).text(caption);

            // show the current slide
            $(currentSlide).css("display", "block");
        }
    }

    // (void) bind handlers.
    function bindControls(element) {
        _logger.log("bindControls()");

        $(element).find(".main-carousel").slick({
            centerMode: true,
            infinite: true,
            slidesToShow: 2,
            slidesToScroll: 1,
            focusOnSelect: true,
            arrows: true,
            variableWidth: true,
            responsive: [
                {
                    breakpoint: 1024,
                    settings: {
                        centerMode: true,
                        slidesToShow: 1,
                        slidesToScroll: 1,
                    }
                }
                // You can unslick at a given breakpoint now by adding:
                // settings: "unslick"
                // instead of a settings object
            ]
        });
    }

    // prototype extensions.
    Gallery2.prototype = {

        // (void) initialise.
        init: function () {
            validateOptions(this._options);
            validateElement(this._element);
            _logger.log("init()");

            bindControls(this._element);
            setupModel(this._element);
        }
    };

    // A really lightweight plugin wrapper around the constructor,
    // preventing against multiple instantiations
    $.fn[_pluginName] = function (options) {
        return this.each(function () {
            if (!$.data(this, "plugin_" + _pluginName)) {
                $.data(this, "plugin_" + _pluginName,
                    new Gallery2(this, options));
            }
        });
    };

})(jQuery, window, document);