content: import React from 'react';
  import Environment from '../environment/environment.js';
  import {BaseMixin, ElementaryMixin, CcrWriterMixin, Tools} from '../common/common.js';
  import {FloatMixin} from '../layout/layout.js';
  import Alert from './alert.js';
  
  import './alert-bus.less';
  
  export const AlertBus = React.createClass({
  
    //@@viewOn:mixins
    mixins: [
      BaseMixin,
      ElementaryMixin,
      CcrWriterMixin,
      FloatMixin
    ],
    //@@viewOff:mixins
  
    //@@viewOn:statics
    statics: {
      tagName: 'UU5.Bricks.AlertBus',
      classNames: {
        main: 'uu5-bricks-alert-bus'
      },
      warnings: {
        noMessage: 'Alert "%s" is not set.'
      }
    },
    //@@viewOff:statics
  
    //@@viewOn:propTypes
    propTypes: {
      // has not color schema because color schema css class is added automatically to all alerts,
      // but we just need to set color schema of added alert
      colorSchema: React.PropTypes.oneOf(Environment.colorSchema),
      position: React.PropTypes.string,
      closeTimer: React.PropTypes.number,
      closeDisabled: React.PropTypes.bool,
      block: React.PropTypes.bool,
      onClose: React.PropTypes.func
    },
    //@@viewOff:propTypes
  
    //@@viewOn:getDefaultProps
    getDefaultProps: function () {
      return {
        colorSchema: null,
        position: 'center',
        closeTimer: 10000,
        closeDisabled: false,
        block: false,
        onClose: null
      };
    },
    //@@viewOff:getDefaultProps
  
    //@@viewOn:standardComponentLifeCycle
    getInitialState: function () {
      return {
        alertStack: []
      };
    },
    //@@viewOff:standardComponentLifeCycle
  
    //@@viewOn:interface
    addAlert: function (alertProps, setStateCallback) {
      if (alertProps.content) {
        var messageProps = this._getMessageProps(null, alertProps);
  
        this.setState(function (state) {
          var alertStack = state.alertStack;
          if (alertProps.priority) {
            alertStack.splice(0, 0, messageProps);
          } else {
            alertStack.push(messageProps);
          }
          return {alertStack: alertStack};
        }, setStateCallback);
      } else {
        this.showWarning('noMessage', alertProps.content, {alertProps: alertProps});
      }
  
      return this;
    },
  
    addAlertToPosition: function (alertIndex, alertProps, setStateCallback) {
      if (alertProps.content) {
        var messageProps = this._getMessageProps(null, alertProps);
  
        this.setState(function (state) {
          var alertStack = state.alertStack;
          alertStack.splice(alertIndex, 0, messageProps);
          return {alertStack: alertStack};
        }, setStateCallback);
      } else {
        this.showWarning('noMessage', alertProps.content, {alertProps: alertProps});
      }
  
      return this;
    },
  
    setAlert: function (alertProps, setStateCallback) {
      if (alertProps.content) {
        var messageProps = this._getMessageProps(null, alertProps);
        this.setState({alertStack: [messageProps]}, setStateCallback);
      } else {
        this.showWarning('noMessage', alertProps.content, {alertProps: alertProps});
      }
      return this;
    },
  
    setAlerts: function (alertStack, setStateCallback) {
      this.setState({alertStack: alertStack}, setStateCallback);
      return this;
    },
  
    removeAlert: function (alertId, setStateCallback) {
      this.setState(function (state) {
        var alertStack = state.alertStack;
        var index = null;
  
        for (var i = 0; i < alertStack.length; i++) {
          if (alertStack[i].id === alertId) {
            index = i;
            break;
          }
        }
  
        alertStack.splice(index, 1);
        return {alertStack: alertStack};
      }, setStateCallback);
  
      return this;
    },
  
    clearAlerts: function (setStateCallback) {
      var props = this.getAlerts()[0];
      props.hidden = true;
      this.setState({
          alertStack: [props]
        },
        ()=> {
          setTimeout(
            ()=> {
              this.setState({alertStack: []}, setStateCallback)
            },
            Alert.defaults.transitionDuration
          )
        }
      );
      return this;
    },
  
    getAlerts: function () {
      return this.state.alertStack;
    },
    //@@viewOff:interface
  
    //@@viewOn:overridingMethods
    //@@viewOff:overridingMethods
  
    //@@viewOn:componentSpecificHelpers
    _getMessageProps: function (message, alertProps) {
      alertProps = alertProps || {};
      var alertBus = this;
      var messageId = alertProps.id || Tools.generateUUID();
  
      return {
        id: messageId,
        hidden: false,
  
        content: alertProps.content,
        colorSchema: typeof alertProps.colorSchema === 'string' ? alertProps.colorSchema : this.props.colorSchema,
        closeTimer: typeof alertProps.closeTimer === 'number' ? alertProps.closeTimer : this.props.closeTimer,
        onClose: function (alert) {
          var onClose;
          if (typeof alertProps.onClose === 'function') {
            onClose = function () {
              alertProps.onClose(alert);
            }
          } else if (typeof alertBus.props.onClose === 'function') {
            onClose = function () {
              alertBus.props.onClose(alert);
            }
          }
  
          alertBus.removeAlert(messageId, onClose);
        }
      };
    },
    //@@viewOff:componentSpecificHelpers
  
    // Render
    _getProps: function () {
      var alertStack = this.getAlerts();
  
      var alertProps = this.getMainPropsToPass();
      var hidden = alertStack.length === 0;
      alertProps.hidden = hidden;
  
      if (!hidden) {
        alertProps = Tools.mergeDeep(alertProps, alertStack[0]);
      }
  
      alertProps.id = this.getId() + '-alert';
      alertProps.position = this.props.position;
      alertProps.closeDisabled = this.props.closeDisabled;
      alertProps.block = this.props.block;
  
      return alertProps;
    },
  
    //@@viewOn:render
    render: function () {
      return <Alert {...this._getProps()} />;
    }
    //@@viewOff:render
  });
  
  export default AlertBus;