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

import com.airlock.iam.plugin.configeditor.session.PropertyGroupsCache;
import com.airlock.iam.plugin.configeditor.util.GuiResources;
import com.airlock.iam.plugin.framework.application.configuration.MutablePluginConfiguration;
import com.vaadin.server.Sizeable.Unit;
import com.vaadin.shared.ui.MarginInfo;
import com.vaadin.ui.Component;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.NativeButton;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.List;

public class FoldBox extends VerticalLayout implements ClickListener {
   private NativeButton foldButton;
   private FormLayout foldFormLayout;
   private final int orderId;
   private final List<String> properties;
   private boolean hasErrorsOnProperties;
   private boolean hasLicenseViolatingProperties;
   private final String identifier;

   public static String identifierOf(MutablePluginConfiguration pc, String groupId) {
      return groupId + pc.getUuid();
   }

   public FoldBox(MutablePluginConfiguration pc, String groupIdentifier, int order, boolean groupOpen) {
      this.identifier = identifierOf(pc, groupIdentifier);
      this.initFoldButton(groupIdentifier);
      this.initFormLayout();
      if (groupOpen) {
         this.setFoldBoxOpen();
      }

      this.orderId = order;
      this.properties = new ArrayList<>();
      this.addComponent(this.foldButton);
      this.addComponent(this.foldFormLayout);
      this.setSpacing(false);
      this.setMargin(false);
   }

   public FoldBox(MutablePluginConfiguration pc, Object propertyId, Component component, String groupIdentifier, int order) {
      this(pc, groupIdentifier, order, false);
      this.properties.add(propertyId.toString());
      this.foldFormLayout.addComponent(component);
   }

   private void initFoldButton(String groupIdentifier) {
      this.foldButton = new NativeButton(groupIdentifier);
      this.foldButton.setWidth(100.0F, Unit.PERCENTAGE);
      this.foldButton.addStyleName("group");
      this.foldButton.addClickListener(this);
   }

   private void initFormLayout() {
      this.foldFormLayout = new FormLayout();
      this.foldFormLayout.addStyleName("plugin-fields-form");
      this.foldFormLayout.setVisible(false);
      this.foldFormLayout.setSizeFull();
      this.foldFormLayout.setMargin(new MarginInfo(true, false, true, true));
   }

   public void buttonClick(ClickEvent event) {
      boolean isVisible = this.foldFormLayout.isVisible();
      this.foldFormLayout.setVisible(!isVisible);
      this.changeButtonStyle(isVisible);
      PropertyGroupsCache.get().setOpen(this.identifier, !isVisible);
   }

   private void changeButtonStyle(boolean isVisible) {
      if (isVisible) {
         this.foldButton.removeStyleName("pressed");
      } else {
         this.foldButton.addStyleName("pressed");
      }
   }

   public void addComponentToFoldBox(Object propertyId, Component component) {
      this.properties.add(propertyId.toString());
      this.foldFormLayout.addComponent(component);
   }

   public int getOrderId() {
      return this.orderId;
   }

   public void setErrorsOnProperties(boolean hasErrors) {
      this.hasErrorsOnProperties = hasErrors;
   }

   public void setLicenseViolationsOnProperties(boolean hasLicenseViolations) {
      this.hasLicenseViolatingProperties = hasLicenseViolations;
   }

   public void setValidationStateOnUI() {
      if (this.hasLicenseViolatingProperties) {
         this.foldButton.setIcon(GuiResources.ICON_VALIDATION_WARNING);
      } else if (this.hasErrorsOnProperties) {
         this.foldButton.setIcon(GuiResources.ICON_VALIDATION_ERROR);
      } else {
         this.foldButton.setIcon(null);
      }
   }

   public boolean containsPropertyWithName(String propertyName) {
      return this.properties.contains(propertyName);
   }

   public final void setFoldBoxOpen() {
      if (!this.foldFormLayout.isVisible()) {
         this.foldButton.click();
      }
   }

   public boolean isEmpty() {
      return this.properties.isEmpty();
   }

   @SuppressFBWarnings(justification = "generated code")
   public String getIdentifier() {
      return this.identifier;
   }
}
