/*
 * Copyright 2008 Google Inc.
 * 
 * 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.gwt.sample.showcase.client.content.text;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.i18n.client.Constants;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.RichTextArea;
import com.google.gwt.user.client.ui.ToggleButton;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * A sample toolbar for use with {@link RichTextArea}. It provides a simple UI
 * for all rich text formatting, dynamically displayed only for the available
 * functionality.
 */
@SuppressWarnings("deprecation")
public class RichTextToolbar extends Composite {

  /**
   * This {@link ClientBundle} is used for all the button icons. Using a bundle
   * allows all of these images to be packed into a single image, which saves a
   * lot of HTTP requests, drastically improving startup time.
   */
  public interface Images extends ClientBundle {

    ImageResource bold();

    ImageResource createLink();

    ImageResource hr();

    ImageResource indent();

    ImageResource insertImage();

    ImageResource italic();

    ImageResource justifyCenter();

    ImageResource justifyLeft();

    ImageResource justifyRight();

    ImageResource ol();

    ImageResource outdent();

    ImageResource removeFormat();

    ImageResource removeLink();

    ImageResource strikeThrough();

    ImageResource subscript();

    ImageResource superscript();

    ImageResource ul();

    ImageResource underline();
  }

  /**
   * This {@link Constants} interface is used to make the toolbar's strings
   * internationalizable.
   */
  public interface Strings extends Constants {

    String black();

    String blue();

    String bold();

    String color();

    String createLink();

    String font();

    String green();

    String hr();

    String indent();

    String insertImage();

    String italic();

    String justifyCenter();

    String justifyLeft();

    String justifyRight();

    String large();

    String medium();

    String normal();

    String ol();

    String outdent();

    String red();

    String removeFormat();

    String removeLink();

    String size();

    String small();

    String strikeThrough();

    String subscript();

    String superscript();

    String ul();

    String underline();

    String white();

    String xlarge();

    String xsmall();

    String xxlarge();

    String xxsmall();

    String yellow();
  }

  /**
   * We use an inner EventHandler class to avoid exposing event methods on the
   * RichTextToolbar itself.
   */
  private class EventHandler implements ClickHandler, ChangeHandler,
      KeyUpHandler {

    public void onChange(ChangeEvent event) {
      Widget sender = (Widget) event.getSource();

      if (sender == backColors) {
        basic.setBackColor(backColors.getValue(backColors.getSelectedIndex()));
        backColors.setSelectedIndex(0);
      } else if (sender == foreColors) {
        basic.setForeColor(foreColors.getValue(foreColors.getSelectedIndex()));
        foreColors.setSelectedIndex(0);
      } else if (sender == fonts) {
        basic.setFontName(fonts.getValue(fonts.getSelectedIndex()));
        fonts.setSelectedIndex(0);
      } else if (sender == fontSizes) {
        basic.setFontSize(fontSizesConstants[fontSizes.getSelectedIndex() - 1]);
        fontSizes.setSelectedIndex(0);
      }
    }

    public void onClick(ClickEvent event) {
      Widget sender = (Widget) event.getSource();

      if (sender == bold) {
        basic.toggleBold();
      } else if (sender == italic) {
        basic.toggleItalic();
      } else if (sender == underline) {
        basic.toggleUnderline();
      } else if (sender == subscript) {
        basic.toggleSubscript();
      } else if (sender == superscript) {
        basic.toggleSuperscript();
      } else if (sender == strikethrough) {
        extended.toggleStrikethrough();
      } else if (sender == indent) {
        extended.rightIndent();
      } else if (sender == outdent) {
        extended.leftIndent();
      } else if (sender == justifyLeft) {
        basic.setJustification(RichTextArea.Justification.LEFT);
      } else if (sender == justifyCenter) {
        basic.setJustification(RichTextArea.Justification.CENTER);
      } else if (sender == justifyRight) {
        basic.setJustification(RichTextArea.Justification.RIGHT);
      } else if (sender == insertImage) {
        String url = Window.prompt("Enter an image URL:", "http://");
        if (url != null) {
          extended.insertImage(url);
        }
      } else if (sender == createLink) {
        String url = Window.prompt("Enter a link URL:", "http://");
        if (url != null) {
          extended.createLink(url);
        }
      } else if (sender == removeLink) {
        extended.removeLink();
      } else if (sender == hr) {
        extended.insertHorizontalRule();
      } else if (sender == ol) {
        extended.insertOrderedList();
      } else if (sender == ul) {
        extended.insertUnorderedList();
      } else if (sender == removeFormat) {
        extended.removeFormat();
      } else if (sender == richText) {
        // We use the RichTextArea's onKeyUp event to update the toolbar status.
        // This will catch any cases where the user moves the cursur using the
        // keyboard, or uses one of the browser's built-in keyboard shortcuts.
        updateStatus();
      }
    }

    public void onKeyUp(KeyUpEvent event) {
      Widget sender = (Widget) event.getSource();
      if (sender == richText) {
        // We use the RichTextArea's onKeyUp event to update the toolbar status.
        // This will catch any cases where the user moves the cursur using the
        // keyboard, or uses one of the browser's built-in keyboard shortcuts.
        updateStatus();
      }
    }
  }

