1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.text.style;
18
19import android.os.Parcel;
20import android.os.PersistableBundle;
21import android.text.ParcelableSpan;
22import android.text.TextUtils;
23
24import java.text.NumberFormat;
25import java.util.Locale;
26
27/**
28 * A span that supplies additional meta-data for the associated text intended
29 * for text-to-speech engines. If the text is being processed by a
30 * text-to-speech engine, the engine may use the data in this span in addition
31 * to or instead of its associated text.
32 *
33 * Each instance of a TtsSpan has a type, for example {@link #TYPE_DATE}
34 * or {@link #TYPE_MEASURE}. And a list of arguments, provided as
35 * key-value pairs in a bundle.
36 *
37 * The inner classes are there for convenience and provide builders for each
38 * TtsSpan type.
39 */
40public class TtsSpan implements ParcelableSpan {
41    private final String mType;
42    private final PersistableBundle mArgs;
43
44    /**
45     * This span type can be used to add morphosyntactic features to the text it
46     * spans over, or synthesize a something else than the spanned text. Use
47     * the argument {@link #ARG_TEXT} to set a different text.
48     * Accepts the arguments {@link #ARG_GENDER},
49     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
50     * {@link #ARG_CASE}.
51     */
52    public static final String TYPE_TEXT = "android.type.text";
53
54    /**
55     * The text associated with this span is a cardinal. Must include the
56     * number to be synthesized with {@link #ARG_NUMBER}.
57     * Also accepts the arguments {@link #ARG_GENDER},
58     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
59     * {@link #ARG_CASE}.
60     */
61    public static final String TYPE_CARDINAL = "android.type.cardinal";
62
63    /**
64     * The text associated with this span is an ordinal. Must include the
65     * number to be synthesized with {@link #ARG_NUMBER}.
66     * Also accepts the arguments {@link #ARG_GENDER},
67     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
68     * {@link #ARG_CASE}.
69     */
70    public static final String TYPE_ORDINAL = "android.type.ordinal";
71
72    /**
73     * The text associated with this span is a decimal number. Must include the
74     * number to be synthesized with {@link #ARG_INTEGER_PART} and
75     * {@link #ARG_FRACTIONAL_PART}.
76     * Also accepts the arguments {@link #ARG_GENDER},
77     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
78     * {@link #ARG_CASE}.
79     */
80    public static final String TYPE_DECIMAL = "android.type.decimal";
81
82    /**
83     * The text associated with this span is a fractional number. Must include
84     * the number to be synthesized with {@link #ARG_NUMERATOR} and
85     * {@link #ARG_DENOMINATOR}. {@link #ARG_INTEGER_PART} is optional
86     * Also accepts the arguments {@link #ARG_GENDER},
87     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
88     * {@link #ARG_CASE}.
89     */
90    public static final String TYPE_FRACTION = "android.type.fraction";
91
92    /**
93     * The text associated with this span is a measure, consisting of a number
94     * and a unit. The number can be a cardinal, decimal or a fraction. Set the
95     * number with the same arguments as {@link #TYPE_CARDINAL},
96     * {@link #TYPE_DECIMAL} or {@link #TYPE_FRACTION}. The unit can be
97     * specified with {@link #ARG_UNIT}.
98     * Also accepts the arguments {@link #ARG_GENDER},
99     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
100     * {@link #ARG_CASE}.
101     */
102    public static final String TYPE_MEASURE = "android.type.measure";
103
104    /**
105     * The text associated with this span is a time, consisting of a number of
106     * hours and minutes, specified with {@link #ARG_HOURS} and
107     * {@link #ARG_MINUTES}.
108     * Also accepts the arguments {@link #ARG_GENDER},
109     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
110     * {@link #ARG_CASE}.
111     */
112    public static final String TYPE_TIME = "android.type.time";
113
114    /**
115     * The text associated with this span is a date. At least one of the
116     * arguments {@link #ARG_MONTH} and {@link #ARG_YEAR} has to be provided.
117     * The argument {@link #ARG_DAY} is optional if {@link #ARG_MONTH} is set.
118     * The argument {@link #ARG_WEEKDAY} is optional if {@link #ARG_DAY} is set.
119     * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
120     * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
121     */
122    public static final String TYPE_DATE = "android.type.date";
123
124    /**
125     * The text associated with this span is a telephone number. The argument
126     * {@link #ARG_NUMBER_PARTS} is required. {@link #ARG_COUNTRY_CODE} and
127     * {@link #ARG_EXTENSION} are optional.
128     * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
129     * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
130     */
131    public static final String TYPE_TELEPHONE = "android.type.telephone";
132
133    /**
134     * The text associated with this span is a URI (can be used for URLs and
135     * email addresses). The full schema for URLs, which email addresses can
136     * effectively be seen as a subset of, is:
137     * protocol://username:password@domain:port/path?query_string#fragment_id
138     * Hence populating just username and domain will read as an email address.
139     * All arguments are optional, but at least one has to be provided:
140     * {@link #ARG_PROTOCOL}, {@link #ARG_USERNAME}, {@link #ARG_PASSWORD},
141     * {@link #ARG_DOMAIN}, {@link #ARG_PORT}, {@link #ARG_PATH},
142     * {@link #ARG_QUERY_STRING} and {@link #ARG_FRAGMENT_ID}.
143     * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
144     * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
145     */
146    public static final String TYPE_ELECTRONIC = "android.type.electronic";
147
148    /**
149     * The text associated with this span is an amount of money. Set the amount
150     * with the same arguments as {@link #TYPE_DECIMAL}.
151     * {@link #ARG_CURRENCY} is used to set the currency. {@link #ARG_QUANTITY}
152     * is optional.
153     * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
154     * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
155     */
156    public static final String TYPE_MONEY = "android.type.money";
157
158    /**
159     * The text associated with this span is a series of digits that have to be
160     * read sequentially. The digits can be set with {@link #ARG_DIGITS}.
161     * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
162     * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
163     */
164    public static final String TYPE_DIGITS = "android.type.digits";
165
166    /**
167     * The text associated with this span is a series of characters that have to
168     * be read verbatim. The engine will attempt to read out any character like
169     * punctuation but excluding whitespace. {@link #ARG_VERBATIM} is required.
170     * Also accepts the arguments {@link #ARG_GENDER},
171     * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
172     */
173    public static final String TYPE_VERBATIM = "android.type.verbatim";
174
175    /**
176     * String argument supplying gender information. Can be any of
177     * {@link #GENDER_NEUTRAL}, {@link #GENDER_MALE} and
178     * {@link #GENDER_FEMALE}.
179     */
180    public static final String ARG_GENDER = "android.arg.gender";
181
182    public static final String GENDER_NEUTRAL = "android.neutral";
183    public static final String GENDER_MALE = "android.male";
184    public static final String GENDER_FEMALE = "android.female";
185
186    /**
187     * String argument supplying animacy information. Can be
188     * {@link #ANIMACY_ANIMATE} or
189     * {@link #ANIMACY_INANIMATE}
190     */
191    public static final String ARG_ANIMACY = "android.arg.animacy";
192
193    public static final String ANIMACY_ANIMATE = "android.animate";
194    public static final String ANIMACY_INANIMATE = "android.inanimate";
195
196    /**
197     * String argument supplying multiplicity information. Can be any of
198     * {@link #MULTIPLICITY_SINGLE}, {@link #MULTIPLICITY_DUAL} and
199     * {@link #MULTIPLICITY_PLURAL}
200     */
201    public static final String ARG_MULTIPLICITY = "android.arg.multiplicity";
202
203    public static final String MULTIPLICITY_SINGLE = "android.single";
204    public static final String MULTIPLICITY_DUAL = "android.dual";
205    public static final String MULTIPLICITY_PLURAL = "android.plural";
206
207    /**
208     * String argument supplying case information. Can be any of
209     * {@link #CASE_NOMINATIVE}, {@link #CASE_ACCUSATIVE}, {@link #CASE_DATIVE},
210     * {@link #CASE_ABLATIVE}, {@link #CASE_GENITIVE}, {@link #CASE_VOCATIVE},
211     * {@link #CASE_LOCATIVE} and {@link #CASE_INSTRUMENTAL}
212     */
213    public static final String ARG_CASE = "android.arg.case";
214
215    public static final String CASE_NOMINATIVE = "android.nominative";
216    public static final String CASE_ACCUSATIVE = "android.accusative";
217    public static final String CASE_DATIVE = "android.dative";
218    public static final String CASE_ABLATIVE = "android.ablative";
219    public static final String CASE_GENITIVE = "android.genitive";
220    public static final String CASE_VOCATIVE = "android.vocative";
221    public static final String CASE_LOCATIVE = "android.locative";
222    public static final String CASE_INSTRUMENTAL = "android.instrumental";
223
224    /**
225     * String supplying the text to be synthesized. The synthesizer is free
226     * to decide how to interpret the text.
227     * Can be used with {@link #TYPE_TEXT}.
228     */
229    public static final String ARG_TEXT = "android.arg.text";
230
231    /**
232     * Argument used to specify a whole number. The value can be a string of
233     * digits of any size optionally prefixed with a - or +.
234     * Can be used with {@link #TYPE_CARDINAL} and {@link #TYPE_ORDINAL}.
235     */
236    public static final String ARG_NUMBER = "android.arg.number";
237
238    /**
239     * Argument used to specify the integer part of a decimal or fraction. The
240     * value can be a string of digits of any size optionally prefixed with
241     * a - or +.
242     * Can be used with {@link #TYPE_DECIMAL} and {@link #TYPE_FRACTION}.
243     */
244    public static final String ARG_INTEGER_PART = "android.arg.integer_part";
245
246    /**
247     * Argument used to specify the fractional part of a decimal. The value can
248     * be a string of digits of any size.
249     * Can be used with {@link #TYPE_DECIMAL}.
250     */
251    public static final String ARG_FRACTIONAL_PART =
252        "android.arg.fractional_part";
253
254    /**
255     * Argument used to choose the suffix (thousand, million, etc) that is used
256     * to pronounce large amounts of money. For example it can be used to
257     * disambiguate between "two thousand five hundred dollars" and
258     * "two point five thousand dollars".
259     * If implemented, engines should support at least "1000", "1000000",
260     * "1000000000" and "1000000000000".
261     * Example: if the {@link #ARG_INTEGER_PART} argument is "10", the
262     * {@link #ARG_FRACTIONAL_PART} argument is "4", the {@link #ARG_QUANTITY}
263     * argument is "1000" and the {@link #ARG_CURRENCY} argument is "usd", the
264     * TTS engine may pronounce the span as "ten point four thousand dollars".
265     * With the same example but with the quantity set as "1000000" the TTS
266     * engine may pronounce the span as "ten point four million dollars".
267     * Can be used with {@link #TYPE_MONEY}.
268     */
269    public static final String ARG_QUANTITY =
270            "android.arg.quantity";
271
272    /**
273     * Argument used to specify the numerator of a fraction. The value can be a
274     * string of digits of any size optionally prefixed with a - or +.
275     * Can be used with {@link #TYPE_FRACTION}.
276     */
277    public static final String ARG_NUMERATOR = "android.arg.numerator";
278
279    /**
280     * Argument used to specify the denominator of a fraction. The value can be
281     * a string of digits of any size optionally prefixed with a + or -.
282     * Can be used with {@link #TYPE_FRACTION}.
283     */
284    public static final String ARG_DENOMINATOR = "android.arg.denominator";
285
286    /**
287     * Argument used to specify the unit of a measure. The unit should always be
288     * specified in English singular form. Prefixes may be used. Engines will do
289     * their best to pronounce them correctly in the language used. Engines are
290     * expected to at least support the most common ones like "meter", "second",
291     * "degree celsius" and "degree fahrenheit" with some common prefixes like
292     * "milli" and "kilo".
293     * Can be used with {@link #TYPE_MEASURE}.
294     */
295    public static final String ARG_UNIT = "android.arg.unit";
296
297    /**
298     * Argument used to specify the hours of a time. The hours should be
299     * provided as an integer in the range from 0 up to and including 24.
300     * Can be used with {@link #TYPE_TIME}.
301     */
302    public static final String ARG_HOURS = "android.arg.hours";
303
304    /**
305     * Argument used to specify the minutes of a time. The hours should be
306     * provided as an integer in the range from 0 up to and including 59.
307     * Can be used with {@link #TYPE_TIME}.
308     */
309    public static final String ARG_MINUTES = "android.arg.minutes";
310
311    /**
312     * Argument used to specify the weekday of a date. The value should be
313     * provided as an integer and can be any of {@link #WEEKDAY_SUNDAY},
314     * {@link #WEEKDAY_MONDAY}, {@link #WEEKDAY_TUESDAY},
315     * {@link #WEEKDAY_WEDNESDAY}, {@link #WEEKDAY_THURSDAY},
316     * {@link #WEEKDAY_FRIDAY} and {@link #WEEKDAY_SATURDAY}.
317     * Can be used with {@link #TYPE_DATE}.
318     */
319    public static final String ARG_WEEKDAY = "android.arg.weekday";
320
321    public static final int WEEKDAY_SUNDAY = 1;
322    public static final int WEEKDAY_MONDAY = 2;
323    public static final int WEEKDAY_TUESDAY = 3;
324    public static final int WEEKDAY_WEDNESDAY = 4;
325    public static final int WEEKDAY_THURSDAY = 5;
326    public static final int WEEKDAY_FRIDAY = 6;
327    public static final int WEEKDAY_SATURDAY = 7;
328
329    /**
330     * Argument used to specify the day of the month of a date. The value should
331     * be provided as an integer in the range from 1 up to and including 31.
332     * Can be used with {@link #TYPE_DATE}.
333     */
334    public static final String ARG_DAY = "android.arg.day";
335
336    /**
337     * Argument used to specify the month of a date. The value should be
338     * provided as an integer and can be any of {@link #MONTH_JANUARY},
339     * {@link #MONTH_FEBRUARY},  {@link #MONTH_MARCH}, {@link #MONTH_APRIL},
340     * {@link #MONTH_MAY}, {@link #MONTH_JUNE}, {@link #MONTH_JULY},
341     * {@link #MONTH_AUGUST}, {@link #MONTH_SEPTEMBER}, {@link #MONTH_OCTOBER},
342     * {@link #MONTH_NOVEMBER} and {@link #MONTH_DECEMBER}.
343     * Can be used with {@link #TYPE_DATE}.
344     */
345    public static final String ARG_MONTH = "android.arg.month";
346
347    public static final int MONTH_JANUARY = 0;
348    public static final int MONTH_FEBRUARY = 1;
349    public static final int MONTH_MARCH = 2;
350    public static final int MONTH_APRIL = 3;
351    public static final int MONTH_MAY = 4;
352    public static final int MONTH_JUNE = 5;
353    public static final int MONTH_JULY = 6;
354    public static final int MONTH_AUGUST = 7;
355    public static final int MONTH_SEPTEMBER = 8;
356    public static final int MONTH_OCTOBER = 9;
357    public static final int MONTH_NOVEMBER = 10;
358    public static final int MONTH_DECEMBER = 11;
359
360    /**
361     * Argument used to specify the year of a date. The value should be provided
362     * as a positive integer.
363     * Can be used with {@link #TYPE_DATE}.
364     */
365    public static final String ARG_YEAR = "android.arg.year";
366
367    /**
368     * Argument used to specify the country code of a telephone number. Can be
369     * a string of digits optionally prefixed with a "+".
370     * Can be used with {@link #TYPE_TELEPHONE}.
371     */
372    public static final String ARG_COUNTRY_CODE = "android.arg.country_code";
373
374    /**
375     * Argument used to specify the main number part of a telephone number. Can
376     * be a string of digits where the different parts of the telephone number
377     * can be separated with a space, '-', '/' or '.'.
378     * Can be used with {@link #TYPE_TELEPHONE}.
379     */
380    public static final String ARG_NUMBER_PARTS = "android.arg.number_parts";
381
382    /**
383     * Argument used to specify the extension part of a telephone number. Can be
384     * a string of digits.
385     * Can be used with {@link #TYPE_TELEPHONE}.
386     */
387    public static final String ARG_EXTENSION = "android.arg.extension";
388
389    /**
390     * Argument used to specify the protocol of a URI. Examples are "http" and
391     * "ftp".
392     * Can be used with {@link #TYPE_ELECTRONIC}.
393     */
394    public static final String ARG_PROTOCOL = "android.arg.protocol";
395
396    /**
397     * Argument used to specify the username part of a URI. Should be set as a
398     * string.
399     * Can be used with {@link #TYPE_ELECTRONIC}.
400     */
401    public static final String ARG_USERNAME = "android.arg.username";
402
403    /**
404     * Argument used to specify the password part of a URI. Should be set as a
405     * string.
406     * Can be used with {@link #TYPE_ELECTRONIC}.
407     */
408    public static final String ARG_PASSWORD = "android.arg.password";
409
410    /**
411     * Argument used to specify the domain part of a URI. For example
412     * "source.android.com".
413     * Can be used with {@link #TYPE_ELECTRONIC}.
414     */
415    public static final String ARG_DOMAIN = "android.arg.domain";
416
417    /**
418     * Argument used to specify the port number of a URI. Should be specified as
419     * an integer.
420     * Can be used with {@link #TYPE_ELECTRONIC}.
421     */
422    public static final String ARG_PORT = "android.arg.port";
423
424    /**
425     * Argument used to specify the path part of a URI. For example
426     * "source/index.html".
427     * Can be used with {@link #TYPE_ELECTRONIC}.
428     */
429    public static final String ARG_PATH = "android.arg.path";
430
431    /**
432     * Argument used to specify the query string of a URI. For example
433     * "arg=value&argtwo=value".
434     * Can be used with {@link #TYPE_ELECTRONIC}.
435     */
436    public static final String ARG_QUERY_STRING = "android.arg.query_string";
437
438    /**
439     * Argument used to specify the fragment id of a URI. Should be specified as
440     * a string.
441     * Can be used with {@link #TYPE_ELECTRONIC}.
442     */
443    public static final String ARG_FRAGMENT_ID = "android.arg.fragment_id";
444
445    /**
446     * Argument used to specify the currency. Should be a ISO4217 currency code,
447     * e.g. "USD".
448     * Can be used with {@link #TYPE_MONEY}.
449     */
450    public static final String ARG_CURRENCY = "android.arg.money";
451
452    /**
453     * Argument used to specify a string of digits.
454     * Can be used with {@link #TYPE_DIGITS}.
455     */
456    public static final String ARG_DIGITS = "android.arg.digits";
457
458    /**
459     * Argument used to specify a string where the characters are read verbatim,
460     * except whitespace.
461     * Can be used with {@link #TYPE_VERBATIM}.
462     */
463    public static final String ARG_VERBATIM = "android.arg.verbatim";
464
465    public TtsSpan(String type, PersistableBundle args) {
466        mType = type;
467        mArgs = args;
468    }
469
470    public TtsSpan(Parcel src) {
471        mType = src.readString();
472        mArgs = src.readPersistableBundle();
473    }
474
475    /**
476     * Returns the type.
477     * @return The type of this instance.
478     */
479    public String getType() {
480        return mType;
481    }
482
483    /**
484     * Returns a bundle of the arguments set.
485     * @return The bundle of the arguments set.
486     */
487    public PersistableBundle getArgs() {
488        return mArgs;
489    }
490
491    @Override
492    public int describeContents() {
493        return 0;
494    }
495
496    @Override
497    public void writeToParcel(Parcel dest, int flags) {
498        writeToParcelInternal(dest, flags);
499    }
500
501    /** @hide */
502    public void writeToParcelInternal(Parcel dest, int flags) {
503        dest.writeString(mType);
504        dest.writePersistableBundle(mArgs);
505    }
506
507    @Override
508    public int getSpanTypeId() {
509        return getSpanTypeIdInternal();
510    }
511
512    /** @hide */
513    public int getSpanTypeIdInternal() {
514        return TextUtils.TTS_SPAN;
515    }
516
517    /**
518     * A simple builder for TtsSpans.
519     * This builder can be used directly, but the more specific subclasses of
520     * this builder like {@link TtsSpan.TextBuilder} and
521     * {@link TtsSpan.CardinalBuilder} are likely more useful.
522     *
523     * This class uses generics so methods from this class can return instances
524     * of its child classes, resulting in a fluent API (CRTP pattern).
525     */
526    public static class Builder<C extends Builder<?>> {
527        // Holds the type of this class.
528        private final String mType;
529
530        // Holds the arguments of this class. It only stores objects of type
531        // String, Integer and Long.
532        private PersistableBundle mArgs = new PersistableBundle();
533
534        public Builder(String type) {
535            mType = type;
536        }
537
538        /**
539         * Returns a TtsSpan built from the parameters set by the setter
540         * methods.
541         * @return A TtsSpan built with parameters of this builder.
542         */
543        public TtsSpan build() {
544            return new TtsSpan(mType, mArgs);
545        }
546
547        /**
548         * Sets an argument to a string value.
549         * @param arg The argument name.
550         * @param value The value the argument should be set to.
551         * @return This instance.
552         */
553        @SuppressWarnings("unchecked")
554        public C setStringArgument(String arg, String value) {
555            mArgs.putString(arg, value);
556            return (C) this;
557        }
558
559        /**
560         * Sets an argument to an int value.
561         * @param arg The argument name.
562         * @param value The value the argument should be set to.
563         */
564        @SuppressWarnings("unchecked")
565        public C setIntArgument(String arg, int value) {
566            mArgs.putInt(arg, value);
567            return (C) this;
568        }
569
570        /**
571         * Sets an argument to a long value.
572         * @param arg The argument name.
573         * @param value The value the argument should be set to.
574         */
575        @SuppressWarnings("unchecked")
576        public C setLongArgument(String arg, long value) {
577            mArgs.putLong(arg, value);
578            return (C) this;
579        }
580    }
581
582    /**
583     * A builder for TtsSpans, has setters for morphosyntactic features.
584     * This builder can be used directly, but the more specific subclasses of
585     * this builder like {@link TtsSpan.TextBuilder} and
586     * {@link TtsSpan.CardinalBuilder} are likely more useful.
587     */
588    public static class SemioticClassBuilder<C extends SemioticClassBuilder<?>>
589            extends Builder<C> {
590
591        public SemioticClassBuilder(String type) {
592            super(type);
593        }
594
595        /**
596         * Sets the gender information for this instance.
597         * @param gender Can any of {@link #GENDER_NEUTRAL},
598         *     {@link #GENDER_MALE} and {@link #GENDER_FEMALE}.
599         * @return This instance.
600         */
601        public C setGender(String gender) {
602            return setStringArgument(TtsSpan.ARG_GENDER, gender);
603        }
604
605        /**
606         * Sets the animacy information for this instance.
607         * @param animacy Can be any of {@link #ANIMACY_ANIMATE} and
608         *     {@link #ANIMACY_INANIMATE}.
609         * @return This instance.
610         */
611        public C setAnimacy(String animacy) {
612            return setStringArgument(TtsSpan.ARG_ANIMACY, animacy);
613        }
614
615        /**
616         * Sets the multiplicity information for this instance.
617         * @param multiplicity Can be any of
618         *     {@link #MULTIPLICITY_SINGLE}, {@link #MULTIPLICITY_DUAL} and
619         *     {@link #MULTIPLICITY_PLURAL}.
620         * @return This instance.
621         */
622        public C setMultiplicity(String multiplicity) {
623            return setStringArgument(TtsSpan.ARG_MULTIPLICITY, multiplicity);
624        }
625
626        /**
627         * Sets the grammatical case information for this instance.
628         * @param grammaticalCase Can be any of {@link #CASE_NOMINATIVE},
629         *     {@link #CASE_ACCUSATIVE}, {@link #CASE_DATIVE},
630         *     {@link #CASE_ABLATIVE}, {@link #CASE_GENITIVE},
631         *     {@link #CASE_VOCATIVE}, {@link #CASE_LOCATIVE} and
632         *     {@link #CASE_INSTRUMENTAL}.
633         * @return This instance.
634         */
635        public C setCase(String grammaticalCase) {
636            return setStringArgument(TtsSpan.ARG_CASE, grammaticalCase);
637        }
638    }
639
640    /**
641     * A builder for TtsSpans of type {@link #TYPE_TEXT}.
642     */
643    public static class TextBuilder extends SemioticClassBuilder<TextBuilder> {
644
645        /**
646         * Creates a builder for a TtsSpan of type {@link #TYPE_TEXT}.
647         */
648        public TextBuilder() {
649            super(TtsSpan.TYPE_TEXT);
650        }
651
652        /**
653         * Creates a TtsSpan of type {@link #TYPE_TEXT} and sets the
654         * {@link #ARG_TEXT} argument.
655         * @param text The text to be synthesized.
656         * @see #setText(String)
657         */
658        public TextBuilder(String text) {
659            this();
660            setText(text);
661        }
662
663        /**
664         * Sets the {@link #ARG_TEXT} argument, the text to be synthesized.
665         * @param text The string that will be synthesized.
666         * @return This instance.
667         */
668        public TextBuilder setText(String text) {
669            return setStringArgument(TtsSpan.ARG_TEXT, text);
670        }
671    }
672
673    /**
674     * A builder for TtsSpans of type {@link #TYPE_CARDINAL}.
675     */
676    public static class CardinalBuilder
677            extends SemioticClassBuilder<CardinalBuilder> {
678
679        /**
680         * Creates a builder for a TtsSpan of type {@link #TYPE_CARDINAL}.
681         */
682        public CardinalBuilder() {
683            super(TtsSpan.TYPE_CARDINAL);
684        }
685
686        /**
687         * Creates a TtsSpan of type {@link #TYPE_CARDINAL} and sets the
688         * {@link #ARG_NUMBER} argument.
689         * @param number The number to synthesize.
690         * @see #setNumber(long)
691         */
692        public CardinalBuilder(long number) {
693            this();
694            setNumber(number);
695        }
696
697        /**
698         * Creates a TtsSpan of type {@link #TYPE_CARDINAL} and sets the
699         * {@link #ARG_NUMBER} argument.
700         * @param number The number to synthesize.
701         * @see #setNumber(String)
702         */
703        public CardinalBuilder(String number) {
704            this();
705            setNumber(number);
706        }
707
708        /**
709         * Convenience method that converts the number to a String and set it to
710         * the value for {@link #ARG_NUMBER}.
711         * @param number The number that will be synthesized.
712         * @return This instance.
713         */
714        public CardinalBuilder setNumber(long number) {
715            return setNumber(String.valueOf(number));
716        }
717
718        /**
719         * Sets the {@link #ARG_NUMBER} argument.
720         * @param number A non-empty string of digits with an optional
721         *     leading + or -.
722         * @return This instance.
723         */
724        public CardinalBuilder setNumber(String number) {
725            return setStringArgument(TtsSpan.ARG_NUMBER, number);
726        }
727    }
728
729    /**
730     * A builder for TtsSpans of type {@link #TYPE_ORDINAL}.
731     */
732    public static class OrdinalBuilder
733            extends SemioticClassBuilder<OrdinalBuilder> {
734
735        /**
736         * Creates a builder for a TtsSpan of type {@link #TYPE_ORDINAL}.
737         */
738        public OrdinalBuilder() {
739            super(TtsSpan.TYPE_ORDINAL);
740        }
741
742        /**
743         * Creates a TtsSpan of type {@link #TYPE_ORDINAL} and sets the
744         * {@link #ARG_NUMBER} argument.
745         * @param number The ordinal number to synthesize.
746         * @see #setNumber(long)
747         */
748        public OrdinalBuilder(long number) {
749            this();
750            setNumber(number);
751        }
752
753        /**
754         * Creates a TtsSpan of type {@link #TYPE_ORDINAL} and sets the
755         * {@link #ARG_NUMBER} argument.
756         * @param number The number to synthesize.
757         * @see #setNumber(String)
758         */
759        public OrdinalBuilder(String number) {
760            this();
761            setNumber(number);
762        }
763
764        /**
765         * Convenience method that converts the number to a String and sets it
766         * to the value for {@link #ARG_NUMBER}.
767         * @param number The ordinal number that will be synthesized.
768         * @return This instance.
769         */
770        public OrdinalBuilder setNumber(long number) {
771            return setNumber(String.valueOf(number));
772        }
773
774        /**
775         * Sets the {@link #ARG_NUMBER} argument.
776         * @param number A non-empty string of digits with an optional
777         *     leading + or -.
778         * @return This instance.
779         */
780        public OrdinalBuilder setNumber(String number) {
781            return setStringArgument(TtsSpan.ARG_NUMBER, number);
782        }
783    }
784
785    /**
786     * A builder for TtsSpans of type {@link #TYPE_DECIMAL}.
787     */
788    public static class DecimalBuilder
789            extends SemioticClassBuilder<DecimalBuilder> {
790
791        /**
792         * Creates a builder for a TtsSpan of type {@link #TYPE_DECIMAL}.
793         */
794        public DecimalBuilder() {
795            super(TtsSpan.TYPE_DECIMAL);
796        }
797
798        /**
799         * Creates a TtsSpan of type {@link #TYPE_DECIMAL} and sets the
800         * {@link #ARG_INTEGER_PART} and {@link #ARG_FRACTIONAL_PART} arguments.
801         * @see #setArgumentsFromDouble(double, int, int)
802         */
803        public DecimalBuilder(double number,
804                              int minimumFractionDigits,
805                              int maximumFractionDigits) {
806            this();
807            setArgumentsFromDouble(number,
808                                   minimumFractionDigits,
809                                   maximumFractionDigits);
810        }
811
812        /**
813         * Creates a TtsSpan of type {@link #TYPE_DECIMAL} and sets the
814         * {@link #ARG_INTEGER_PART} and {@link #ARG_FRACTIONAL_PART} arguments.
815         */
816        public DecimalBuilder(String integerPart, String fractionalPart) {
817            this();
818            setIntegerPart(integerPart);
819            setFractionalPart(fractionalPart);
820        }
821
822        /**
823         * Convenience method takes a double and a maximum number of fractional
824         * digits, it sets the {@link #ARG_INTEGER_PART} and
825         * {@link #ARG_FRACTIONAL_PART} arguments.
826         * @param number The number to be synthesized.
827         * @param minimumFractionDigits The minimum number of fraction digits
828         *     that are pronounced.
829         * @param maximumFractionDigits The maximum number of fraction digits
830         *     that are pronounced. If maximumFractionDigits <
831         *     minimumFractionDigits then minimumFractionDigits will be assumed
832         *     to be equal to maximumFractionDigits.
833         * @return This instance.
834         */
835        public DecimalBuilder setArgumentsFromDouble(
836                double number,
837                int minimumFractionDigits,
838                int maximumFractionDigits) {
839            // Format double.
840            NumberFormat formatter = NumberFormat.getInstance(Locale.US);
841            formatter.setMinimumFractionDigits(maximumFractionDigits);
842            formatter.setMaximumFractionDigits(maximumFractionDigits);
843            formatter.setGroupingUsed(false);
844            String str = formatter.format(number);
845
846            // Split at decimal point.
847            int i = str.indexOf('.');
848            if (i >= 0) {
849                setIntegerPart(str.substring(0, i));
850                setFractionalPart(str.substring(i + 1));
851            } else {
852                setIntegerPart(str);
853            }
854            return this;
855        }
856
857        /**
858         * Convenience method that converts the number to a String and sets it
859         * to the value for {@link #ARG_INTEGER_PART}.
860         * @param integerPart The integer part of the decimal.
861         * @return This instance.
862         */
863        public DecimalBuilder setIntegerPart(long integerPart) {
864            return setIntegerPart(String.valueOf(integerPart));
865        }
866
867        /**
868         * Sets the {@link #ARG_INTEGER_PART} argument.
869         * @param integerPart A non-empty string of digits with an optional
870         *     leading + or -.
871         * @return This instance.
872         */
873        public DecimalBuilder setIntegerPart(String integerPart) {
874            return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
875        }
876
877        /**
878         * Sets the {@link #ARG_FRACTIONAL_PART} argument.
879         * @param fractionalPart A non-empty string of digits.
880         * @return This instance.
881         */
882        public DecimalBuilder setFractionalPart(String fractionalPart) {
883            return setStringArgument(TtsSpan.ARG_FRACTIONAL_PART,
884                                     fractionalPart);
885        }
886    }
887
888    /**
889     * A builder for TtsSpans of type {@link #TYPE_FRACTION}.
890     */
891    public static class FractionBuilder
892            extends SemioticClassBuilder<FractionBuilder> {
893
894        /**
895         * Creates a builder for a TtsSpan of type {@link #TYPE_FRACTION}.
896         */
897        public FractionBuilder() {
898            super(TtsSpan.TYPE_FRACTION);
899        }
900
901        /**
902         * Creates a TtsSpan of type {@link #TYPE_FRACTION} and sets the
903         * {@link #ARG_INTEGER_PART}, {@link #ARG_NUMERATOR}, and
904         * {@link #ARG_DENOMINATOR} arguments.
905         */
906        public FractionBuilder(long integerPart,
907                               long numerator,
908                               long denominator) {
909            this();
910            setIntegerPart(integerPart);
911            setNumerator(numerator);
912            setDenominator(denominator);
913        }
914
915        /**
916         * Convenience method that converts the integer to a String and sets the
917         * argument {@link #ARG_NUMBER}.
918         * @param integerPart The integer part.
919         * @return This instance.
920         */
921        public FractionBuilder setIntegerPart(long integerPart) {
922            return setIntegerPart(String.valueOf(integerPart));
923        }
924
925        /**
926         * Sets the {@link #ARG_INTEGER_PART} argument.
927         * @param integerPart A non-empty string of digits with an optional
928         *     leading + or -.
929         * @return This instance.
930         */
931        public FractionBuilder setIntegerPart(String integerPart) {
932            return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
933        }
934
935        /**
936         * Convenience method that converts the numerator to a String and sets
937         * the argument {@link #ARG_NUMERATOR}.
938         * @param numerator The numerator.
939         * @return This instance.
940         */
941        public FractionBuilder setNumerator(long numerator) {
942            return setNumerator(String.valueOf(numerator));
943        }
944
945        /**
946         * Sets the {@link #ARG_NUMERATOR} argument.
947         * @param numerator A non-empty string of digits with an optional
948         *     leading + or -.
949         * @return This instance.
950         */
951        public FractionBuilder setNumerator(String numerator) {
952            return setStringArgument(TtsSpan.ARG_NUMERATOR, numerator);
953        }
954
955        /**
956         * Convenience method that converts the denominator to a String and sets
957         * the argument {@link #ARG_DENOMINATOR}.
958         * @param denominator The denominator.
959         * @return This instance.
960         */
961        public FractionBuilder setDenominator(long denominator) {
962            return setDenominator(String.valueOf(denominator));
963        }
964
965        /**
966         * Sets the {@link #ARG_DENOMINATOR} argument.
967         * @param denominator A non-empty string of digits with an optional
968         *     leading + or -.
969         * @return This instance.
970         */
971        public FractionBuilder setDenominator(String denominator) {
972            return setStringArgument(TtsSpan.ARG_DENOMINATOR, denominator);
973        }
974    }
975
976    /**
977     * A builder for TtsSpans of type {@link #TYPE_MEASURE}.
978     */
979    public static class MeasureBuilder
980            extends SemioticClassBuilder<MeasureBuilder> {
981
982        /**
983         * Creates a builder for a TtsSpan of type {@link #TYPE_MEASURE}.
984         */
985        public MeasureBuilder() {
986            super(TtsSpan.TYPE_MEASURE);
987        }
988
989        /**
990         * Convenience method that converts the number to a String and set it to
991         * the value for {@link #ARG_NUMBER}.
992         * @param number The amount of the measure.
993         * @return This instance.
994         */
995        public MeasureBuilder setNumber(long number) {
996            return setNumber(String.valueOf(number));
997        }
998
999        /**
1000         * Sets the {@link #ARG_NUMBER} argument.
1001         * @param number A non-empty string of digits with an optional
1002         *     leading + or -.
1003         * @return This instance.
1004         */
1005        public MeasureBuilder setNumber(String number) {
1006            return setStringArgument(TtsSpan.ARG_NUMBER, number);
1007        }
1008
1009        /**
1010         * Convenience method that converts the integer part to a String and set
1011         * it to the value for {@link #ARG_INTEGER_PART}.
1012         * @param integerPart The integer part of a decimal or fraction.
1013         * @return This instance.
1014         */
1015        public MeasureBuilder setIntegerPart(long integerPart) {
1016            return setIntegerPart(String.valueOf(integerPart));
1017        }
1018
1019        /**
1020         * Sets the {@link #ARG_INTEGER_PART} argument.
1021         * @param integerPart The integer part of a decimal or fraction; a
1022         * non-empty string of digits with an optional
1023         *     leading + or -.
1024         * @return This instance.
1025         */
1026        public MeasureBuilder setIntegerPart(String integerPart) {
1027            return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
1028        }
1029
1030        /**
1031         * Sets the {@link #ARG_FRACTIONAL_PART} argument.
1032         * @param fractionalPart The fractional part of a decimal; a non-empty
1033         *     string of digits with an optional leading + or -.
1034         * @return This instance.
1035         */
1036        public MeasureBuilder setFractionalPart(String fractionalPart) {
1037            return setStringArgument(TtsSpan.ARG_FRACTIONAL_PART,
1038                                     fractionalPart);
1039        }
1040
1041        /**
1042         * Convenience method that converts the numerator to a String and set it
1043         * to the value for {@link #ARG_NUMERATOR}.
1044         * @param numerator The numerator of a fraction.
1045         * @return This instance.
1046         */
1047        public MeasureBuilder setNumerator(long numerator) {
1048            return setNumerator(String.valueOf(numerator));
1049        }
1050
1051        /**
1052         * Sets the {@link #ARG_NUMERATOR} argument.
1053         * @param numerator The numerator of a fraction; a non-empty string of
1054         *     digits with an optional leading + or -.
1055         * @return This instance.
1056         */
1057        public MeasureBuilder setNumerator(String numerator) {
1058            return setStringArgument(TtsSpan.ARG_NUMERATOR, numerator);
1059        }
1060
1061        /**
1062         * Convenience method that converts the denominator to a String and set
1063         * it to the value for {@link #ARG_DENOMINATOR}.
1064         * @param denominator The denominator of a fraction.
1065         * @return This instance.
1066         */
1067        public MeasureBuilder setDenominator(long denominator) {
1068            return setDenominator(String.valueOf(denominator));
1069        }
1070
1071        /**
1072         * Sets the {@link #ARG_DENOMINATOR} argument.
1073         * @param denominator The denominator of a fraction; a non-empty string
1074         *     of digits with an optional leading + or -.
1075         * @return This instance.
1076         */
1077        public MeasureBuilder setDenominator(String denominator) {
1078            return setStringArgument(TtsSpan.ARG_DENOMINATOR, denominator);
1079        }
1080
1081        /**
1082         * Sets the {@link #ARG_UNIT} argument.
1083         * @param unit The unit of the measure.
1084         * @return This instance.
1085         * @see TtsSpan.ARG_UNIT
1086         */
1087        public MeasureBuilder setUnit(String unit) {
1088            return setStringArgument(TtsSpan.ARG_UNIT, unit);
1089        }
1090    }
1091
1092    /**
1093     * A builder for TtsSpans of type {@link #TYPE_TIME}.
1094     */
1095    public static class TimeBuilder
1096            extends SemioticClassBuilder<TimeBuilder> {
1097
1098        /**
1099         * Creates a builder for a TtsSpan of type {@link #TYPE_TIME}.
1100         */
1101        public TimeBuilder() {
1102            super(TtsSpan.TYPE_TIME);
1103        }
1104
1105        /**
1106         * Creates a builder for a TtsSpan of type {@link #TYPE_TIME} and
1107         * sets the {@link #ARG_HOURS} and {@link #ARG_MINUTES} arguments.
1108         */
1109        public TimeBuilder(int hours, int minutes) {
1110            this();
1111            setHours(hours);
1112            setMinutes(minutes);
1113        }
1114
1115        /**
1116         * Sets the {@link #ARG_HOURS} argument.
1117         * @param hours The value to be set for hours. See {@link #ARG_HOURS}.
1118         * @return This instance.
1119         * @see #ARG_HOURS
1120         */
1121        public TimeBuilder setHours(int hours) {
1122            return setIntArgument(TtsSpan.ARG_HOURS, hours);
1123        }
1124
1125        /**
1126         * Sets the {@link #ARG_MINUTES} argument.
1127         * @param minutes The value to be set for minutes. See
1128         *     {@link #ARG_MINUTES}.
1129         * @return This instance.
1130         * @see #ARG_MINUTES
1131         */
1132        public TimeBuilder setMinutes(int minutes) {
1133            return setIntArgument(TtsSpan.ARG_MINUTES, minutes);
1134        }
1135    }
1136
1137    /**
1138     * A builder for TtsSpans of type {@link #TYPE_DATE}.
1139     */
1140    public static class DateBuilder
1141            extends SemioticClassBuilder<DateBuilder> {
1142
1143        /**
1144         * Creates a builder for a TtsSpan of type {@link #TYPE_DATE}.
1145         */
1146        public DateBuilder() {
1147            super(TtsSpan.TYPE_DATE);
1148        }
1149
1150        /**
1151         * Creates a builder for a TtsSpan of type {@link #TYPE_TIME} and
1152         * possibly sets the {@link #ARG_WEEKDAY}, {@link #ARG_DAY},
1153         * {@link #ARG_MONTH} and {@link #ARG_YEAR} arguments. Pass null to any
1154         * argument to leave it unset.
1155         */
1156        public DateBuilder(Integer weekday,
1157                           Integer day,
1158                           Integer month,
1159                           Integer year) {
1160            this();
1161            if (weekday != null) {
1162                setWeekday(weekday);
1163            }
1164            if (day != null) {
1165                setDay(day);
1166            }
1167            if (month != null) {
1168                setMonth(month);
1169            }
1170            if (year != null) {
1171                setYear(year);
1172            }
1173        }
1174
1175        /**
1176         * Sets the {@link #ARG_WEEKDAY} argument.
1177         * @param weekday The value to be set for weekday. See
1178         *     {@link #ARG_WEEKDAY}.
1179         * @return This instance.
1180         * @see #ARG_WEEKDAY
1181         */
1182        public DateBuilder setWeekday(int weekday) {
1183            return setIntArgument(TtsSpan.ARG_WEEKDAY, weekday);
1184        }
1185
1186        /**
1187         * Sets the {@link #ARG_DAY} argument.
1188         * @param day The value to be set for day. See {@link #ARG_DAY}.
1189         * @return This instance.
1190         * @see #ARG_DAY
1191         */
1192        public DateBuilder setDay(int day) {
1193            return setIntArgument(TtsSpan.ARG_DAY, day);
1194        }
1195
1196        /**
1197         * Sets the {@link #ARG_MONTH} argument.
1198         * @param month The value to be set for month. See {@link #ARG_MONTH}.
1199         * @return This instance.
1200         * @see #ARG_MONTH
1201         */
1202        public DateBuilder setMonth(int month) {
1203            return setIntArgument(TtsSpan.ARG_MONTH, month);
1204        }
1205
1206        /**
1207         * Sets the {@link #ARG_YEAR} argument.
1208         * @param year The value to be set for year. See {@link #ARG_YEAR}.
1209         * @return This instance.
1210         * @see #ARG_YEAR
1211         */
1212        public DateBuilder setYear(int year) {
1213            return setIntArgument(TtsSpan.ARG_YEAR, year);
1214        }
1215    }
1216
1217    /**
1218     * A builder for TtsSpans of type {@link #TYPE_MONEY}.
1219     */
1220    public static class MoneyBuilder
1221            extends SemioticClassBuilder<MoneyBuilder> {
1222
1223        /**
1224         * Creates a TtsSpan of type {@link #TYPE_MONEY}.
1225         */
1226        public MoneyBuilder() {
1227            super(TtsSpan.TYPE_MONEY);
1228        }
1229
1230        /**
1231         * Convenience method that converts the number to a String and set it to
1232         * the value for {@link #ARG_INTEGER_PART}.
1233         * @param integerPart The integer part of the amount.
1234         * @return This instance.
1235         */
1236        public MoneyBuilder setIntegerPart(long integerPart) {
1237            return setIntegerPart(String.valueOf(integerPart));
1238        }
1239
1240        /**
1241         * Sets the {@link #ARG_INTEGER_PART} argument.
1242         * @param integerPart A non-empty string of digits with an optional
1243         *     leading + or -.
1244         * @return This instance.
1245         */
1246        public MoneyBuilder setIntegerPart(String integerPart) {
1247            return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
1248        }
1249
1250        /**
1251         * Sets the {@link #ARG_FRACTIONAL_PART} argument.
1252         * @param fractionalPart Can be a string of digits of any size.
1253         * @return This instance.
1254         */
1255        public MoneyBuilder setFractionalPart(String fractionalPart) {
1256            return setStringArgument(TtsSpan.ARG_FRACTIONAL_PART, fractionalPart);
1257        }
1258
1259        /**
1260         * Sets the {@link #ARG_CURRENCY} argument.
1261         * @param currency Should be a ISO4217 currency code, e.g. "USD".
1262         * @return This instance.
1263         */
1264        public MoneyBuilder setCurrency(String currency) {
1265            return setStringArgument(TtsSpan.ARG_CURRENCY, currency);
1266        }
1267
1268        /**
1269         * Sets the {@link #ARG_QUANTITY} argument.
1270         * @param quantity
1271         * @return This instance.
1272         */
1273        public MoneyBuilder setQuantity(String quantity) {
1274            return setStringArgument(TtsSpan.ARG_QUANTITY, quantity);
1275        }
1276    }
1277
1278    /**
1279     * A builder for TtsSpans of type {@link #TYPE_TELEPHONE}.
1280     */
1281    public static class TelephoneBuilder
1282            extends SemioticClassBuilder<TelephoneBuilder> {
1283
1284        /**
1285         * Creates a TtsSpan of type {@link #TYPE_TELEPHONE}.
1286         */
1287        public TelephoneBuilder() {
1288            super(TtsSpan.TYPE_TELEPHONE);
1289        }
1290
1291        /**
1292         * Creates a TtsSpan of type {@link #TYPE_TELEPHONE} and sets the
1293         * {@link #ARG_NUMBER_PARTS} argument.
1294         */
1295        public TelephoneBuilder(String numberParts) {
1296            this();
1297            setNumberParts(numberParts);
1298        }
1299
1300        /**
1301         * Sets the {@link #ARG_COUNTRY_CODE} argument.
1302         * @param countryCode The country code can be a series of digits
1303         * optionally prefixed with a "+".
1304         * @return This instance.
1305         */
1306        public TelephoneBuilder setCountryCode(String countryCode) {
1307            return setStringArgument(TtsSpan.ARG_COUNTRY_CODE, countryCode);
1308        }
1309
1310        /**
1311         * Sets the {@link #ARG_NUMBER_PARTS} argument.
1312         * @param numberParts The main telephone number. Can be a series of
1313         *     digits and letters separated by spaces, "/", "-" or ".".
1314         * @return This instance.
1315         */
1316        public TelephoneBuilder setNumberParts(String numberParts) {
1317            return setStringArgument(TtsSpan.ARG_NUMBER_PARTS, numberParts);
1318        }
1319
1320        /**
1321         * Sets the {@link #ARG_EXTENSION} argument.
1322         * @param extension The extension can be a series of digits.
1323         * @return This instance.
1324         */
1325        public TelephoneBuilder setExtension(String extension) {
1326            return setStringArgument(TtsSpan.ARG_EXTENSION, extension);
1327        }
1328    }
1329
1330    /**
1331     * A builder for TtsSpans of type {@link #TYPE_ELECTRONIC}.
1332     */
1333    public static class ElectronicBuilder
1334            extends SemioticClassBuilder<ElectronicBuilder> {
1335
1336        /**
1337         * Creates a TtsSpan of type {@link #TYPE_ELECTRONIC}.
1338         */
1339        public ElectronicBuilder() {
1340            super(TtsSpan.TYPE_ELECTRONIC);
1341        }
1342
1343        /**
1344         * Sets the {@link #ARG_USERNAME} and {@link #ARG_DOMAIN}
1345         *     arguments, representing an email address.
1346         * @param username The part before the @ in the email address.
1347         * @param domain The part after the @ in the email address.
1348         * @return This instance.
1349         */
1350        public ElectronicBuilder setEmailArguments(String username,
1351                                                   String domain) {
1352            return setDomain(domain).setUsername(username);
1353        }
1354
1355        /**
1356         * Sets the {@link #ARG_PROTOCOL} argument.
1357         * @param protocol The protocol of the URI. Examples are "http" and
1358         *     "ftp".
1359         * @return This instance.
1360         */
1361        public ElectronicBuilder setProtocol(String protocol) {
1362            return setStringArgument(TtsSpan.ARG_PROTOCOL, protocol);
1363        }
1364
1365        /**
1366         * Sets the {@link #ARG_USERNAME} argument.
1367         * @return This instance.
1368         */
1369        public ElectronicBuilder setUsername(String username) {
1370            return setStringArgument(TtsSpan.ARG_USERNAME, username);
1371        }
1372
1373        /**
1374         * Sets the {@link #ARG_PASSWORD} argument.
1375         * @return This instance.
1376         */
1377        public ElectronicBuilder setPassword(String password) {
1378            return setStringArgument(TtsSpan.ARG_PASSWORD, password);
1379        }
1380
1381        /**
1382         * Sets the {@link #ARG_DOMAIN} argument.
1383         * @param domain The domain, for example "source.android.com".
1384         * @return This instance.
1385         */
1386        public ElectronicBuilder setDomain(String domain) {
1387            return setStringArgument(TtsSpan.ARG_DOMAIN, domain);
1388        }
1389
1390        /**
1391         * Sets the {@link #ARG_PORT} argument.
1392         * @return This instance.
1393         */
1394        public ElectronicBuilder setPort(int port) {
1395            return setIntArgument(TtsSpan.ARG_PORT, port);
1396        }
1397
1398        /**
1399         * Sets the {@link #ARG_PATH} argument.
1400         * @param path For example "source/index.html".
1401         * @return This instance.
1402         */
1403        public ElectronicBuilder setPath(String path) {
1404            return setStringArgument(TtsSpan.ARG_PATH, path);
1405        }
1406
1407        /**
1408         * Sets the {@link #ARG_QUERY_STRING} argument.
1409         * @param queryString For example "arg=value&argtwo=value".
1410         * @return This instance.
1411         */
1412        public ElectronicBuilder setQueryString(String queryString) {
1413            return setStringArgument(TtsSpan.ARG_QUERY_STRING, queryString);
1414        }
1415
1416        /**
1417         * Sets the {@link #ARG_FRAGMENT_ID} argument.
1418         * @return This instance.
1419         */
1420        public ElectronicBuilder setFragmentId(String fragmentId) {
1421            return setStringArgument(TtsSpan.ARG_FRAGMENT_ID, fragmentId);
1422        }
1423    }
1424
1425    /**
1426     * A builder for TtsSpans of type {@link #TYPE_DIGITS}.
1427     */
1428    public static class DigitsBuilder
1429            extends SemioticClassBuilder<DigitsBuilder> {
1430
1431        /**
1432         * Creates a builder for a TtsSpan of type {@link #TYPE_DIGITS}.
1433         */
1434        public DigitsBuilder() {
1435            super(TtsSpan.TYPE_DIGITS);
1436        }
1437
1438        /**
1439         * Creates a builder for a TtsSpan of type {@link #TYPE_DIGITS}
1440         * and sets the {@link #ARG_DIGITS} argument.
1441         */
1442        public DigitsBuilder(String digits) {
1443            this();
1444            setDigits(digits);
1445        }
1446
1447        /**
1448         * Sets the {@link #ARG_DIGITS} argument.
1449         * @param digits A string of digits.
1450         * @return This instance.
1451         */
1452        public DigitsBuilder setDigits(String digits) {
1453            return setStringArgument(TtsSpan.ARG_DIGITS, digits);
1454        }
1455    }
1456
1457    /**
1458     * A builder for TtsSpans of type {@link #TYPE_VERBATIM}.
1459     */
1460    public static class VerbatimBuilder
1461            extends SemioticClassBuilder<VerbatimBuilder> {
1462
1463        /**
1464         * Creates a builder for a TtsSpan of type {@link #TYPE_VERBATIM}.
1465         */
1466        public VerbatimBuilder() {
1467            super(TtsSpan.TYPE_VERBATIM);
1468        }
1469
1470        /**
1471         * Creates a builder for a TtsSpan of type {@link #TYPE_VERBATIM}
1472         * and sets the {@link #ARG_VERBATIM} argument.
1473         */
1474        public VerbatimBuilder(String verbatim) {
1475            this();
1476            setVerbatim(verbatim);
1477        }
1478
1479        /**
1480         * Sets the {@link #ARG_VERBATIM} argument.
1481         * @param verbatim A string of characters that will be read verbatim,
1482         *     except whitespace.
1483         * @return This instance.
1484         */
1485        public VerbatimBuilder setVerbatim(String verbatim) {
1486            return setStringArgument(TtsSpan.ARG_VERBATIM, verbatim);
1487        }
1488    }
1489}
1490