/**
 * DevExtreme (ui/color_box/color_box.js)
 * Version: 17.2.10 (build 18271)
 * Build date: Fri Sep 28 2018
 *
 * Copyright (c) 2012 - 2018 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
"use strict";
var $ = require("../../core/renderer"),
    eventsEngine = require("../../events/core/events_engine"),
    Color = require("../../color"),
    ColorView = require("./color_view"),
    extend = require("../../core/utils/extend").extend,
    isFunction = require("../../core/utils/type").isFunction,
    registerComponent = require("../../core/component_registrator"),
    DropDownEditor = require("../drop_down_editor/ui.drop_down_editor");
var COLOR_BOX_CLASS = "dx-colorbox",
    COLOR_BOX_INPUT_CLASS = COLOR_BOX_CLASS + "-input",
    COLOR_BOX_INPUT_CONTAINER_CLASS = COLOR_BOX_INPUT_CLASS + "-container",
    COLOR_BOX_COLOR_RESULT_PREVIEW_CLASS = COLOR_BOX_CLASS + "-color-result-preview",
    COLOR_BOX_COLOR_IS_NOT_DEFINED = COLOR_BOX_CLASS + "-color-is-not-defined",
    COLOR_BOX_OVERLAY_CLASS = COLOR_BOX_CLASS + "-overlay",
    COLOR_BOX_CONTAINER_CELL_CLASS = "dx-colorview-container-cell",
    COLOR_BOX_BUTTON_CELL_CLASS = "dx-colorview-button-cell",
    COLOR_BOX_BUTTONS_CONTAINER_CLASS = "dx-colorview-buttons-container",
    COLOR_BOX_APPLY_BUTTON_CLASS = "dx-colorview-apply-button",
    COLOR_BOX_CANCEL_BUTTON_CLASS = "dx-colorview-cancel-button";
var colorEditorPrototype = ColorView.prototype,
    colorUtils = {
        makeTransparentBackground: colorEditorPrototype._makeTransparentBackground.bind(colorEditorPrototype),
        makeRgba: colorEditorPrototype._makeRgba.bind(colorEditorPrototype)
    };
var ColorBox = DropDownEditor.inherit({
    _supportedKeys: function() {
        var arrowHandler = function(e) {
            e.stopPropagation();
            if (this.option("opened")) {
                e.preventDefault();
                return true
            }
        };
        var upArrowHandler = function(e) {
            if (!this.option("opened")) {
                e.preventDefault();
                return false
            }
            if (e.altKey) {
                this.close();
                return false
            }
            return true
        };
        var downArrowHandler = function(e) {
            if (!this.option("opened") && !e.altKey) {
                e.preventDefault();
                return false
            }
            if (!this.option("opened") && e.altKey) {
                this._validatedOpening();
                return false
            }
            return true
        };
        return extend(this.callBase(), {
            tab: function(e) {
                if (this.option("opened")) {
                    e.preventDefault();
                    this._colorView._rgbInputs[0].focus()
                }
            },
            enter: this._enterKeyHandler,
            leftArrow: arrowHandler,
            rightArrow: arrowHandler,
            upArrow: upArrowHandler,
            downArrow: downArrowHandler
        })
    },
    _getDefaultOptions: function() {
        return extend(this.callBase(), {
            editAlphaChannel: false,
            applyValueMode: "useButtons",
            keyStep: 1,
            fieldTemplate: null,
            onApplyButtonClick: null,
            onCancelButtonClick: null,
            buttonsLocation: "bottom after"
        })
    },
    _popupConfig: function() {
        return extend(this.callBase(), {
            height: "auto",
            width: ""
        })
    },
    _contentReadyHandler: function() {
        this._createColorView();
        this._addPopupBottomClasses()
    },
    _addPopupBottomClasses: function() {
        var $popupBottom = this._popup.bottomToolbar();
        if ($popupBottom) {
            $popupBottom.addClass(COLOR_BOX_CONTAINER_CELL_CLASS).addClass(COLOR_BOX_BUTTON_CELL_CLASS).find(".dx-toolbar-items-container").addClass(COLOR_BOX_BUTTONS_CONTAINER_CLASS);
            $popupBottom.find(".dx-popup-done").addClass(COLOR_BOX_APPLY_BUTTON_CLASS);
            $popupBottom.find(".dx-popup-cancel").addClass(COLOR_BOX_CANCEL_BUTTON_CLASS)
        }
    },
    _createColorView: function() {
        this._popup.overlayContent().addClass(COLOR_BOX_OVERLAY_CLASS);
        var $colorView = $("<div>").appendTo(this._popup.$content());
        this._colorView = this._createComponent($colorView, ColorView, this._colorViewConfig());
        eventsEngine.on($colorView, "focus", function() {
            this.focus()
        }.bind(this))
    },
    _applyNewColor: function(value) {
        this.option("value", value);
        if (value) {
            colorUtils.makeTransparentBackground(this._$colorResultPreview, value)
        }
        if (this._colorViewEnterKeyPressed) {
            this.close();
            this._colorViewEnterKeyPressed = false
        }
    },
    _colorViewConfig: function() {
        var that = this;
        return {
            value: that.option("value"),
            editAlphaChannel: that.option("editAlphaChannel"),
            applyValueMode: that.option("applyValueMode"),
            focusStateEnabled: that.option("focusStateEnabled"),
            onEnterKeyPressed: function() {
                that._colorViewEnterKeyPressed = true;
                if (that._colorView.option("value") !== that.option("value")) {
                    that._applyNewColor(that._colorView.option("value"));
                    that.close()
                }
            },
            onValueChanged: function(args) {
                var instantlyMode = "instantly" === that.option("applyValueMode");
                if (!instantlyMode && !that._colorViewEnterKeyPressed) {
                    return
                }
                that._applyNewColor(args.value)
            },
            _keyboardProcessor: that._colorViewProcessor
        }
    },
    _enterKeyHandler: function() {
        var newValue = this._input().val(),
            value = this.option("value"),
            oldValue = this.option("editAlphaChannel") ? colorUtils.makeRgba(value) : value;
        if (!newValue) {
            return false
        }
        var color = new Color(newValue);
        if (color.colorIsInvalid) {
            this._input().val(oldValue);
            return
        }
        if (newValue !== oldValue) {
            this._applyColorFromInput(newValue);
            this.option("value", this.option("editAlphaChannel") ? colorUtils.makeRgba(newValue) : newValue)
        }
        if (this._colorView) {
            var colorViewValue = this._colorView.option("value");
            if (value !== colorViewValue) {
                this.option("value", colorViewValue)
            }
        }
        this.close();
        return false
    },
    _applyButtonHandler: function() {
        this._applyNewColor(this._colorView.option("value"));
        if (isFunction(this.option("onApplyButtonClick"))) {
            this.option("onApplyButtonClick")()
        }
        this.callBase()
    },
    _cancelButtonHandler: function() {
        this._resetInputValue();
        if (isFunction(this.option("onCancelButtonClick"))) {
            this.option("onCancelButtonClick")()
        }
        this.callBase()
    },
    _attachChildKeyboardEvents: function() {
        this._colorViewProcessor = this._keyboardProcessor.attachChildProcessor();
        if (this._colorView) {
            this._colorView.option("_keyboardProcessor", this._colorViewProcessor);
            return
        }
    },
    _init: function() {
        this.callBase()
    },
    _render: function() {
        this.callBase();
        this.$element().addClass(COLOR_BOX_CLASS)
    },
    _renderInput: function() {
        this.callBase();
        this._input().addClass(COLOR_BOX_INPUT_CLASS);
        this._renderColorPreview()
    },
    _renderColorPreview: function() {
        this.$element().wrapInner($("<div>").addClass(COLOR_BOX_INPUT_CONTAINER_CLASS));
        this._$colorBoxInputContainer = this.$element().children().eq(0);
        this._$colorResultPreview = $("<div>").addClass(COLOR_BOX_COLOR_RESULT_PREVIEW_CLASS).appendTo(this._$colorBoxInputContainer);
        if (!this.option("value")) {
            this._$colorBoxInputContainer.addClass(COLOR_BOX_COLOR_IS_NOT_DEFINED)
        } else {
            colorUtils.makeTransparentBackground(this._$colorResultPreview, this.option("value"))
        }
    },
    _renderValue: function() {
        var value = this.option("value");
        this.option("text", this.option("editAlphaChannel") ? colorUtils.makeRgba(value) : value);
        this.callBase()
    },
    _resetInputValue: function() {
        var $input = this._input(),
            value = this.option("value");
        $input.val(value);
        this._colorView && this._colorView.option("value", value)
    },
    _valueChangeEventHandler: function(e) {
        var value = this._input().val();
        if (value) {
            value = this._applyColorFromInput(value);
            this._colorView && this._colorView.option("value", value)
        }
        this.callBase(e, value)
    },
    _applyColorFromInput: function(value) {
        var newColor = new Color(value);
        if (newColor.colorIsInvalid) {
            this._resetInputValue();
            value = this.option("value")
        }
        return value
    },
    _optionChanged: function(args) {
        var value = args.value,
            name = args.name;
        switch (name) {
            case "value":
                this._$colorBoxInputContainer.toggleClass(COLOR_BOX_COLOR_IS_NOT_DEFINED, !value);
                if (value) {
                    colorUtils.makeTransparentBackground(this._$colorResultPreview, value)
                } else {
                    this._$colorResultPreview.removeAttr("style")
                }
                if (this._colorView) {
                    this._colorView.option("value", value)
                }
                this.callBase(args);
                break;
            case "applyButtonText":
            case "cancelButtonText":
                this.callBase(args);
                this._popup && this._addPopupBottomClasses();
                break;
            case "editAlphaChannel":
            case "onCancelButtonClick":
            case "onApplyButtonClick":
            case "keyStep":
                if (this._colorView) {
                    this._colorView.option(name, value)
                }
                break;
            case "applyValueMode":
                this.callBase(args);
                break;
            case "rtlEnabled":
                if (this._colorView) {
                    this._colorView.option(name, value)
                }
                this.callBase(args);
                break;
            default:
                this.callBase(args)
        }
    }
});
registerComponent("dxColorBox", ColorBox);
module.exports = ColorBox;