  private static final RichTextArea.FontSize[] fontSizesConstants = new RichTextArea.FontSize[] {
      RichTextArea.FontSize.XX_SMALL, RichTextArea.FontSize.X_SMALL,
      RichTextArea.FontSize.SMALL, RichTextArea.FontSize.MEDIUM,
      RichTextArea.FontSize.LARGE, RichTextArea.FontSize.X_LARGE,
      RichTextArea.FontSize.XX_LARGE};

  private Images images = (Images) GWT.create(Images.class);
  private Strings strings = (Strings) GWT.create(Strings.class);
  private EventHandler handler = new EventHandler();

  private RichTextArea richText;
  private RichTextArea.BasicFormatter basic;
  private RichTextArea.ExtendedFormatter extended;

  private VerticalPanel outer = new VerticalPanel();
  private HorizontalPanel topPanel = new HorizontalPanel();
  private HorizontalPanel bottomPanel = new HorizontalPanel();
  private ToggleButton bold;
  private ToggleButton italic;
  private ToggleButton underline;
  private ToggleButton subscript;
  private ToggleButton superscript;
  private ToggleButton strikethrough;
  private PushButton indent;
  private PushButton outdent;
  private PushButton justifyLeft;
  private PushButton justifyCenter;
  private PushButton justifyRight;
  private PushButton hr;
  private PushButton ol;
  private PushButton ul;
  private PushButton insertImage;
  private PushButton createLink;
  private PushButton removeLink;
  private PushButton removeFormat;

  private ListBox backColors;
  private ListBox foreColors;
  private ListBox fonts;
  private ListBox fontSizes;

