/*
 * 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.ui.multisplitpanel.menu;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import org.vectomatic.dom.svg.ui.SVGResource;

/**
 * Widget that represents the {@link Menu}.
 *
 * @author Artem Zatsarynnyi
 */
public class MenuWidget extends Composite implements Menu {

  private static final String GWT_POPUP_STANDARD_STYLE = "gwt-PopupPanel";
  private static final ListButtonWidgetUiBinder UI_BINDER =
      GWT.create(ListButtonWidgetUiBinder.class);

  @UiField(provided = true)
  final Resources resources;

  private final PopupPanel popupPanel;
  private final FlowPanel listPanel;

  private ActionDelegate delegate;
  private long closeTime;

  private MenuItem.ActionDelegate itemDelegate =
      new MenuItem.ActionDelegate() {

        @Override
        public void onItemSelected(MenuItem menuItem) {
          popupPanel.hide();
          if (delegate != null) {
            delegate.onMenuItemSelected(menuItem);
          }
        }

        @Override
        public void onItemClosing(MenuItem menuItem) {
          popupPanel.hide();
          if (delegate != null) {
            delegate.onMenuItemClosing(menuItem);
          }
        }
      };

  @Inject
  public MenuWidget(Resources resources) {
    this.resources = resources;
    resources.css().ensureInjected();

    initWidget(UI_BINDER.createAndBindUi(this));

    closeTime = System.currentTimeMillis();
    addDomHandler(
        new MouseDownHandler() {
          @Override
          public void onMouseDown(MouseDownEvent event) {
            long time = System.currentTimeMillis();
            if (time - closeTime < 100) {
              return;
            }
            showList();
          }
        },
        MouseDownEvent.getType());

    listPanel = new FlowPanel();
    listPanel.addStyleName(resources.css().listItemPanel());

    popupPanel = new PopupPanel();
    popupPanel.setAutoHideEnabled(true);
    popupPanel.removeStyleName(GWT_POPUP_STANDARD_STYLE);
    popupPanel.add(listPanel);

    popupPanel.addCloseHandler(
        new CloseHandler<PopupPanel>() {
          @Override
          public void onClose(CloseEvent<PopupPanel> event) {
            closeTime = System.currentTimeMillis();
          }
        });
  }

  public void showList() {
    int x = getAbsoluteLeft() + getOffsetWidth() - 6;
    int y = getAbsoluteTop() + 19;

    popupPanel.show();
    popupPanel.getElement().getStyle().setProperty("position", "absolute");
    popupPanel.getElement().getStyle().clearProperty("left");
    popupPanel.getElement().getStyle().setProperty("right", "calc(100% - " + x + "px");
    popupPanel.getElement().getStyle().setProperty("top", "" + y + "px");
  }

  @Override
  public void addListItem(MenuItem menuItem) {
    menuItem.setDelegate(itemDelegate);
    listPanel.add(menuItem);
  }

  @Override
  public void removeListItem(MenuItem menuItem) {
    listPanel.remove(menuItem);
  }

  @Override
  public void setDelegate(ActionDelegate delegate) {
    this.delegate = delegate;
  }

  public interface Resources extends ClientBundle {
    @Source({"style.css", "org/eclipse/che/ide/api/ui/style.css"})
    Resources.Styles css();

    @Source("multi-file-icon.svg")
    SVGResource multiFileIcon();

    interface Styles extends CssResource {
      String listItemPanel();
    }
  }

  interface ListButtonWidgetUiBinder extends UiBinder<Widget, MenuWidget> {}
}

@@ -876,16 +876,58 @@
 iField;%0A
+import com.google.gwt.user.client.Window;%0A
 import c
@@ -3376,44 +3376,8 @@
  6;%0A
-    int y = getAbsoluteTop() + 19;%0A%0A
     
@@ -3391,24 +3391,24 @@
 nel.show();%0A
+
     popupPan
@@ -3629,75 +3629,26 @@
     
-popupPanel.getElement().getStyle().setProperty(%22top%22, %22%22 + y + %22px%22
+adjustTopPosition(
 );%0A 
@@ -3771,32 +3771,57 @@
 .add(menuItem);%0A
+    adjustTopPosition();%0A
   %7D%0A%0A  @Override
@@ -3867,24 +3867,24 @@
 menuItem) %7B%0A
-
     listPane
@@ -3903,16 +3903,617 @@
 uItem);%0A
+    adjustTopPosition();%0A  %7D%0A%0A  /** Fix top value if need. Need in case if bottom part of menu not display */%0A  private void adjustTopPosition() %7B%0A    int totalHeight = listPanel.getWidgetCount() * 19; // 19 height of menu item%0A    int y = getAbsoluteTop() + 19 + totalHeight;%0A    if (y %3E Window.getClientHeight()) %7B%0A      y = getAbsoluteTop() - 8 - totalHeight; // 8 need some correction for looking good in UI%0A      popupPanel.getElement().getStyle().clearProperty(%22top%22);%0A    %7D else %7B%0A      y = getAbsoluteTop() + 19;%0A    %7D%0A    popupPanel.getElement().getStyle().setProperty(%22top%22, %22%22 + y + %22px%22);%0A
   %7D%0A%0A  @

Fix menu position: if not enough space under button will be shown above (#7283)