<?xml version="1.0" encoding="UTF-8" standalone="no"?><addon xmlns="http://icplayer.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Single_State_Button" xsi:schemaLocation="http://icplayer.com ../../tools/addon.xsd">
	<model>
		<property isLocalized="true" name="Title" nameLabel="Single_State_Button_property_title" type="string"/>
		<property name="Image" nameLabel="Single_State_Button_property_image" type="image"/>
		<property isDefault="true" name="onClick" nameLabel="Single_State_Button_property_on_click" type="event"/>
		<property name="Disable" nameLabel="Single_State_Button_property_disable" type="boolean"/>
		<property name="Enable in error mode" nameLabel="Single_State_Button_property_enable_in_error_mode" type="boolean"/>
		<property name="Enable in show answers mode" nameLabel="Single_State_Button_property_enable_in_show_answers_mode" type="boolean"/>
		<property displayName="Render SVG as HTML" name="renderSVGAsHTML" nameLabel="Single_State_Button_property_render_SVG_as_HTML" type="boolean"/>
	</model>
<css>.singlestate-button-wrapper {
    border: 0 solid black;
    padding: 0;
    margin: 0;
}

.singlestate-button-wrapper div.svg-element {
    height: auto!important;
}

.singlestate-button-element {
    border: 0 solid black;
    padding: 0;
    margin: 0;
    background: url('resources/ssb-button.png') no-repeat center;
    cursor: pointer;
}