  /**
   * Creates a new toolbar that drives the given rich text area.
   * 
   * @param richText the rich text area to be controlled
   */
  public RichTextToolbar(RichTextArea richText) {
    this.richText = richText;
    this.basic = richText.getBasicFormatter();
    this.extended = richText.getExtendedFormatter();

    outer.add(topPanel);
    outer.add(bottomPanel);
    topPanel.setWidth("100%");
    bottomPanel.setWidth("100%");

    initWidget(outer);
    setStyleName("gwt-RichTextToolbar");
    richText.addStyleName("hasRichTextToolbar");

    if (basic != null) {
      topPanel.add(bold = createToggleButton(images.bold(), strings.bold()));
      topPanel.add(italic = createToggleButton(images.italic(),
          strings.italic()));
      topPanel.add(underline = createToggleButton(images.underline(),
          strings.underline()));
      topPanel.add(subscript = createToggleButton(images.subscript(),
          strings.subscript()));
      topPanel.add(superscript = createToggleButton(images.superscript(),
          strings.superscript()));
      topPanel.add(justifyLeft = createPushButton(images.justifyLeft(),
          strings.justifyLeft()));
      topPanel.add(justifyCenter = createPushButton(images.justifyCenter(),
          strings.justifyCenter()));
      topPanel.add(justifyRight = createPushButton(images.justifyRight(),
          strings.justifyRight()));
    }

    if (extended != null) {
      topPanel.add(strikethrough = createToggleButton(images.strikeThrough(),
          strings.strikeThrough()));
      topPanel.add(indent = createPushButton(images.indent(), strings.indent()));
      topPanel.add(outdent = createPushButton(images.outdent(),
          strings.outdent()));
      topPanel.add(hr = createPushButton(images.hr(), strings.hr()));
      topPanel.add(ol = createPushButton(images.ol(), strings.ol()));
      topPanel.add(ul = createPushButton(images.ul(), strings.ul()));
      topPanel.add(insertImage = createPushButton(images.insertImage(),
          strings.insertImage()));
      topPanel.add(createLink = createPushButton(images.createLink(),
          strings.createLink()));
      topPanel.add(removeLink = createPushButton(images.removeLink(),
          strings.removeLink()));
      topPanel.add(removeFormat = createPushButton(images.removeFormat(),
          strings.removeFormat()));
    }

    if (basic != null) {
      bottomPanel.add(backColors = createColorList("Background"));
      bottomPanel.add(foreColors = createColorList("Foreground"));
      bottomPanel.add(fonts = createFontList());
      bottomPanel.add(fontSizes = createFontSizes());

      // We only use these handlers for updating status, so don't hook them up
      // unless at least basic editing is supported.
      richText.addKeyUpHandler(handler);
      richText.addClickHandler(handler);
    }
  }

  private ListBox createColorList(String caption) {
    ListBox lb = new ListBox();
    lb.addChangeHandler(handler);
    lb.setVisibleItemCount(1);

    lb.addItem(caption);
    lb.addItem(strings.white(), "white");
    lb.addItem(strings.black(), "black");
    lb.addItem(strings.red(), "red");
    lb.addItem(strings.green(), "green");
    lb.addItem(strings.yellow(), "yellow");
    lb.addItem(strings.blue(), "blue");
    return lb;
  }

  private ListBox createFontList() {
    ListBox lb = new ListBox();
    lb.addChangeHandler(handler);
    lb.setVisibleItemCount(1);

    lb.addItem(strings.font(), "");
    lb.addItem(strings.normal(), "");
    lb.addItem("Times New Roman", "Times New Roman");
    lb.addItem("Arial", "Arial");
    lb.addItem("Courier New", "Courier New");
    lb.addItem("Georgia", "Georgia");
    lb.addItem("Trebuchet", "Trebuchet");
    lb.addItem("Verdana", "Verdana");
    return lb;
  }

  private ListBox createFontSizes() {
    ListBox lb = new ListBox();
    lb.addChangeHandler(handler);
    lb.setVisibleItemCount(1);

    lb.addItem(strings.size());
    lb.addItem(strings.xxsmall());
    lb.addItem(strings.xsmall());
    lb.addItem(strings.small());
    lb.addItem(strings.medium());
    lb.addItem(strings.large());
    lb.addItem(strings.xlarge());
    lb.addItem(strings.xxlarge());
    return lb;
  }

  private PushButton createPushButton(ImageResource img, String tip) {
    PushButton pb = new PushButton(new Image(img));
    pb.addClickHandler(handler);
    pb.setTitle(tip);
    return pb;
  }

  private ToggleButton createToggleButton(ImageResource img, String tip) {
    ToggleButton tb = new ToggleButton(new Image(img));
    tb.addClickHandler(handler);
    tb.setTitle(tip);
    return tb;
  }

  /**
   * Updates the status of all the stateful buttons.
   */
  private void updateStatus() {
    if (basic != null) {
      bold.setDown(basic.isBold());
      italic.setDown(basic.isItalic());
      underline.setDown(basic.isUnderlined());
      subscript.setDown(basic.isSubscript());
      superscript.setDown(basic.isSuperscript());
    }

    if (extended != null) {
      strikethrough.setDown(extended.isStrikethrough());
    }
  }
}
