/*
 * 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.i18n.client;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * A tag interface that facilitates locale-sensitive, compile-time binding of
 * messages supplied from various sources.Using
 * <code>GWT.create(<i>class</i>)</code> to "instantiate" an interface that
 * extends <code>Messages</code> returns an instance of an automatically
 * generated subclass that is implemented using message templates selected based
 * on locale. Message templates are based on a subset of the format used by <a
 * href="http://java.sun.com/j2se/1.5.0/docs/api/java/text/MessageFormat.html">
 * <code>MessageFormat</code></a>.  Note in particular that single quotes are
 * used to quote other characters, and should be doubled for a literal single
 * quote.
 * 
 * <p>
 * Locale is specified at run time using a meta tag or query string as described
 * for {@link com.google.gwt.i18n.client.Localizable}.
 * </p>
 * 
 * <h3>Extending <code>Messages</code></h3>
 * To use <code>Messages</code>, begin by defining an interface that extends
 * it. Each interface method is referred to as a <i>message accessor</i>, and
 * its corresponding message template is loaded based on the key for that
 * method. The default key is simply the unqualified name of the method, but can
 * be specified directly with an {@code @Key} annotation or a different
 * generation method using {@code @GenerateKeys}. Additionally, if
 * plural forms are used on a given method the plural form is added as a suffix
 * to the key, such as <code>widgets[one]</code> for the singular version of
 * the <code>widgets</code> message. The resulting key is used to find
 * translated versions of the message from any supported input file, such as
 * Java properties files. For example,
 * 
 * {@example com.google.gwt.examples.i18n.GameStatusMessages}
 * 
 * expects to find properties named <code>turnsLeft</code> and
 * <code>currentScore</code> in an associated properties file, formatted as
 * message templates taking two arguments and one argument, respectively. For
 * example, the following properties would correctly bind to the
 * <code>GameStatusMessages</code> interface:
 * 
 * {@gwt.include com/google/gwt/examples/i18n/GameStatusMessages.properties}
 * 
 * <p>
 * The following example demonstrates how to use constant accessors defined in
 * the interface above:
 * 
 * {@example com.google.gwt.examples.i18n.GameStatusMessagesExample#beginNewGameRound(String)}
 * </p>
 * 
 * <p>The following example shows how to use annotations to store the default strings
 * in the source file itself, rather than needing a properties file (you still need
 * properties files for the translated strings):
 * 
 * {@example com.google.gwt.examples.i18n.GameStatusMessagesAnnot}
 * </p>
 * 
 * <p>In this example, calling <code>msg.turnsLeft("John", 13)</code> would
 * return the string <code>"Turns left for player 'John': 13"</code>.
 * </p>
 * 
 * <h3>Defining Message Accessors</h3>
 * Message accessors must be of the form
 * 
 * <pre>String methodName(<i>optional-params</i>)</pre>
 * 
 * and parameters may be of any type. Arguments are converted into strings at
 * runtime using Java string concatenation syntax (the '+' operator), which
 * uniformly handles primitives, <code>null</code>, and invoking
 * <code>toString()</code> to format objects.
 * 
 * <p>
 * Compile-time checks are performed to ensure that the number of placeholders
 * in a message template (e.g. <code>{0}</code>) matches the number of
 * parameters supplied.
 * </p>
 * 
 * <p>
 * Integral arguments may be used to select the proper plural form to use for
 * different locales. To do this, mark the particular argument with
 * {@code @PluralCount} (a plural rule may be specified with
 * {@code @PluralCount} if necessary, but you will almost never need to
 * do this). The actual plural forms for the default locale can be supplied in a
 * {@code @PluralText} annotation on the method, such as
 * <code>@PluralText({"one", "You have one widget"})</code>, or they can be
 * supplied in the properties file as {@code methodkey[one]=You have one widget}. Note
 * that non-default plural forms are not inherited between locales, because the
 * different locales may have different plural rules (especially {@code default} and
 * anything else and those which use different scripts such as {@code sr_Cyrl} and
 * {@code sr_Latn} [one of which would likely be the default], but also subtle cases
 * like {@code pt} and {@code pt_BR}).
 * </p>
 * 
 * <p>
 * Additionally, individual arguments can be marked as optional (ie, GWT will
 * not give an error if a particular translation does not reference the
 * argument) with the {@code @Optional} annotation, and an example may be supplied to
 * the translator with the {@code @Example(String)} annotation.
 * </p>
 * 
 * <h3>Complete Annotations Example</h3>
 * In addition to the default properties file, default text and additional
 * metadata may be stored in the source file itself using annotations. A
 * complete example of using annotations in this way is:
 * 
 * <code><pre>
 * &#64;Generate(format = "com.google.gwt.i18n.rebind.format.PropertiesFormat")
 * &#64;DefaultLocale("en_US")
 * public interface MyMessages extends Messages {
 *   &#64;Key("1234")
 *   &#64;DefaultText("This is a plain string.")
 *   String oneTwoThreeFour();
 *   
 *   &#64;DefaultText("You have {0} widgets")
 *   &#64;PluralText({"one", "You have one widget")
 *   String widgetCount(&#64;PluralCount int count);
 *   
 *   &#64;DefaultText("No reference to the argument")
 *   String optionalArg(&#64;Optional String ignored);
 *   
 *   &#64;DefaultText("Your cart total is {0,number,currency}")
 *   &#64;Description("The total value of the items in the shopping cart in local currency")
 *   String totalAmount(&#64;Example("$5.00") double amount);
 *   
 *   &#64;Meaning("the color")
 *   &#64;DefaultMessage("orange")
 *   String orangeColor();
 *   
 *   &#64;Meaning("the fruit")
 *   &#64;DefaultMessage("orange")
 *   String orangeFruit();
 * }
 * </pre></code>
 * 
 * <h3>Binding to Properties Files</h3>
 * Interfaces extending <code>Messages</code> are bound to resource files
 * using the same algorithm as interfaces extending <code>Constants</code>.
 * See the documentation for {@link Constants} for a description of the
 * algorithm.
 * 
 * <h3>Required Module</h3>
 * Modules that use this interface should inherit
 * <code>com.google.gwt.i18n.I18N</code>.
 * 
 * {@gwt.include com/google/gwt/examples/i18n/InheritsExample.gwt.xml}
 * 
 * <h3>Note</h3>
 * You should not directly implement this interface or interfaces derived from
 * it since an implementation is generated automatically when message interfaces
 * are created using {@link com.google.gwt.core.client.GWT#create(Class)}.
 */
