/*
 * Copyright 2010 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.app.client;

import com.google.gwt.animation.client.Animation;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.SpanElement;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;

/**
 * <p>
 * <span style="color:red">Experimental API: This class is still under rapid
 * development, and is very likely to be deleted. Use it at your own risk.
 * </span>
 * </p>
 * Simple widget for providing notification feedback.
 */
public class NotificationMole extends Composite {
  /**
   * Default CSS styles for this widget.
   */
  public interface Style extends CssResource {
    String container();

    String notificationText();
  }

  interface Binder extends UiBinder<HTMLPanel, NotificationMole> {
  }

  private class MoleAnimation extends Animation {
    private int endSize;
    private int startSize;

    @Override
    protected void onComplete() {
      if (endSize == 0) {
        borderElement.getStyle().setDisplay(Display.NONE);
        return;
      }
      borderElement.getStyle().setHeight(endSize, Unit.PX);
    }

    @Override
    protected void onUpdate(double progress) {
      double delta = (endSize - startSize) * progress;
      double newSize = startSize + delta;
      borderElement.getStyle().setHeight(newSize, Unit.PX);
    }

    void animateMole(int startSize, int endSize, int duration) {
      this.startSize = startSize;
      this.endSize = endSize;
      if (duration == 0) {
        onComplete();
        return;
      }
      run(duration);
    }
  }

  private static final Binder BINDER = GWT.create(Binder.class);

  @UiField()
  DivElement borderElement;

  @UiField
  DivElement heightMeasure;

  @UiField()
  SpanElement notificationText;

  int showAttempts = 0;

  Timer showTimer = new Timer() {
    @Override
    public void run() {
      if (showAttempts > 0) {
        showImpl();
      }
    }
  };

  private final MoleAnimation animation = new MoleAnimation();

  private int animationDuration;

  public NotificationMole() {
    initWidget(BINDER.createAndBindUi(this));
  }

  /**
   * Hides the notification.
   */
  public void hide() {
    if (showAttempts > 0) {
      --showAttempts;
    }
    if (showAttempts == 0) {
      animation.animateMole(heightMeasure.getOffsetHeight(), 0,
          animationDuration);
      return;
    }
  }

  /**
   * Force mole to hide and discard outstanding show attempts.
   */
  public void hideNow() {
    showAttempts = 0;
    animation.animateMole(heightMeasure.getOffsetHeight(), 0, animationDuration);
  }

  /**
   * Sets the animation duration in milliseconds. The animation duration
   * defaults to 0 if this method is never called.
   * 
   * @param duration the animation duration in milliseconds.
   */
  public void setAnimationDuration(int duration) {
    this.animationDuration = duration;
  }

  /**
   * Sets the message text to be displayed.
   * 
   * @param message the text to be displayed.
   */
  public void setMessage(String message) {
    notificationText.setInnerText(message);
  }

  /**
   * Display the notification with the existing message.
   */
  public void show() {
    ++showAttempts;
    showImpl();
  }

  /**
   * Set the message text and then display the notification.
   */
  public void show(String message) {
    setMessage(message);
    show();
  }

  /**
   * Display the notification, but after a delay.
   * 
   * @param delay delay in milliseconds.
   */
  public void showDelayed(int delay) {
    if (showAttempts == 0) {
      if (delay == 0) {
        show();
      } else {
        ++showAttempts;
        showTimer.schedule(delay);
      }
    }
  }

  private void showImpl() {
    borderElement.getStyle().setDisplay(Display.BLOCK);
    borderElement.getStyle().setWidth(notificationText.getOffsetWidth(),
        Unit.PX);
    animation.animateMole(0, heightMeasure.getOffsetHeight(), animationDuration);
  }
}
