/*
 * Copyright (c) 2012-2017 Red Hat, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Red Hat, Inc. - initial API and implementation
 */
package org.eclipse.che.ide.command.explorer;

import static com.google.gwt.user.client.Event.ONCLICK;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.Event;
import org.eclipse.che.ide.command.CommandResources;
import org.eclipse.che.ide.command.explorer.CommandsExplorerView.ActionDelegate;
import org.eclipse.che.ide.command.node.CommandFileNode;
import org.eclipse.che.ide.command.node.CommandGoalNode;
import org.eclipse.che.ide.ui.smartTree.Tree;
import org.eclipse.che.ide.ui.smartTree.TreeStyles;
import org.eclipse.che.ide.ui.smartTree.data.Node;
import org.eclipse.che.ide.ui.smartTree.presentation.DefaultPresentationRenderer;
import org.vectomatic.dom.svg.ui.SVGResource;

/**
 * Renderer for the commands tree.
 *
 * @author Artem Zatsarynnyi
 */
class CommandsTreeRenderer extends DefaultPresentationRenderer<Node> {

  private final CommandResources resources;

  private ActionDelegate delegate;

  CommandsTreeRenderer(TreeStyles treeStyles, CommandResources resources, ActionDelegate delegate) {
    super(treeStyles);

    this.resources = resources;
    this.delegate = delegate;
  }

  /** Sets the delegate that will handle events from the rendered DOM elements. */
  void setDelegate(ActionDelegate delegate) {
    this.delegate = delegate;
  }

  @Override
  public Element getPresentableTextContainer(Element content) {
    final Element presentableTextContainer = super.getPresentableTextContainer(content);
    presentableTextContainer.addClassName(resources.commandsExplorerCss().commandNodeText());

    return presentableTextContainer;
  }

  @Override
  public Element render(Node node, String domID, Tree.Joint joint, int depth) {
    final Element element = super.render(node, domID, joint, depth);
    final Element nodeContainerElement = element.getFirstChildElement();

    if (node instanceof CommandFileNode) {
      CommandFileNode commandNode = (CommandFileNode) node;

      nodeContainerElement.setId("command_" + commandNode.getDisplayName());

      renderCommandNode(commandNode, nodeContainerElement);
    } else if (node instanceof CommandGoalNode) {
      CommandGoalNode goalNode = (CommandGoalNode) node;

      nodeContainerElement.setId("goal_" + goalNode.getName());

      renderCommandGoalNode(nodeContainerElement);
    }

    return element;
  }

  private void renderCommandNode(CommandFileNode node, Element nodeContainerElement) {
    nodeContainerElement.addClassName(resources.commandsExplorerCss().commandNode());

    final Element removeCommandButton = createButton(resources.removeCommand());
    Event.setEventListener(
        removeCommandButton,
        event -> {
          if (ONCLICK == event.getTypeInt()) {
            event.stopPropagation();
            delegate.onCommandRemove(node.getData());
          }
        });

    final Element duplicateCommandButton = createButton(resources.duplicateCommand());
    Event.setEventListener(
        duplicateCommandButton,
        event -> {
          if (ONCLICK == event.getTypeInt()) {
            event.stopPropagation();
            delegate.onCommandDuplicate(node.getData());
          }
        });

    final Element buttonsPanel = Document.get().createSpanElement();
    buttonsPanel.setClassName(resources.commandsExplorerCss().commandNodeButtonsPanel());
    buttonsPanel.appendChild(removeCommandButton);
    buttonsPanel.appendChild(duplicateCommandButton);

    nodeContainerElement.appendChild(buttonsPanel);

    removeCommandButton.setId("commands_tree-button-remove");
    duplicateCommandButton.setId("commands_tree-button-duplicate");
  }

  private void renderCommandGoalNode(Element nodeContainerElement) {
    nodeContainerElement.addClassName(resources.commandsExplorerCss().commandGoalNode());

    final Element addCommandButton = createButton(resources.addCommand());

    Event.setEventListener(
        addCommandButton,
        event -> {
          if (ONCLICK == event.getTypeInt()) {
            event.stopPropagation();
            delegate.onCommandAdd(
                addCommandButton.getAbsoluteLeft(), addCommandButton.getAbsoluteTop());
          }
        });

    nodeContainerElement.appendChild(addCommandButton);

    addCommandButton.setId("commands_tree-button-add");
  }

  private Element createButton(SVGResource icon) {
    final Element button = Document.get().createSpanElement();
    button.appendChild(icon.getSvg().getElement());

    Event.sinkEvents(button, ONCLICK);

    return button;
  }
}

@@ -570,33 +570,159 @@
 gle.gwt.
-user.client.Event
+dom.client.SpanElement;%0Aimport com.google.gwt.dom.client.Style;%0Aimport com.google.gwt.user.client.Event;%0Aimport org.eclipse.che.ide.FontAwesome
 ;%0Aimport
@@ -3091,33 +3091,25 @@
 ton(
-resources.removeCommand()
+FontAwesome.TRASH
 );%0A 
@@ -4821,27 +4821,22 @@
 eButton(
-SVGResource
+Object
  icon) %7B
@@ -4926,33 +4926,23 @@
 ild(
-icon.getSvg().get
+getIcon
 Element(
 ));%0A
@@ -4937,16 +4937,20 @@
 Element(
+icon
 ));%0A%0A   
@@ -5008,11 +5008,519 @@
 ton;%0A  %7D
+%0A%0A  private Element getIconElement(Object icon) %7B%0A    if (icon instanceof SVGResource) %7B%0A      return ((SVGResource) icon).getSvg().getElement();%0A    %7D else if (icon instanceof String) %7B%0A      SpanElement element = Document.get().createSpanElement();%0A      element.getStyle().setFontSize(11., Style.Unit.PT);%0A      element.getStyle().setMarginTop(2., Style.Unit.PT);%0A      element.setInnerHTML((String) icon);%0A      return element;%0A    %7D%0A%0A    throw new IllegalArgumentException(%22Icon type is undefined%22);%0A  %7D
 %0A%7D%0A

Use trash icon from FontAwesome for delete command operation (#7951)