public interface Messages extends LocalizableResource {

  /**
   * Default text to be used if no translation is found (and also used as the
   * source for translation). Format should be that expected by
   * {@link java.text.MessageFormat}.
   * 
   * <p>Example:
   * <code><pre>
   *   &#64;DefaultMessage("Don''t panic - you have {0} widgets left")
   *   String example(int count)
   * </pre></code>
   * </p>
   */
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.METHOD)
  @Documented
  public @interface DefaultMessage {
    String value();
  }

  /**
   * An example of the annotated parameter to assist translators.
   * 
   * <p>Example:
   * <code><pre>
   *   String example(&#64;Example("/etc/passwd") String fileName)
   * </pre></code>
   * </p>
   */
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.PARAMETER)
  public @interface Example {
    String value();
  }


  /**
   * Ignored except on parameters also tagged with {@link PluralCount}, and
   * provides an offset to be subtracted from the value before a plural rule
   * is chosen or the value is formatted.  Note that "=n" forms are evaluated
   * before this offset is applied.
   * 
   * <p>Example:
   * <code><pre>
   *   &#64;PluralText({"=0", "No one has recommended this movie",
   *     "=1", "{0} has recommended this movie",
   *     "=2", "{0} and {1} have recommended this movie",
   *     "one", "{0}, {1} and one other have recommended this movie"})
   *   &#64;DefaultMessage("{0}, {1} and {2,number} others have recommended this movie")
   *   String recommenders(&#64;Optional String rec1, &#64;Optional String rec2,
   *     &#64;PluralCount &#64;Offset(2) int count);
   * </pre></code>
   * would result in
   * <code><pre>
   * recommenders("John", null, 1) => "John has..."
   * recommenders("John", "Jane", 3) => "John, Jane, and one other..."
   * recommenders("John", "Jane", 1402) => "John, Jane, and 1,400 others..."
   * </pre></code>
   * </p>
   */
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.PARAMETER)
  public @interface Offset {
    int value();
  }

  /**
   * Indicates the specified parameter is optional and need not appear in a
   * particular translation of this message.
   * 
   * <p>Example:
   * <code><pre>
   *   String example(&#64;Optional int count)
   * </pre></code>
   * </p>
   */
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.PARAMETER)
  public @interface Optional {
  }

  /**
   * Provides multiple plural forms based on a count. The selection of which
   * plural form is performed by a PluralRule implementation.
   * 
   * This annotation is applied to a single parameter of a Messages subinterface
   * and indicates that parameter is to be used to choose the proper plural form
   * of the message. The parameter chosen must be of type short or int.
   * 
   * Optionally, a class literal referring to a PluralRule implementation can be
   * supplied as the argument if the standard implementation is insufficient.
   * 
   * <p>Example:
   * <code><pre>
   *   &#64;DefaultMessage("You have {0} widgets.")
   *   &#64;PluralText({"one", "You have one widget.")
   *   String example(&#64;PluralCount int count)
   * </pre></code>
   * </p>
   */
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.PARAMETER)
  public @interface PluralCount {

    /**
     * The PluralRule implementation to use for this message. If not specified,
     * the GWT-supplied one is used instead, which should cover most use cases.
     * 
     * <p>{@code PluralRule.class} is used as a default value here, which will
     * be replaced during code generation with the default implementation.
     * </p>
     */
    Class<? extends PluralRule> value() default PluralRule.class;
  }

  /**
   * Provides multiple plural forms based on a count. The selection of which
   * plural form to use is based on the value of the argument marked
   * PluralCount, which may also specify an alternate plural rule to use.
   * 
   * <p>Example:
   * <code><pre>
   *   &#64;DefaultMessage("You have {0} widgets.")
   *   &#64;PluralText({"one", "You have one widget.")
   *   String example(&#64;PluralCount int count)
   * </pre></code>
   * </p>
   */
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.METHOD)
  @Documented
  public @interface PluralText {

    /**
     * An array of pairs of strings containing the strings for different plural
     * forms.
     * 
     * Each pair is the name of the plural form (as returned by
     * PluralForm.toString) followed by the string for that plural form. An
     * example for a locale that has "none", "one", and "other" plural forms:
     * 
     * <code><pre>
     * &#64;DefaultMessage("{0} widgets")
     * &#64;PluralText({"none", "No widgets", "one", "One widget"})
     * </pre>
     * 
     * "other" must not be included in this array as it will map to the
     * DefaultMessage value.
     */
    String[] value();
  }
}
