// com.tts.initial.html5.lightbox
// HTML4 / HTML5: No differences
define(["jquery"], function (jq) {

	"use strict";

    var EventUtil = (function() {

        var isIOS = (/iphone|ipad|ipod/i.test( navigator.userAgent.toLowerCase() ) );

        function getFirstSupportedEvent(tagName, eventNames) {
            var result = "";

            jq.each(eventNames.split(" "), function (i, evtName) {
                if (isEventSupported(evtName, tagName)) {
                    result = evtName;
                    return false;
                }
            });
            return result;
        }

        function isEventSupported(eventName, tagName) {
            var elem = tagName ? document.createElement(tagName) : document,
                onEventName = "on" + eventName,
                isSupported;

            isSupported = !!(onEventName in elem);
            if (!isSupported && typeof elem.setAttribute !== "undefined") {
                elem.setAttribute(onEventName, "return;");
                isSupported = typeof elem[onEventName] === "function";
            }

            return isSupported;
        }

        return {
            /**
             * Attach the event handler <b>handler</b> for the first supported event specified by <b>eventNames</b>
             * to the element <b>jqObject</b>.
             * Example: attachFirstSupportedEvent( myObject, "pointerdown mousedown touchend", myHandler );
             *
             * @param element
             * @param {String} eventNames
             * @param handler
             * @return {String} the event name or ""
             */
            attachFirstSupportedEvent: function (element, eventNames, handler) {
                var jqObject = jq(element),
                    evtName = getFirstSupportedEvent(element.nodeName, eventNames);

                if (!evtName) {
                    return "";
                }

                jqObject.on(evtName, handler);
                return evtName;
            },

            /**
             * Remove attached event handler <b>handler</b> for the first supported event specified by <b>eventNames</b>
             * from the element <b>jqObject</b>.
             * Example: removeFirstSupportedEvent( myObject, "pointerdown mousedown touchend", myHandler );
             *
             * @param element
             * @param {String} eventNames
             * @param handler
             * @return {String} the event name or ""
             */
            removeFirstSupportedEvent: function (element, eventNames, handler) {
                var jqObject = jq(element),
                    evtName = getFirstSupportedEvent(element.nodeName, eventNames);

                if (!evtName) {
                    return "";
                }

                jqObject.off(evtName, handler);
                return evtName;
            },

            getPointerDownEvent: function( element ) {
                if( !isIOS ) {
                    return getFirstSupportedEvent( element.nodeName, "pointerdown mousedown touchstart" );
                }

                // iOS 9.3 unterstützt zwar click und mouseup, weshalb sich auf diese Events attached wird, aber sie werden
                //  aus unbekannten Gründen nicht gesendet.
                return "touchstart";
            },

            getPointerUpEvent: function( element ) {

                if( !isIOS ) {
                    return getFirstSupportedEvent( element.nodeName, "click pointerup mouseup touchend" );
                }

                // iOS 9.3 unterstützt zwar click und mouseup, weshalb sich auf diese Events attached wird, aber sie werden
                //  aus unbekannten Gründen nicht gesendet.
                return "touchend";
            }
        };
    })();

	/**
	 * @constructor
	 */
	return function (context, metadata) {

		var shell = null,
            lightbox = null,
            originalWidth = 1024,
            originalHeight = 683,
            width = 300,
            height,
            imageFilename,
            image,
            hover,
            lightboxWrapper,
            lightboxClose,
            lightboxImg,
            hoverColor,
            hoverTransparency,
            lightboxColor,
            lightboxTransparency,
            lightboxPercentage,
            padding,
            closeColor,
            closeHoverColor,
            clickArea,
            lightboxImgHeight,
            lightboxImgWidth;

		// sets private variables to initial parameter values
		function initializeParameters(parameters) {
            width = parameters.asNumber("wrapperWidth", "300");
            hoverColor = hexToRgb(parameters.get("hoverColor", null));
            hoverTransparency = (parameters.asNumber("hoverTransparency", "50"));
            lightboxColor = parameters.get("lightboxColor", null);
            lightboxTransparency = (parameters.asNumber("lightboxTransparency", "90"));
            lightboxPercentage = (parameters.asNumber("lightboxPercentage", "80")) / 100;
            padding = parameters.asNumber("padding", "100");
            closeColor = hexToRgb(parameters.get("closeColor", null));
            closeHoverColor = hexToRgb(parameters.get("closeHoverColor", null));

            var pic = parameters.get("picture", null);
            if (pic) {
                imageFilename = context.stage.getSharedPath() + pic.fileName;
                originalWidth = pic.width;
                originalHeight = pic.height;
            }
            else {
                imageFilename = context.getPath() + "lightbox.jpg";
            }

            if (originalWidth === 0) {
                if (console) {
                        console.log("Unexpected width! Picture width is zero!");
                }
                height = 0;
            } else {
                height = (width / originalWidth) * originalHeight;
            }


		}

        function hexToRgb(hex) {
			var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
			return result ? {
				r: parseInt(result[1], 16),
				g: parseInt(result[2], 16),
				b: parseInt(result[3], 16)
			} : {
				r: 0,
				g: 0,
				b: 0
			};
		}

        function asRgbaValue( colorValue, transparencyValue ) {

            var color = hexToRgb( colorValue ),
                alpha = asAlpha( transparencyValue );

            return "rgba(" + color.r + ", " + color.g + ", " + color.b + ", " + alpha + ")";
        }

        function asAlpha( percentValue ) {
            return (100 - percentValue) / 100;
        }

		function createMarkup() {

            shell = jq(context.getElement())
                .css({
                    "width": width + "px",
                    "height": height + "px"
                });

            // if we are in authoring mode, create an object shield so we are able to select and drag element
            if (context.stage.isInAuthoringMode()) {
                shell.append(
                    jq(document.createElement("div"))
                        .css({
                            "position": "absolute",
                            "left": 0,
                            "background-color": "#fff",
                            "opacity": "0.4",
                            "width": width + "px",
                            "height": height + "px",
                            "z-index": "9999"
                        })
                );
            }
            image = createImage();
            hover = createHover();
            lightbox = createLightbox();
            clickArea = createClickArea();

            jq(context.getPositioningElement()).parent().append(lightbox);

            shell.append(image).append(hover).append(clickArea);

		}

		function createImage() {
            return jq(document.createElement("img"))
                .attr({
                    "id" : "Img" + metadata.getId(),
                    "src" : imageFilename
                })
                .css({
                    "position" : "absolute",
                    "width" : width + "px",
                    "height": height + "px"
                })
        }

        function createHover() {
            return jq(document.createElement("div"))
                .attr({
                    "id" : "ImgHover" + metadata.getId(),
                })
                .css({
                    "position" : "absolute",
                    "display" : "block",
                    "width" : width + "px",
                    "height": height + "px",
                    "background-color" : "rgb(" + hoverColor.r + ", " + hoverColor.g + ", " + hoverColor.b + ")",
                    "opacity" : "0.0",
                    "-webkit-transition" : "opacity 0.4s ease",
                    "-moz-transition" : "opacity  0.4s ease",
                    "-o-transition" : "opacity  0.4s ease",
                    "transition" : "opacity  0.4s ease"
                })
		}

        function createLightbox(){
            lightbox = jq(document.createElement("div"))
                .attr({
                    "id" : "lightboxContent" + metadata.getId()
                })
                .css({
                    "display" : "none",
                    "position" : "relative",
                    "z-index" : "999",
                    "text-align" : "center",
                    "left" : "0",
                    "top" : "0",
                    "width" : "100%",
                    "height" : "100%",
                    "overflow" : "auto",
                    "background-color" : asRgbaValue(lightboxColor, lightboxTransparency),
                    "opacity" : "0.0",
                    "-webkit-transition" : "opacity  0.4s ease",
                    "-moz-transition" : "opacity  0.4s ease",
                    "-o-transition" : "opacity  0.4s ease",
                    "transition" : "opacity  0.4s ease"
                });

                lightboxWrapper = jq(document.createElement("div"))
                .attr({
                    "id" : "lightboxWrapper" + metadata.getId()
                })
                .css({
                    "display" : "table-cell",
                    "position" : "absoulte",
                    "left" : "0",
                    "top" : "0",
                    "width" : "100%",
                    "height" : "100%",
                    "vertical-align" : "middle"
                });

                lightboxClose = jq(document.createElement("div"))
                    .attr({
                        "id" : "lightboxClose" + metadata.getId()
                    })
                    .css({
                        "position" : "absolute",
                        "right" : "15px",
                        "top" : "15px",
                        "color" : "rgb(" + closeColor.r + ", " + closeColor.b + ", " + closeColor.b + ")",
                        "font-size" : "40px",
                        "font-weight" : "bold",
                        "cursor" : "pointer",
                        "-webkit-transition" : "color  0.4s ease",
                        "-moz-transition" : "color  0.4s ease",
                        "-o-transition" : "color  0.4s ease",
                        "transition" : "color  0.4s ease"
                    })
                    .html('&times;');

                if(width >= height) {
                    lightboxImgWidth = (metadata.stage.getWidth() * lightboxPercentage) - (2 * padding);
                    lightboxImgHeight = lightboxImgWidth * (height / width);
                }else{
                    lightboxImgHeight = (metadata.stage.getHeight() * lightboxPercentage) - (2 * padding);
                    lightboxImgWidth = lightboxImgHeight * (width / height);
                }

                lightboxImg = jq(document.createElement("img"))
                    .attr({
                        "id" : "lightboxImg" + metadata.getId(),
                        "src" : imageFilename
                    })
                    .css({
                        "width" : lightboxImgWidth + "px",
                        "height" : lightboxImgHeight + "px"
                    });

            var pointerUpEventName = EventUtil.getPointerUpEvent( lightboxClose.get(0) );
            EventUtil.attachFirstSupportedEvent( lightboxClose, pointerUpEventName, closelightbox );
            EventUtil.attachFirstSupportedEvent( lightboxClose, "pointermove mousemove", showlightboxCloseHover );
            EventUtil.attachFirstSupportedEvent( lightboxClose, "pointerout mouseout", hidelightboxCloseHover );
            lightboxWrapper.append ( lightboxImg );
            lightbox.append( lightboxWrapper );
            lightbox.append( lightboxClose );
            return lightbox;
		}

		function createClickArea(){
            clickArea = jq(document.createElement("div"))
                .attr("id", "clickArea" + metadata.getId())
                .width(width + "px")
                .height(height + "px")
                .css({
                    "position" : "absolute",
                    "cursor" : "pointer",
                    "display" : "block"
                });

            var pointerUpEventName = EventUtil.getPointerUpEvent( clickArea.get(0) );
            EventUtil.attachFirstSupportedEvent( clickArea, pointerUpEventName, openlightbox );
            EventUtil.attachFirstSupportedEvent( clickArea, "pointermove mousemove", showImageHover );
            EventUtil.attachFirstSupportedEvent( clickArea, "pointerout mouseout", hideImageHover );

            return clickArea;
        }

        function showlightboxCloseHover() {
            lockNavigation();
            lightboxClose.css({
                "color" : "rgb(" + closeHoverColor.r + ", " + closeHoverColor.b + ", " + closeHoverColor.b + ")"
            })
        }

        function hidelightboxCloseHover() {
            unlockNavigation();
            lightboxClose.css({
                "color" : "rgb(" + closeColor.r + ", " + closeColor.b + ", " + closeColor.b + ")"
            })
        }

        function showImageHover() {
            lockNavigation();
            hover.css({
                "opacity" : asAlpha(hoverTransparency)
            })
        }

        function hideImageHover() {
            unlockNavigation();
            hover.css({
                "opacity" : "0.0"
            })
        }

        function openlightbox(e) {
            lockNavigation();
            lightbox.css({
                "display" : "table",
                "opacity" : "1.0"
            })
        }

        function closelightbox(e) {
            unlockNavigation();
            lightbox.css({
                "display" : "none",
                "opacity" : "0.0"
            })
        }

		function lockNavigation() {
            if (context.stage.isInAuthoringMode() || (!context.stage.trigger)) {
                return;
            }

            context.stage.trigger.lock(metadata.getId());
		}

		function unlockNavigation() {
            if (context.stage.isInAuthoringMode() || (!context.stage.trigger)) {
                return;
            }

            context.stage.trigger.unlock(metadata.getId());
		}

		// revealing public API
		return {
			// declare public members
			onLoading: function () {
                context.page.event.bindOnExit(this);

				initializeParameters(metadata.parameters);

				createMarkup();
			},

            onExitPage: function () {
                closelightbox();
			}
		};
	};
});