.singlestate-button-title,
.singlestate-button-image {
    border: 0 solid black;
    padding: 0;
    margin: 0;
    cursor: pointer;
    position: absolute;
}
</css><view>&lt;div class="singlestate-button-wrapper"&gt;
&lt;/div&gt;
</view><preview>&lt;div class="singlestate-button-wrapper"&gt;
&lt;/div&gt;
</preview><presenter>function AddonSingle_State_Button_create() {
    var presenter = function() {};

    presenter.DISPLAY_CONTENT_TYPE = {
        NONE: 0,
        TITLE: 1,
        IMAGE: 2,
        BOTH: 3
    };

    presenter.ERROR_MESSAGES = {
        INVALID_FILE: 'Invalid SVG file',
    };

    presenter.state = {
        isErrorMode: false
    };

    presenter.executeUserEventCode = function() {
        if (presenter.playerController == null) return;
        if (presenter.configuration.onClickEvent.isEmpty) return;

        presenter.playerController.getCommands().executeEventCode(presenter.configuration.onClickEvent.value);
    };

    presenter.clickHandler = function (event) {
        if (event !== undefined) {
            event.stopPropagation();
        }

        var allowClickInErrorMode = presenter.state.isErrorMode &amp;&amp; presenter.configuration.enableInErrorMode;
        if (presenter.configuration.isDisabled) return;
        if (presenter.configuration.isErrorMode &amp;&amp; !allowClickInErrorMode) return;
        if (presenter.configuration.isShowAnswersMode &amp;&amp; !presenter.configuration.enableInShowAnswersMode) return;

        presenter.executeUserEventCode();
        presenter.triggerButtonClickedEvent();
    };

    function handleMouseActions() {
        var $element = presenter.$view.find('div[class*=singlestate-button-element]:first');
        $element.click(presenter.clickHandler);
    }

    function setElementsDimensions(model, wrapper, element) {
        var viewDimensions = DOMOperationsUtils.getOuterDimensions(presenter.$view);
        var viewDistances = DOMOperationsUtils.calculateOuterDistances(viewDimensions);
        presenter.$view.css({
            width:(model.Width - viewDistances.horizontal) + 'px',
            height:(model.Height - viewDistances.vertical) + 'px'
        });

        DOMOperationsUtils.setReducedSize(presenter.$view, wrapper);
        DOMOperationsUtils.setReducedSize(wrapper, element);
    }

    function createImageElement(element) {
        $(element).removeClass('svg-element');
        if (presenter.configuration.renderSVGAsHTML) {
            $(element).addClass('svg-element');
            createSVGElement(element);
        } else {
            var $imageElement = $(document.createElement('img'));
            $imageElement.addClass('singlestate-button-image');
            $imageElement.attr('src', presenter.configuration.image);
            $(element).append($imageElement);
        }
    }

    function createTitleElement(element) {
        var $titleElement = $(document.createElement('span'));
        $titleElement.addClass('singlestate-button-title');
        $titleElement.html(presenter.configuration.title);
        $(element).append($titleElement);
    }

    function createElements(wrapper) {
        var $element = $(document.createElement('div'));
        $element.addClass('singlestate-button-element');
        if (presenter.configuration.isTabindexEnabled) {$element.attr('tabindex', '0');}

        switch (presenter.configuration.displayContent) {
            case presenter.DISPLAY_CONTENT_TYPE.TITLE:
                createTitleElement($element);

                break;
            case presenter.DISPLAY_CONTENT_TYPE.IMAGE:
                createImageElement($element);

                break;
            case presenter.DISPLAY_CONTENT_TYPE.BOTH:
                createImageElement($element);
                createTitleElement($element);

                break;
        }

        wrapper.append($element);

        return $element;
    }

    function createSVGElement(element) {
        const sanitizeUrl = window.xssUtils.sanitize(presenter.configuration.image);

        $.ajax({
            url: sanitizeUrl,
            success: function (data) {
                onSVGLoadCompleted(data, element);
            },
            error: function () {
                onSVGLoadError();
            },
            dataType: 'xml'
        });
    }

    function onSVGLoadError () {
        const errorContainer = '&lt;p&gt;' + presenter.ERROR_MESSAGES.INVALID_FILE + '&lt;/p&gt;';
        presenter.$view.html(errorContainer);
    }

    function onSVGLoadCompleted(data, element) {
        const svgElement = $(data).find('svg');
        if (svgElement.length === 0) {
            onSVGLoadError();
            return;
        }

        const svgWidth = getElementWidth(svgElement);
        const svgHeight = getElementHeight(svgElement);

        svgElement.attr('viewBox', '0 0 ' + svgWidth + ' ' + svgHeight);
        svgElement.attr('width', '100%');
        svgElement.attr('height', '100%');

        const svgData = data.childNodes;
        $(element).html(svgData);
        createTitleElement(element);
    }

    function getElementWidth(HTMLElement) {
        const width = HTMLElement.attr('width');
        const widthFromRectTag = HTMLElement.find('rect').attr('width');

        if (width) {
            return width.replace('px', '');
        } else if (widthFromRectTag) {
            return widthFromRectTag.replace('px', '');
        } else {
            return presenter.configuration.width;
        }
    }

    function getElementHeight(HTMLElement) {
        const height = HTMLElement.attr('width');
        const heightFromRectTag = HTMLElement.find('rect').attr('width');

        if (height) {
            return height.replace('px', '');
        } else if (heightFromRectTag) {
            return heightFromRectTag.replace('px', '');
        } else {
            return presenter.configuration.height;
        }
    }

    function presenterLogic(view, model, isPreview) {
        presenter.addonID = model.ID;
        presenter.$view = $(view);

        var upgradedModel = presenter.upgradeModel(model);
        presenter.configuration = presenter.validateModel(upgradedModel);

        var $wrapper = $(presenter.$view.find('.singlestate-button-wrapper:first')[0]);
        var $element = createElements($wrapper);

        setElementsDimensions(upgradedModel, $wrapper, $element);
        presenter.toggleDisable(presenter.configuration.isDisabledByDefault);
        presenter.setVisibility(presenter.configuration.isVisibleByDefault || isPreview);

        if (!isPreview) {
            handleMouseActions();
        }
    }

    presenter.setPlayerController = function(controller) {
        presenter.playerController = controller;

        var eventBus = presenter.playerController.getEventBus();

        eventBus.addEventListener('ShowAnswers', this);
        eventBus.addEventListener('HideAnswers', this);
    };

    presenter.createPreview = function(view, model) {
        presenterLogic(view, model, true);
    };

    presenter.run = function(view, model){
        presenterLogic(view, model, false);
    };

    presenter.upgradeModel = function(model) {
        var upgradedModel = presenter.upgradeDisable(model);
        upgradedModel = presenter.upgradeEnableInErrorMode(upgradedModel);
        upgradedModel =  presenter.upgradeEnableInShowAnswersMode(upgradedModel);
        return presenter.addRenderSVGAsHTML(upgradedModel);
    };

    presenter.upgradeDisable = function (model) {
        var upgradedModel = {};
        $.extend(true, upgradedModel, model); // Deep copy of model object

        if (!upgradedModel.Disable) {
            upgradedModel.Disable = "False";
        }

        return upgradedModel;
    };

    presenter.upgradeEnableInErrorMode = function AddonSingleStateButton_upgradeEnableInErrorMode(model) {
        var upgradedModel = {};
        $.extend(true, upgradedModel, model);

        if (!upgradedModel['Enable in error mode']) {
            upgradedModel['Enable in error mode'] = "False";
        }

        return upgradedModel;
    }

    presenter.upgradeEnableInShowAnswersMode = function AddonSingleStateButton_upgradeEnableInErrorMode(model) {
        var upgradedModel = {};
        $.extend(true, upgradedModel, model);

        if (!upgradedModel['Enable in show answers mode']) {
            upgradedModel['Enable in show answers mode'] = "False";
        }

        return upgradedModel;
    }

    presenter.addRenderSVGAsHTML = function (model) {
        const upgradedModel = {};
        $.extend(true, upgradedModel, model);

        if(!model.hasOwnProperty('renderSVGAsHTML')) {
            upgradedModel['renderSVGAsHTML'] = 'False';
        }

        return upgradedModel;
    };

    presenter.validateString = function (imageSrc) {
        var isEmpty = ModelValidationUtils.isStringEmpty(imageSrc);

        return {
            isEmpty: isEmpty,
            value: isEmpty ? "" : imageSrc
        };
    };

    presenter.determineDisplayContent = function(title, image) {
        var displayContent = presenter.DISPLAY_CONTENT_TYPE.NONE;

        if (!title.isEmpty &amp;&amp; image.isEmpty) {
            displayContent = presenter.DISPLAY_CONTENT_TYPE.TITLE;
        } else if (title.isEmpty &amp;&amp; !image.isEmpty) {
            displayContent = presenter.DISPLAY_CONTENT_TYPE.IMAGE;
        } else if (!title.isEmpty &amp;&amp; !image.isEmpty) {
            displayContent = presenter.DISPLAY_CONTENT_TYPE.BOTH;
        }

        return displayContent;
    };

    presenter.validateModel = function (model) {
        var title = presenter.validateString(model.Title);
        var image = presenter.validateString(model.Image);
        var onClickEvent = presenter.validateString(model.onClick);
        var isDisabled = ModelValidationUtils.validateBoolean(model.Disable);
        var isVisible = ModelValidationUtils.validateBoolean(model['Is Visible']);
        var isTabindexEnabled = ModelValidationUtils.validateBoolean(model['Is Tabindex Enabled']);
        var enableInErrorMode = ModelValidationUtils.validateBoolean(model['Enable in error mode']);
        var enableInShowAnswersMode = ModelValidationUtils.validateBoolean(model['Enable in show answers mode']);
        var renderSVGAsHTML = ModelValidationUtils.validateBoolean(model.renderSVGAsHTML);

        return {
            displayContent: presenter.determineDisplayContent(title, image),
            title: title.value,
            image: image.value,
            onClickEvent: onClickEvent,
            isDisabled: isDisabled,
            isDisabledByDefault: isDisabled,
            isVisible: isVisible,
            isVisibleByDefault: isVisible,
            isErrorMode: false,
            isTabindexEnabled: isTabindexEnabled,
            enableInErrorMode: enableInErrorMode,
            enableInShowAnswersMode: enableInShowAnswersMode,
            renderSVGAsHTML: renderSVGAsHTML
        };
    };

    presenter.executeCommand = function(name, params) {
        if (presenter.configuration.isErrorMode) return;

        var commands = {
            'show': presenter.show,
            'hide': presenter.hide,
            'enable': presenter.enable,
            'disable': presenter.disable
        };

        Commands.dispatch(commands, name, params, presenter);
    };

    presenter.createEventData = function() {
        return {
            source : presenter.addonID,
            item : '',
            value : '1',
            score : ''
        };
    };

    presenter.triggerButtonClickedEvent = function() {
        if (presenter.playerController == null) return;

        presenter.playerController.getEventBus().sendEvent('ValueChanged', this.createEventData());
    };

    presenter.setVisibility = function(isVisible) {
        presenter.$view.css("visibility", isVisible ? "visible" : "hidden");
    };

    presenter.show = function() {
        this.setVisibility(true);
        presenter.configuration.isVisible = true;
    };

    presenter.hide = function() {
        this.setVisibility(false);
        presenter.configuration.isVisible = false;
    };

    presenter.isEnabledInGSAMode = function () {
        return presenter.configuration.enableInShowAnswersMode;
    }

    presenter.reset = function() {
        presenter.setWorkMode();

        presenter.configuration.isVisible = presenter.configuration.isVisibleByDefault;
        if (presenter.configuration.isVisible) {
            this.show();
        } else {
            this.hide();
        }
        presenter.toggleDisable(this.configuration.isDisabledByDefault);
    };

    presenter.enable = function() {
        this.toggleDisable(false);
    };

    presenter.disable = function() {
        this.toggleDisable(true);
    };

    presenter.toggleDisable = function(disable) {
        var element = presenter.$view.find('div[class*=singlestate-button-element]:first');
        if(disable) {
            element.addClass("disable");
        } else {
            element.removeClass("disable");
        }
        presenter.configuration.isDisabled = disable;
    };

    presenter.getState = function() {
        return JSON.stringify({
            isVisible: presenter.configuration.isVisible,
            isDisabled: presenter.configuration.isDisabled
        });
    };

    presenter.setState = function(stateString) {
        if (ModelValidationUtils.isStringEmpty(stateString)) return;

        var state = JSON.parse(stateString);
        presenter.configuration.isDisabled = state.isDisabled;
        presenter.configuration.isVisible = state.isVisible;

        if (presenter.configuration.isVisible) {
            presenter.show();
        } else {
            presenter.hide();
        }

        presenter.toggleDisable(presenter.configuration.isDisabled);
    };

    presenter.setShowErrorsMode = function () {
        presenter.configuration.isErrorMode = true;
        presenter.state.isErrorMode = true;
    };

    presenter.setWorkMode = function () {
        presenter.configuration.isErrorMode = false;
        presenter.state.isErrorMode = false;
        presenter.configuration.isShowAnswersMode = false;
    };

    presenter.onEventReceived = function (eventName) {
        if (eventName === "ShowAnswers") {
            presenter.configuration.isShowAnswersMode = true;
        }

        if (eventName === "HideAnswers") {
            presenter.configuration.isShowAnswersMode = false;
            presenter.setWorkMode();
        }
    };

    presenter.keyboardController = function(keyCode, isShiftDown, event) {
        event.preventDefault();
        if (keyCode === window.KeyboardControllerKeys.ENTER) {
            presenter.clickHandler();
        }
    };
    return presenter;
}
</presenter></addon>