Show:
import Ember from 'ember';
import FdAppStructTree from '../objects/fd-appstruct-tree';
import EditFormController from 'ember-flexberry/controllers/edit-form';
import { translationMacro as t } from 'ember-i18n';
import FdWorkPanelToggler from '../mixins/fd-work-panel-toggler';
import { restorationNodeTree, findFreeNodeTreeID, findFreeNodeTreeNameIndex } from '../utils/fd-metods-for-tree';
import { getNewFormCaption, getNewFormDescription } from '../utils/fd-create-form-properties';

export default EditFormController.extend(FdWorkPanelToggler, {

  /**
    @property store
    @type Service
  */
  store: Ember.inject.service(),

  /**
    @property currentProjectContext
    @type Service
  */
  currentProjectContext: Ember.inject.service('fd-current-project-context'),

  /**
    Setting off for 'openProcessEditorForm' buttons.

    @property processMethodologyValue
    @type Boolean
    @default false
  */
  processMethodologyValue: false,

  /*
    Setting off for buttons of the left tree.
  */
  removeLeftNodeDisabled: 'disabled',
  addLeftNodeDisabled: 'disabled',
  editLeftNodeDisabled: 'disabled',

  /*
    Setting off for 'moveRight' buttons.
  */
  moveRightDisabled: 'disabled',

  /*
    Setting off for buttons of the right tree.
  */
  addRightNodeDisabled: 'disabled',
  editRightNodeDisabled: 'disabled',
  removeRightNodeDisabled: 'disabled',
  addFolderNodeDisabled: 'disabled',

  /**
   Service that triggers objectlistview events.

   @property objectlistviewEventsService
   @type {Class}
   @default Ember.inject.service()
   */
  objectlistviewEventsService: Ember.inject.service('objectlistview-events'),

  allAttrsHidedn: false,

  /**
    Show question of removal.

    @private
    @property _showModalDialog
    @type Boolean
    @default false
  */
  _showModalDialog: false,

  /**
    Included plugins for left jsTree.

    @property pluginsLeft
    @type String
    @default 'wholerow, types, sort, search'
   */
  pluginsLeft: 'wholerow, types, sort, search',

  /**
    Included plugins for right jsTree.

    @property pluginsRight
    @type String
    @default 'wholerow, types, search'
   */
  pluginsRight: 'wholerow, types, search',

  /**
    Selected nodes in left jsTree.

    @property jstreeSelectedNodesLeft
    @type Array
    @default []
   */
  jstreeSelectedNodesLeft: Ember.A(),

  /**
    Selected nodes in right jsTree.

    @property jstreeSelectedNodesRight
    @type Array
    @default []
   */
  jstreeSelectedNodesRight: Ember.A(),

  /**
    Nodes in right jsTree for edit propertys.

    @property selectedElementForEdit
    @type Object
   */
  selectedElementForEdit: undefined,

  /**
    Type settings for jsTree.

    @property typesOptions
    @type Object
  */
  typesOptions: Ember.computed(() => ({
    '«listform»': {
      icon: 'assets/images/listform.png',
      max_children: 0
    },
    '«editform»': {
      icon: 'assets/images/editform.png',
      max_children: 0
    },
    'implementations': {
      icon: 'assets/images/implementations.png'
    },
    'desk': {
      icon: 'assets/images/class.bmp'
    },
    'notStored': {
      icon: 'assets/images/notStored.png'
    },
    'folder': {
      icon: 'folder icon'
    },
    '#': {
      max_children: 1
    },
    'url': {
      icon: 'globe icon'
    }
  })),

  /**
    Data for search tree node.

    @property searchTermLeft
    @type String
    @default ''
   */
  searchTermLeft: '',

  /**
    Data for search tree node.

    @property searchTermRight
    @type String
    @default ''
   */
  searchTermRight: '',

  /**
    Search settings for jsTree.

    @property searchOptions
    @type Object
  */
  searchOptions: Ember.computed(() => ({
    show_only_matches: true
  })),

  /**
    Flag: indicates whether to show close button.

    @property singleModeStage
    @type Boolean
    @default false
   */
  singleModeStage: false,

  _modelObserver: Ember.on('init', Ember.observer('model', function() {
    // Reset selection.
    this.set('jstreeSelectedNodesLeft', Ember.A());
    this.set('jstreeSelectedNodesRight', Ember.A());
    this.set('selectedElementForEdit', undefined);
  })),

  /**
    Update text in node.

    @method selectedElementCaptionObserver
  */
  selectedElementCaptionObserver: Ember.observer('selectedElementForEdit.caption', function() {
    let selectedElement = this.get('selectedElementForEdit');
    if (Ember.isNone(selectedElement)) {
      return;
    }

    if (selectedElement.get('type') !== 'folder' && selectedElement.get('type') !== 'desk') {
      let caption = selectedElement.get('caption');
      if (caption !== '' && !Ember.isNone(caption)) {
        selectedElement.set('text', caption);
      } else {
        selectedElement.set('text', selectedElement.get('className'));
      }
    }
  }),

  /**
    Redraw text in node.

    @method selectedElementTextObserver
  */
  selectedElementTextObserver: Ember.observer('selectedElementForEdit.text', function() {
    let selectedElement = this.get('selectedElementForEdit');
    if (Ember.isNone(selectedElement)) {
      return;
    }

    this.get('jstreeActionReceiverRight').send('renameNode', selectedElement.get('id'), selectedElement.get('text'));
  }),

  /**
    Handles changes in jstreeSelectedNodesLeft.

    @method jstreeSelectedNodesLeftObserver
  */
  _jstreeSelectedNodesLeftObserver: Ember.observer('jstreeSelectedNodesLeft', function() {
    let jstreeSelectedNodesLeft = this.get('jstreeSelectedNodesLeft');
    if (jstreeSelectedNodesLeft.length === 0) {
      this.set('removeLeftNodeDisabled', 'disabled');
      this.set('addLeftNodeDisabled', 'disabled');
      this.set('editLeftNodeDisabled', 'disabled');
    } else {
      this.set('removeLeftNodeDisabled', '');
      this.set('editLeftNodeDisabled', '');
      let selectedNode = jstreeSelectedNodesLeft[0];
      let typeNode = selectedNode.original.type;
      if (typeNode === 'implementations' || typeNode === 'notStored') {
        this.set('addLeftNodeDisabled', '');
      } else {
        this.set('addLeftNodeDisabled', 'disabled');
      }
    }
  }),

  /**
    Handles changes in jstreeSelectedNodesRight.

    @method jstreeSelectedNodesRightObserver
  */
  _jstreeSelectedNodesRightObserver: Ember.observer('jstreeSelectedNodesRight', function() {
    let jstreeSelectedNodesRight = this.get('jstreeSelectedNodesRight');
    if (jstreeSelectedNodesRight.length === 0) {
      this.set('addRightNodeDisabled', 'disabled');
      this.set('editRightNodeDisabled', 'disabled');
      this.set('removeRightNodeDisabled', 'disabled');
      this.set('addFolderNodeDisabled', 'disabled');
    } else {
      let selectedNode = jstreeSelectedNodesRight[0];
      this.set('selectedElementForEdit', selectedNode.original);
      let typeNode = selectedNode.original.type;

      if (typeNode === '«listform»' || typeNode === '«editform»' || typeNode === 'url') {
        this.set('addRightNodeDisabled', 'disabled');
        this.set('addFolderNodeDisabled', 'disabled');
        this.set('removeRightNodeDisabled', '');
        this.set('editRightNodeDisabled', '');
      } else {
        this.set('addFolderNodeDisabled', '');
        if (typeNode === 'desk') {
          this.set('removeRightNodeDisabled', 'disabled');
          this.set('editRightNodeDisabled', 'disabled');
          this.set('addRightNodeDisabled', '');
        } else {
          this.set('addRightNodeDisabled', '');
          this.set('removeRightNodeDisabled', '');
          this.set('editRightNodeDisabled', '');
        }
      }
    }
  }),

  /**
    Handles changes in jstreeSelectedNodesRight and jstreeSelectedNodesLeft.

    @method _jstreeSelectedNodesObserver
  */
  _jstreeSelectedNodesObserver: Ember.observer('jstreeSelectedNodesLeft', 'jstreeSelectedNodesRight', function() {
    let jstreeSelectedNodesLeft = this.get('jstreeSelectedNodesLeft');
    let jstreeSelectedNodesRight = this.get('jstreeSelectedNodesRight');
    if (jstreeSelectedNodesRight.length === 0 || jstreeSelectedNodesLeft.length === 0) {
      return;
    }

    let jstreeSelectedNodesRightType = jstreeSelectedNodesRight[0].original.type;
    let jstreeSelectedNodesLeftType = jstreeSelectedNodesLeft[0].original.type;
    if ((jstreeSelectedNodesLeftType !== '«listform»' && jstreeSelectedNodesLeftType !== '«editform»') ||
      jstreeSelectedNodesRightType === '«listform»' || jstreeSelectedNodesRightType === '«editform»' ||
      jstreeSelectedNodesRightType === 'url' || jstreeSelectedNodesRightType === 'desk') {
      this.set('moveRightDisabled', 'disabled');
    } else {
      this.set('moveRightDisabled', '');
    }
  }),

  /**
    Index selected attribute in right tree.

    @property indexSelectedRight
    @type Number
  */
  indexSelectedRight: Ember.computed('jstreeSelectedNodesRight', function() {
    let jstreeSelectedNodesRight = this.get('jstreeSelectedNodesRight');
    if (jstreeSelectedNodesRight.length === 0 || jstreeSelectedNodesRight[0].type === 'desk') {
      return {
        upRightNodeDisabled: 'disabled',
        downRightNodeDisabled: 'disabled'
      };
    }

    let parentSelectedNode = this.get('jstreeObjectRight').jstree(true).get_node(jstreeSelectedNodesRight[0].parent);
    let arrayChildrensParentSelectedNode = parentSelectedNode.original.get('copyChildren');
    let selectedObject = arrayChildrensParentSelectedNode.findBy('text', jstreeSelectedNodesRight[0].text);
    let indexSelectedNode = arrayChildrensParentSelectedNode.indexOf(selectedObject);

    let upRightNodeDisabled = 'disabled';
    let downRightNodeDisabled = 'disabled';

    if (indexSelectedNode !== 0) {
      upRightNodeDisabled = '';
    }

    if (indexSelectedNode !== arrayChildrensParentSelectedNode.length - 1) {
      downRightNodeDisabled = '';
    }

    return {
      index: indexSelectedNode,
      array: arrayChildrensParentSelectedNode,
      upRightNodeDisabled: upRightNodeDisabled,
      downRightNodeDisabled: downRightNodeDisabled
    };
  }),

  actions: {

    /**
      Close current form, go back
      .

      @method actions.close
    */
    close() {
      history.back();
    },

    /**
      Handles move node from left in right jsTree.

      @method actions.moveRightHighlighted
    */
    moveRightHighlighted() {
      let jstreeSelectedNodesLeft = this.get('jstreeSelectedNodesLeft');
      let jstreeSelectedNodesRight = this.get('jstreeSelectedNodesRight');
      if (jstreeSelectedNodesLeft.length === 0 || jstreeSelectedNodesRight.length === 0) {
        return;
      }

      let nodeId = findFreeNodeTreeID('move', 0, this.get('jstreeObjectRight'));
      let leftSelectedNodes = jstreeSelectedNodesLeft[0].original;
      let rightSelectedNodes = jstreeSelectedNodesRight[0].original.get('copyChildren');
      let newNode = FdAppStructTree.create({
        text: leftSelectedNodes.get('text'),
        type: leftSelectedNodes.get('type'),
        caption: leftSelectedNodes.get('caption'),
        className: leftSelectedNodes.get('name'),
        description: leftSelectedNodes.get('description'),
        a_attr: leftSelectedNodes.get('a_attr'),
        id: 'move' + nodeId
      });

      rightSelectedNodes.pushObject(newNode);
      this.get('jstreeActionReceiverRight').send('createNode', jstreeSelectedNodesRight[0], newNode);
      this.get('jstreeActionReceiverRight').send('openNode', jstreeSelectedNodesRight[0]);
    },

    /**
      Handles remove node from left jsTree.

      @method actions.removeLeftNode
    */
    removeLeftNode(approve) {
      if (approve) {
        let jstreeSelectedNodesLeft = this.get('jstreeSelectedNodesLeft');
        let classId = jstreeSelectedNodesLeft[0].original.idNode;
        let store = this.get('store');
        let allClasses = store.peekAll('fd-dev-class');
        let forms = allClasses.filterBy('formViews.firstObject.view.class.id', classId);
        if (forms.length === 0) {
          this.get('jstreeActionReceiverLeft').send('deleteNode', jstreeSelectedNodesLeft[0]);
          this.set('jstreeSelectedNodesLeft', Ember.A());
          let deletedClass = allClasses.findBy('id', classId);
          deletedClass.destroyRecord();
        } else {
          this.set('error', new Error(this.get('i18n').t('forms.fd-appstruct-form.delete-error')));
        }
      } else {
        this.set('_showModalDialog', true);
      }
    },

    /**
      Handles create new class left jsTree.

      @method actions.addLeftClass
    */
    addLeftClass() {
      this.transitionToRoute('fd-class-edit-form.new');
    },

    /**
      Handles add edit form for class in left jsTree.

      @method actions.addLeftListForm
    */
    addLeftEditForm() {
      this.set('state', 'loading');

      let jstreeSelectedNodesLeft = this.get('jstreeSelectedNodesLeft');
      if (jstreeSelectedNodesLeft.length === 0) {
        return;
      }

      let _this = this;
      Ember.run.next(_this, () => {
        let selectedNode = jstreeSelectedNodesLeft[0];
        let classId = selectedNode.original.get('idNode');

        let store = this.get('store');
        let currentStage = this.get('currentProjectContext').getCurrentStageModel();

        let devClass = store.peekRecord('fd-dev-class', classId);
        let baseCaption = devClass.get('name') || devClass.get('nameStr');
        let newCaption = getNewFormCaption(store, baseCaption, 'E');
        let newDescription = getNewFormDescription(newCaption);

        store.createRecord('fd-dev-class', {
          stage: currentStage,
          caption: newCaption,
          description: newDescription,
          name: newCaption,
          nameStr: newCaption,
          stereotype: '«editform»'
        }).save().then(savedDevClass => {
          store.createRecord('fd-dev-view', {
            class: devClass,
            name: newCaption,
            definition: Ember.A()
          }).save().then(savedDevView => {
            store.createRecord('fd-dev-form-view', {
              class: savedDevClass,
              view: savedDevView,
              orderNum: 1
            }).save().then(() => {
              this.set('state', '');
              this.transitionToRoute('fd-editform-constructor', savedDevClass.get('id'));
            }, (error) => {
              this.set('state', '');
              this.set('error', error);
            });
          }, (error) => {
            this.set('state', '');
            this.set('error', error);
          });
        }, (error) => {
          this.set('state', '');
          this.set('error', error);
        });
      });
    },

    /**
      Handles add list form for class in left jsTree.

      @method actions.addLeftListForm
    */
    addLeftListForm() {
      let jstreeSelectedNodesLeft = this.get('jstreeSelectedNodesLeft');
      if (jstreeSelectedNodesLeft.length === 0) {
        return;
      }

      let selectedNode = jstreeSelectedNodesLeft[0];
      let classId = selectedNode.original.get('idNode');

      this.transitionToRoute('fd-listform-constructor', {
        queryParams: {
          form: undefined,
          class: classId,
        }
      });
    },

    /**
      Handles edit node left jsTree.

      @method actions.editLeftNode
    */
    editLeftNode() {
      let jstreeSelectedNodesLeft = this.get('jstreeSelectedNodesLeft');
      if (jstreeSelectedNodesLeft.length === 0) {
        return;
      }

      let selectedNode = jstreeSelectedNodesLeft[0];
      let nodeId = selectedNode.original.get('idNode');

      switch (selectedNode.original.get('type')) {
        case '«listform»':
          this.transitionToRoute('fd-listform-constructor', {
            queryParams: {
              form: nodeId,
              class: undefined,
            },
          });
          break;
        case '«editform»':
          this.transitionToRoute('fd-editform-constructor', nodeId);
          break;
        case 'implementations':
        case 'notStored':
          this.transitionToRoute('fd-class-edit-form', nodeId);
          break;
      }
    },

    /**
      Handles open class list form.

      @method actions.listLeft
    */
    listLeft() {
      this.transitionToRoute('fd-class-list-form');
    },

    /**
      Handles add url node.

      @method actions.addUrlNode
    */
    addUrlNode() {
      let jstreeSelectedNodesRight = this.get('jstreeSelectedNodesRight');
      if (jstreeSelectedNodesRight.length === 0) {
        return;
      }

      let selectedNodes = jstreeSelectedNodesRight[0].original.get('copyChildren');
      let urlIndex = findFreeNodeTreeNameIndex('NewUrl', '', selectedNodes, 'text');
      let urlId = findFreeNodeTreeID('NU', 0, this.get('jstreeObjectRight'));

      let urlValue = FdAppStructTree.create({
        text: 'NewUrl' + urlIndex,
        type: 'url',
        id: 'NU' + urlId,
        caption: 'NewUrl' + urlIndex,
        description: '',
        url: '',
        a_attr: { title: 'url' }
      });

      selectedNodes.pushObject(urlValue);

      // Restoration tree.
      this._updateTreeData();
      this.get('jstreeActionReceiverRight').send('openNode', jstreeSelectedNodesRight[0]);
    },

    /**
      Handles edit node right jsTree.

      @method actions.editRightNode
    */
    editRightNode() {
      this.send('toggleConfigPanel', 'second', 1);
    },

    /**
      Handles remove node from right jsTree.

      @method actions.removeRightNode
    */
    removeRightNode() {
      let jstreeSelectedNodesRight = this.get('jstreeSelectedNodesRight');
      if (jstreeSelectedNodesRight.length === 0) {
        return;
      }

      // Delete node from parent copyChildren.
      let parentSelectedNode = this.get('jstreeObjectRight').jstree(true).get_node(jstreeSelectedNodesRight[0].parent);
      let arrayChildrensParentSelectedNode = parentSelectedNode.original.get('copyChildren');
      let selectedObject = arrayChildrensParentSelectedNode.findBy('text', jstreeSelectedNodesRight[0].text);
      arrayChildrensParentSelectedNode.removeObject(selectedObject);

      this.get('jstreeActionReceiverRight').send('deleteNode', jstreeSelectedNodesRight[0]);
      this.set('jstreeSelectedNodesRight', Ember.A());
    },

    /**
      Handles add node in right jsTree.

      @method actions.addFolderNode
    */
    addFolderNode() {
      let jstreeSelectedNodesRight = this.get('jstreeSelectedNodesRight');
      if (jstreeSelectedNodesRight.length === 0) {
        return;
      }

      let selectedNodes = jstreeSelectedNodesRight[0].original.get('copyChildren');
      let folderIndex = findFreeNodeTreeNameIndex('NewFolder', '', selectedNodes, 'text');
      let folderId = findFreeNodeTreeID('NF', 0, this.get('jstreeObjectRight'));

      let folder = FdAppStructTree.create({
        text: 'NewFolder' + folderIndex,
        type: 'folder',
        children: Ember.A(),
        copyChildren: Ember.A(),
        id: 'NF' + folderId
      });

      selectedNodes.pushObject(folder);

      // Restoration tree.
      this._updateTreeData();
      this.get('jstreeActionReceiverRight').send('openNode', jstreeSelectedNodesRight[0]);
    },

    /**
      Handles up move tree node.

      @method actions.upRightNode
    */
    upRightNode() {
      let jstreeSelectedNodesRight = this.get('jstreeSelectedNodesRight');
      if (jstreeSelectedNodesRight.length === 0) {
        return;
      }

      let indexSelectedRight = this.get('indexSelectedRight');
      let index = indexSelectedRight.index;
      let array = indexSelectedRight.array;
      let prev = index - 1;
      let node = array[index];
      let prevNode = array[prev];

      array.replace(prev, 1, node);
      array.replace(index, 1, prevNode);

      // Restoration tree.
      this._updateTreeData();
    },

    /**
      Handles down move tree node.

      @method actions.downRightNode
    */
    downRightNode() {
      let jstreeSelectedNodesRight = this.get('jstreeSelectedNodesRight');
      if (jstreeSelectedNodesRight.length === 0) {
        return;
      }

      let indexSelectedRight = this.get('indexSelectedRight');
      let index = indexSelectedRight.index;
      let array = indexSelectedRight.array;
      let next = index + 1;
      let node = array[next];
      let nextNode = array[index];

      array.replace(index, 1, node);
      array.replace(next, 1, nextNode);

      // Restoration tree.
      this._updateTreeData();
    },

    /**
      Handles save in right tree.

      @method actions.saveTree
    */
    saveTree() {
      let dataTree = this.get('model.rightTreeNodes')[0];
      let dataForSave = dataTree.get('copyChildren');

      let record = this.get('model.applications')[0];
      record.set('containersStr', dataForSave);

      if (Ember.isNone(record.get('caption'))) {
        record.set('caption', record.get('name'));
      }

      let _this = this;
      this.get('objectlistviewEventsService').setLoadingState('loading');
      record.save().then(() => {
        _this.get('objectlistviewEventsService').setLoadingState('');
      });
    },

    /**
      Handles open process editor form.

      @method actions.openProcessEditorForm
    */
    openProcessEditorForm() {
      // TODO ProcessEditorForm don't work.
    },

    /**
      Handles open generation form.

      @method actions.openGenerationForm
    */
    openGenerationForm() {
      this.transitionToRoute('fd-generation-process-form.new');
    },

    closeRightpanel() {
      Ember.$('.closable.panel-left').toggle(500);

      if (this.allAttrsHidedn) {
        this.set('popupMessage', t('forms.fd-appstruct-form.close-panel-btn-caption'));
        Ember.$('.panel-wrapper .panel-right').css('width', '50%');
      } else {
        this.set('popupMessage', t('forms.fd-appstruct-form.show-panel-btn-caption'));
        Ember.$('.panel-wrapper .panel-right').css('width', '100%');
      }

      this.toggleProperty('allAttrsHidedn');
    }
  },

  /**
    Method for update data in tree.
    @method _updateTreeData
    @private
  */
  _updateTreeData() {
    let dataTree = this.get('model.rightTreeNodes');
    restorationNodeTree(dataTree, {}, Ember.A(['folder', 'desk']), true);

    this.get('jstreeActionReceiverRight').send('redraw');
  },
});