package com.airlock.iam.plugin.configeditor.ui.visibility;

import com.airlock.iam.plugin.configeditor.ConfigEditorApplication;
import com.airlock.iam.plugin.configeditor.util.FontAwesomeExtended;
import com.vaadin.server.FontAwesome;
import com.vaadin.server.FontIcon;
import com.vaadin.server.Sizeable.Unit;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.VerticalSplitPanel;

public final class UiToggles extends HorizontalLayout {
   private final Button headerToggle;
   private final Button tabsheetToggle;
   private final Button treeToggle;

   public UiToggles() {
      this.setWidth("100%");
      this.addStyleName("ui-toggles");
      this.headerToggle = this.addHeaderToggle();
      this.tabsheetToggle = this.addTabsheetToggle();
      this.treeToggle = this.addTreeToggle();
      this.addComponents(new Component[]{this.treeToggle, this.tabsheetToggle, this.headerToggle});
      this.setComponentAlignment(this.headerToggle, Alignment.MIDDLE_RIGHT);
      this.setComponentAlignment(this.tabsheetToggle, Alignment.MIDDLE_RIGHT);
      this.setExpandRatio(this.treeToggle, 1.0F);
   }

   public boolean isPluginTreeVisible() {
      return this.treeToggle.getData() != null;
   }

   private boolean isViewTabSheetVisible() {
      return this.tabsheetToggle.getData() != null;
   }

   public void toggleTree() {
      this.treeToggle.click();
   }

   public void toggleTabsheet() {
      this.tabsheetToggle.click();
   }

   public void toggleHeader() {
      this.headerToggle.click();
   }

   public void resetTabsheetPosition() {
      if (this.isViewTabSheetVisible()) {
         this.setInitialTabsheetPosition();
      } else {
         this.toggleTabsheet();
      }
   }

   private Button buildToggleButton(String description, FontIcon icon, String id) {
      Button toggle = new Button();
      toggle.setDescription(description);
      toggle.setIcon(icon);
      toggle.setId(id);
      toggle.addStyleNames(new String[]{"ui-toggle", id, "borderless"});
      toggle.setData("show");
      return toggle;
   }

   private Button addTreeToggle() {
      Button toggle = this.buildToggleButton("Show/Hide Plugin Tree (ALT + CTRL + A)", FontAwesome.BARS, "tree-toggle");
      toggle.addClickListener(event -> {
         if (toggle.getData() != null) {
            this.horizontalSplit().setSplitPosition(0.0F, Unit.PIXELS);
            this.horizontalSplit().setLocked(true);
            toggle.setData(null);
         } else {
            this.horizontalSplit().setSplitPosition(275.0F, Unit.PIXELS);
            this.horizontalSplit().setLocked(false);
            toggle.setData("show");
         }
      });
      return toggle;
   }

   private Button addTabsheetToggle() {
      Button toggle = this.buildToggleButton("Show/Hide Tabsheet (ALT + CTRL + S)", FontAwesomeExtended.WINDOW_MAXIMIZE, "tabsheet-toggle");
      toggle.addClickListener(event -> {
         if (toggle.getData() != null) {
            this.verticalSplit().setSplitPosition(0.0F, Unit.PIXELS, true);
            this.verticalSplit().setLocked(true);
            toggle.setData(null);
         } else {
            this.verticalSplit().setLocked(false);
            this.setInitialTabsheetPosition();
            toggle.setData("show");
         }
      });
      return toggle;
   }

   private Button addHeaderToggle() {
      Button toggle = this.buildToggleButton("Show/Hide Header (ALT + CTRL + D)", FontAwesomeExtended.WINDOW_MAXIMIZE, "header-toggle");
      toggle.addClickListener(event -> {
         if (toggle.getData() != null) {
            this.getApplication().getHeaderUI().setVisible(false);
            toggle.setData(null);
         } else {
            this.getApplication().getHeaderUI().setVisible(true);
            toggle.setData("show");
         }
      });
      return toggle;
   }

   private void setInitialTabsheetPosition() {
      float splitPosition = this.verticalSplit().getSplitPosition();
      if (splitPosition < 300.0F) {
         this.verticalSplit().setSplitPosition(300.0F, Unit.PIXELS, true);
      }
   }

   private HorizontalSplitPanel horizontalSplit() {
      return this.getApplication().getHorizontalSplit();
   }

   private VerticalSplitPanel verticalSplit() {
      return this.getApplication().getVerticalSplit();
   }

   private ConfigEditorApplication getApplication() {
      return (ConfigEditorApplication)this.getUI();
   }
}
