define( [
    "./dialog.button.builder",
    "jquery"
],
    function (
        DialogButtonBuilder,
        jq
    ) {

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

            var dialog,
                closeDialog,
                isVisible = false,
                noButton,
                yesButton;

            function createDialog() {
                closeDialog = jq( document.createElement( "div" ) )
                    .attr( {
                        "id": "closeDialog" + options.Id
                    } )
                    .css( {
                        "width": options.dialog.width + "px",
                        "height": options.dialog.height + "px",
                        "background-color": options.dialog.dialog.backgroundColor,
                        "color": options.text.fontColor,
                        "font-family": options.text.fontFamily,
                        "font-size": options.text.fontSize + "px",
                        "font-weight": "normal",
                        "font-style": "normal",
                        "padding-left": options.text.paddingLeft + "px",
                        "padding-right": options.text.paddingRight + "px",
                        "padding-top": options.text.paddingTop + "px",
                        "text-align": options.text.horizontalAlign,
                        "box-sizing": "border-box",
                        "border": ( options.dialog.border.width > 0 ) ? options.dialog.border.width + "px solid " + options.dialog.border.backgroundColor : "0",
                        "position": "absolute",
                        "top": "50%",
                        "left": "50%",
                        "transform": "translate( -50%, -50%)"
                    } )
                    .html( options.text.text );

                dialog = jq( document.createElement( "div" ) )
                    .attr( {
                        "id": "dialog" + options.Id
                    } )
                    .css( {
                        "background-color": options.dialog.cover.backgroundColor,
                        "top": "0px",
                        "left": "0px",
                        "width": options.stageSize.width + "px",
                        "height": options.stageSize.height + "px",
                        "position": "absolute",
                        "cursor": "auto",
                        "z-index": "999"
                    } );

                noButton = new DialogButtonBuilder( {
                    image: options.noButton.image,
                    name: "noButton",
                    label: options.noButton.label,
                    ariaLabel: options.noButton.ariaLabel,
                    fontColor: options.noButton.label.fontColor,
                    fontColorHover: options.noButton.label.fontColorHover,
                    fontColorPressed: options.noButton.label.fontColorPressed,
                    showLabel: options.noButton.showLabel,
                    action: function () {
                        dialog.hide();
                    },
                    css: {
                        "box-sizing": "border-box",
                        "cursor": "pointer",
                        "position": "absolute",
                        "bottom": "10px",
                        "left": "10px"
                    },
                    accessibilityKey: options.accessibilityKeys.no,
                    accessibilityLocation: options.accessibilityKeys.accessibilityLocation,
                    accessibilityPositionX: options.accessibilityKeys.accessibilityPositionX,
                    accessibilityPositionY: options.accessibilityKeys.accessibilityPositionY
                }, context, metadata ).build();
                yesButton = new DialogButtonBuilder( {
                    image: options.yesButton.image,
                    name: "yesButton",
                    label: options.yesButton.label,
                    ariaLabel: options.yesButton.ariaLabel,
                    fontColor: options.yesButton.label.fontColor,
                    fontColorHover: options.yesButton.label.fontColorHover,
                    fontColorPressed: options.yesButton.label.fontColorPressed,
                    showLabel: options.yesButton.showLabel,
                    action: function () {
                        context.stage.navigation.terminate();
                    },
                    css: {
                        "box-sizing" : "border-box",
                        "cursor" : "pointer",
                        "position" : "absolute",
                        "bottom" : "10px",
                        "right" : "10px"
                    },
                    accessibilityKey: options.accessibilityKeys.yes,
                    accessibilityLocation: options.accessibilityKeys.accessibilityLocation,
                    accessibilityPositionX: options.accessibilityKeys.accessibilityPositionX,
                    accessibilityPositionY: options.accessibilityKeys.accessibilityPositionY
                }, context, metadata ).build();

                if ( options.text.bold ) { closeDialog.css( { "font-weight": "bold" } ) };
                if ( options.text.italic ) { closeDialog.css( { "font-style": "italic" } ) };
                if ( options.text.underline ) { closeDialog.css( { "text-decoration": "underline" } ) };

                closeDialog.append( noButton.getElement() );
                closeDialog.append( yesButton.getElement() );

                dialog.append( closeDialog );
                dialog.hide();
                isVisible = false;
            }

            function lockNavigation() {
                if ( options.isInAuthoringMode || !options.hasStageTriggerSupport ) {
                    return;
                }
                context.stage.trigger.lock( metadata.getId() );
            }

            function unlockNavigation() {
                if ( options.isInAuthoringMode || !options.hasStageTriggerSupport ) {
                    return;
                }
                context.stage.trigger.unlock( metadata.getId() );
            }

            function bindEvents() {

                if ( context.stage.isInAuthoringMode() ) {
                    return;
                }

                removeEvents();

                context.page.interaction.provokesFeedback( dialog, false );
                context.page.interaction.provokesAutosolve( dialog, false );
                context.page.interaction.provokesFeedback( closeDialog, false );
                context.page.interaction.provokesAutosolve( closeDialog, false );
                context.page.interaction.provokesFeedback( noButton.getElement(), false );
                context.page.interaction.provokesAutosolve( noButton.getElement(), false );
                context.page.interaction.provokesFeedback( yesButton.getElement(), false );
                context.page.interaction.provokesAutosolve( yesButton.getElement(), false );

                context.device.attachFirstSupportedEvent( dialog, options.pointerDownEventName, cancelEvent);
                context.device.attachFirstSupportedEvent( dialog, options.pointerUpEventName, cancelEvent );

                context.device.attachFirstSupportedEvent( closeDialog, options.pointerDownEventName, cancelEvent );
                context.device.attachFirstSupportedEvent( closeDialog, options.pointerUpEventName, cancelEvent );

                context.device.attachFirstSupportedEvent( noButton.getElement(), options.pointerDownEventName, noButton.onMouseDown );
                context.device.attachFirstSupportedEvent( noButton.getElement(), options.pointerMoveEventNames, noButton.onMouseOver );
                context.device.attachFirstSupportedEvent( noButton.getElement(), options.pointerLeaveEventNames, noButton.onMouseLeave );
                context.device.attachFirstSupportedEvent( noButton.getElement(), options.pointerUpEventName, noButton.onMouseUp );

                context.device.attachFirstSupportedEvent( yesButton.getElement(), options.pointerDownEventName, yesButton.onMouseDown );
                context.device.attachFirstSupportedEvent( yesButton.getElement(), options.pointerMoveEventNames, yesButton.onMouseOver );
                context.device.attachFirstSupportedEvent( yesButton.getElement(), options.pointerLeaveEventNames, yesButton.onMouseLeave );
                context.device.attachFirstSupportedEvent( yesButton.getElement(), options.pointerUpEventName, yesButton.onMouseUp );
            }

            function removeEvents() {
                unlockNavigation();

                context.device.removeFirstSupportedEvent( dialog, options.pointerDownEventName, cancelEvent );
                context.device.removeFirstSupportedEvent( dialog, options.pointerUpEventName, cancelEvent );

                context.device.removeFirstSupportedEvent( closeDialog, options.pointerDownEventName, cancelEvent );
                context.device.removeFirstSupportedEvent( closeDialog, options.pointerUpEventName, cancelEvent );

                context.device.removeFirstSupportedEvent( noButton.getElement(), options.pointerDownEventName, noButton.onMouseDown );
                context.device.removeFirstSupportedEvent( noButton.getElement(), options.pointerMoveEventNames, noButton.onMouseOver );
                context.device.removeFirstSupportedEvent( noButton.getElement(), options.pointerLeaveEventNames, noButton.onMouseLeave );
                context.device.removeFirstSupportedEvent( noButton.getElement(), options.pointerUpEventName, noButton.onMouseUp );

                context.device.removeFirstSupportedEvent( yesButton.getElement(), options.pointerDownEventName, yesButton.onMouseDown );
                context.device.removeFirstSupportedEvent( yesButton.getElement(), options.pointerMoveEventNames, yesButton.onMouseOver );
                context.device.removeFirstSupportedEvent( yesButton.getElement(), options.pointerLeaveEventNames, yesButton.onMouseLeave );
                context.device.removeFirstSupportedEvent( yesButton.getElement(), options.pointerUpEventName, yesButton.onMouseUp );
            }

            function cancelEvent( e ) {
                if ( e && e.preventDefault ) {
                    e.preventDefault();
                }

                if ( e && e.stopPropagation ) {
                    e.stopPropagation();
                }

                return false;
            }

            return {
                build: function () {
                    createDialog();
                    return {
                        getElement: function () {
                            return dialog.get( 0 );
                        },
                        getAccessibilityKeyCodes: function () {
                            return {
                                yesButton: yesButton.getAccessibilityKeyCode(),
                                noButton: noButton.getAccessibilityKeyCode()
                            }
                        },
                        onMouseLeave: function () {
                            unlockNavigation();
                            changeState( ButtonState.Default );
                        },
                        onMouseOver: function () {
                            changeState( ButtonState.Hover );
                        },
                        onMouseDown: function ( e ) {
                            lockNavigation();
                            cancelEvent( e );
                            changeState( ButtonState.Pressed );
                        },
                        onMouseUp: function ( e ) {
                            unlockNavigation();
                            cancelEvent( e );
                            changeState( ButtonState.Hover );
                        },
                        showDialog: function () {
                            dialog.show();
                            isVisible = true;
                        },
                        hideDialog: function () {
                            dialog.hide();
                            isVisible = false;
                        },
                        isVisible: function () {
                            return isVisible;
                        },
                        bindEvents: function () {
                            bindEvents();
                        },
                        removeEvents: function () {
                            removeEvents();
                        },
                        showAccessibilityTooltips: function () {
                            yesButton.showAccessibilityTooltip();
                            noButton.showAccessibilityTooltip();
                        },
                        hideAccessibilityTooltips: function () {
                            yesButton.hideAccessibilityTooltip();
                            noButton.hideAccessibilityTooltip();
                        }
                    }
                }
            }
        };
    } );
