// Copyright (C) 2009 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.google.gwtexpui.clippy.client;

import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwtexpui.safehtml.client.SafeHtml;
import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
import com.google.gwtexpui.user.client.Tooltip;
import com.google.gwtexpui.user.client.UserAgent;

/**
 * Label which permits the user to easily copy the complete content.
 * <p>
 * If the Flash plugin is available a "movie" is embedded that provides
 * one-click copying of the content onto the system clipboard. The label (if
 * visible) can also be clicked, switching from a label to an input box,
 * allowing the user to copy the text with a keyboard shortcut.
 */
public class CopyableLabel extends Composite implements HasText {
  private static final int SWF_WIDTH = 110;
  private static final int SWF_HEIGHT = 14;
  private static boolean flashEnabled = true;

  static {
    ClippyResources.I.css().ensureInjected();
  }

  public static boolean isFlashEnabled() {
    return flashEnabled;
  }

  public static void setFlashEnabled(final boolean on) {
    flashEnabled = on;
  }

  private static String swfUrl() {
    return ClippyResources.I.swf().getSafeUri().asString();
  }

  private final FlowPanel content;
  private String text;
  private int visibleLen;
  private Label textLabel;
  private TextBox textBox;
  private Button copier;
  private Element swf;

  public CopyableLabel() {
    this("");
  }

  /**
   * Create a new label
   *
   * @param str initial content
   */
  public CopyableLabel(final String str) {
    this(str, true);
  }

  /**
   * Create a new label
   *
   * @param str initial content
   * @param showLabel if true, the content is shown, if false it is hidden from
   *        view and only the copy icon is displayed.
   */
  public CopyableLabel(final String str, final boolean showLabel) {
    content = new FlowPanel();
    initWidget(content);

    text = str;
    visibleLen = text.length();

    if (showLabel) {
      textLabel = new InlineLabel(getText());
      textLabel.setStyleName(ClippyResources.I.css().label());
      textLabel.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(final ClickEvent event) {
          showTextBox();
        }
      });
      content.add(textLabel);
    }

    if (UserAgent.hasJavaScriptClipboard()) {
      copier = new Button(new SafeHtmlBuilder()
          .openElement("img")
          .setAttribute("src", ClippyResources.I.clipboard().getSafeUri().asString())
          .setWidth(14)
          .setHeight(14)
          .closeSelf());
      copier.setStyleName(ClippyResources.I.css().copier());
      Tooltip.addStyle(copier);
      Tooltip.setLabel(copier, CopyableLabelText.I.tooltip());
      copier.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(ClickEvent event) {
          copy();
        }
      });
      copier.addMouseOutHandler(new MouseOutHandler() {
        @Override
        public void onMouseOut(MouseOutEvent event) {
          Tooltip.setLabel(copier, CopyableLabelText.I.tooltip());
        }
      });

      FlowPanel p = new FlowPanel();
      p.getElement().getStyle().setDisplay(Display.INLINE_BLOCK);
      p.add(copier);
      content.add(p);
    } else {
      embedMovie();
    }
  }

  /**
   * Change the text which is displayed in the clickable label.
   *
   * @param text the new preview text, should be shorter than the original text
   *        which would be copied to the clipboard.
   */
  public void setPreviewText(final String text) {
    if (textLabel != null) {
      textLabel.setText(text);
    }
  }

  private void embedMovie() {
    if (copier == null && flashEnabled && !text.isEmpty()
        && UserAgent.Flash.isInstalled()) {
      final String flashVars = "text=" + URL.encodeQueryString(getText());
      final SafeHtmlBuilder h = new SafeHtmlBuilder();

      h.openElement("div");
      h.setStyleName(ClippyResources.I.css().swf());

      h.openElement("object");
      h.setWidth(SWF_WIDTH);
      h.setHeight(SWF_HEIGHT);
      h.setAttribute("classid", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000");
      h.paramElement("movie", swfUrl());
      h.paramElement("FlashVars", flashVars);

      h.openElement("embed");
      h.setWidth(SWF_WIDTH);
      h.setHeight(SWF_HEIGHT);
      h.setAttribute("wmode", "transparent");
      h.setAttribute("type", "application/x-shockwave-flash");
      h.setAttribute("src", swfUrl());
      h.setAttribute("FlashVars", flashVars);
      h.closeSelf();

      h.closeElement("object");
      h.closeElement("div");

      if (swf != null) {
        getElement().removeChild(swf);
      }
      DOM.appendChild(getElement(), swf = SafeHtml.parse(h));
    }
  }

  @Override
  public String getText() {
    return text;
  }

  @Override
  public void setText(final String newText) {
    text = newText;
    visibleLen = newText.length();

    if (textLabel != null) {
      textLabel.setText(getText());
    }
    if (textBox != null) {
      textBox.setText(getText());
      textBox.selectAll();
    }
    embedMovie();
  }

  private void showTextBox() {
    if (textBox == null) {
      textBox = new TextBox();
      textBox.setText(getText());
      textBox.setVisibleLength(visibleLen);
      textBox.setReadOnly(true);
      textBox.addKeyPressHandler(new KeyPressHandler() {
        @Override
        public void onKeyPress(final KeyPressEvent event) {
          if (event.isControlKeyDown() || event.isMetaKeyDown()) {
            switch (event.getCharCode()) {
              case 'c':
              case 'x':
                textBox.addKeyUpHandler(new KeyUpHandler() {
                  @Override
                  public void onKeyUp(final KeyUpEvent event) {
                    Scheduler.get().scheduleDeferred(new Command() {
                      @Override
                      public void execute() {
                        hideTextBox();
                      }
                    });
                  }
                });
                break;
            }
          }
        }
      });
      textBox.addBlurHandler(new BlurHandler() {
        @Override
        public void onBlur(final BlurEvent event) {
          hideTextBox();
        }
      });
      content.insert(textBox, 1);
    }

    textLabel.setVisible(false);
    textBox.setVisible(true);
    Scheduler.get().scheduleDeferred(new Command() {
      @Override
      public void execute() {
        textBox.selectAll();
        textBox.setFocus(true);
      }
    });
  }

  private void hideTextBox() {
    if (textBox != null) {
      textBox.removeFromParent();
      textBox = null;
    }
    textLabel.setVisible(true);
  }

  private void copy() {
    TextBox t = new TextBox();
    try {
      t.setText(getText());
      content.add(t);
      t.setFocus(true);
      t.selectAll();

      boolean ok = execCommand("copy");
      Tooltip.setLabel(copier, ok
          ? CopyableLabelText.I.copied()
          : CopyableLabelText.I.failed());
      if (!ok) {
        // Disable JavaScript clipboard and try flash movie in another instance.
        UserAgent.disableJavaScriptClipboard();
      }
    } finally {
      t.removeFromParent();
    }
  }

  private static boolean execCommand(String command) {
    try {
      return nativeExec(command);
    } catch (Exception e) {
      return false;
    }
  }

  private static native boolean nativeExec(String c)
  /*-{ return !! $doc.execCommand(c) }-*/;
}
