// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.googlesource.gerrit.plugins.labelui.client;

import com.google.gerrit.client.GerritUiExtensionPoint;
import com.google.gerrit.client.Resources;
import com.google.gerrit.plugin.client.Plugin;
import com.google.gerrit.plugin.client.PluginEntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.ui.RootPanel;
import com.googlesource.gerrit.plugins.labelui.client.PreferencesInfo.LabelUi;

public class LabelUIPlugin extends PluginEntryPoint {
  public static final Resources RESOURCES = GWT.create(Resources.class);

  private static final String DEFAULT_LABELS_CLASS =
      "com-google-gerrit-client-change-ChangeScreen_BinderImpl_GenCss_style-labels";
  private static final String HIDE_DEFAULT_LABELS_CLASS =
      Plugin.get().getName() + "-hideDefaultLabels";

  @Override
  public void onPluginLoad() {
    injectCssToHideDefaultLabels();

    Plugin.get()
        .panel(
            GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK,
            new LabelPanel.Factory(),
            null);
    Plugin.get()
        .panel(
            GerritUiExtensionPoint.PREFERENCES_SCREEN_BOTTOM,
            new LabelUiPreferencesPanel.Factory(),
            null);
  }

  public static void refreshDefaultLabelUi(LabelUi ui) {
    if (ui == LabelUi.DEFAULT) {
      showDefaultLabelUi();
    } else {
      hideDefaultLabelUi();
    }
  }

  private static void hideDefaultLabelUi() {
    Element body = RootPanel.getBodyElement();
    if (!body.hasClassName(HIDE_DEFAULT_LABELS_CLASS)) {
      body.addClassName(HIDE_DEFAULT_LABELS_CLASS);
    }
  }

  private static void showDefaultLabelUi() {
    RootPanel.getBodyElement().removeClassName(HIDE_DEFAULT_LABELS_CLASS);
  }

  private static void injectCssToHideDefaultLabels() {
    StringBuilder css = new StringBuilder();
    css.append(".");
    css.append(HIDE_DEFAULT_LABELS_CLASS);
    css.append(" .");
    css.append(DEFAULT_LABELS_CLASS);
    css.append(" {display: none;}");
    injectCss(css.toString());
  }

  private static final native void injectCss(String css)
      /*-{ return $wnd.Gerrit.injectCss(css) }-*/ ;
}
