import { Building, Category, Floor, POI } from '../Venue';
import { CategoryLocaleEntry } from './CategoryLocaleEntry';
import { POILocaleEntry } from './POILocaleEntry';
import { VenueLocaleEntry } from './VenueLocaleEntry';

/**
 * Context allow variations in translations.
 * It consists in a map of key/value.
 * Internally VisioOne relies on https://www.i18next.com/ and the "context" must conform to the
 * "context" parameter used by this library.
 * The previous documentation can be useful for instance to translate locales that support several genders.
 */
export interface Context {
    readonly [key: string]: string;
}
/**
 * Resources contains locales entries.
 * It consists in a map of key/value.
 * The list of all keys is available separately.
 * Internally VisioOne relies on https://www.i18next.com/ and the "resources" must conform to the
 * "resources" parameter used by this library. The previous documentation can be useful for instance to translate
 * plurals where locales support several plural.
 */
export interface Resources {
    readonly [key: string]: string;
}
export interface Translator {
    /**
     * The list of all locales existing for this venue.
     *
     * Note that it is possible to add more locales at runtime using the {@link addLocale | addLocale} method.
     */
    readonly allLocales: string[];
    /**
     * Retrieve a LocaleEntry for a given POI.
     * @param poi the POI to translate.
     * @param locale the locale to translate to.
     * @return the POILocaleEntry for the given POI. If it doesn't exist for this POI and locale it will return
     * the POILocaleEntry for the default locale, if it still doesn't exist, it will return a POILocaleEntry with empty strings
     * and values.
     */
    translatePOI(poi: POI, locale: string): POILocaleEntry;
    /**
     * Retrieve a LocaleEntry for a given Floor.
     * @param floor the Floor to translate.
     * @param locale the locale to translate to.
     * @return the VenueLocaleEntry for the given Floor. If it doesn't exist for this Floor and locale it will return
     * the VenueLocaleEntry for the default locale, if it still doesn't exist, it will return a VenueLocaleEntry with empty strings
     * and values.
     */
    translateFloor(floor: Floor, locale: string): VenueLocaleEntry;
    /**
     * Retrieve a LocaleEntry for a given Building.
     * @param building the Building to translate.
     * @param locale the locale to translate to.
     * @return the VenueLocaleEntry for the given Building. If it doesn't exist for this Building and locale it will return
     * the VenueLocaleEntry for the default locale, if it still doesn't exist, it will return a VenueLocaleEntry with empty strings
     * and values.
     */
    translateBuilding(building: Building, locale: string): VenueLocaleEntry;
    /**
     * Translate a Category.
     * @param category the Category to translate.
     * @param locale the locale to translate to.
     * @return the translated Category. If it doesn't exist for this Building and locale it will return
     * the Category for the default locale, if it still doesn't exist, it will return a Category with empty strings
     * and values.
     */
    translateCategory(category: Category, locale: string): CategoryLocaleEntry;
    /**
     * Translate given key to given locale.
     * @param key key of the translation you look for.
     * @param locale locale in which you want to translate.
     * @param context according to {@link Context}, translation may have variation depending on context.
     * This is an example of simple use:
     * @example
     * const localeFoo = {
     *   singers: 'a band',
     *   singers_male: 'a boys band',
     *   singers_female: 'a girls band with {{ count }} singers'
     * };
     * myVenue.translator.addLocale('foo', localeFoo);
     * myVenue.translator.translate('singers', 'foo') // => 'a band'
     * myVenue.translator.translate('singers', 'foo', { context: 'male' }) // => 'a boys band'
     * myVenue.translator.translate('singer', 'foo', { context: 'female', count: 5}) // => 'a girls band with {{ count }} singers'
     */
    translate(key: string, locale: string, context?: Context): string;
    /**
     * Create a locale at runtime. It will not be saved once the application is reloaded.
     * @param locale the locale to create.
     * @param resources the locale entry. It consists in a map of key/value. The list of all keys is available separately.
     * Internally VisioOne relies on https://www.i18next.com/ and the "resources" parameter must conform to the
     * "resources" parameter used by this library. The previous documentation can be useful for instance to translate
     * plurals where locales support several plural.
     *
     * Translation keys for Navigation are:
     *  * changeModality
     *  * changeFloor
     *  * goDown
     *  * goUp
     *  * waypoint
     *  * goStraight
     *  * turnGentleLeft
     *  * turnGentleRight
     *  * turnRight
     *  * turnLeft
     *  * turnSharpRight
     *  * turnSharpLeft
     *  * end
     *
     * Translation keys for UI are:
     *  * 'about'
     *  * 'level'
     *  * 'search-for-anything'
     *  * 'what-are-you-looking-for'
     *  * 'recent-searches'
     *  * 'close'
     *  * 'cancel'
     *  * 'go'
     *  * 'add-a-step'
     *  * 'edit-step'
     *  * 'remove-step'
     *  * 'start'
     *  * 'stop'
     *  * 'poi-info-placeholder-1'
     *  * 'open'
     *  * 'until'
     *  * 'monday'
     *  * 'tuesday'
     *  * 'wednesday'
     *  * 'thursday'
     *  * 'friday'
     *  * 'saturday'
     *  * 'sunday'
     *  * 'my-position'
     *  * 'choose-start-position'
     *  * 'itinerary'
     *  * 'itinerary-options'
     *  * 'accessible-navigation'
     *  * 'optimize-itinerary'
     *  * 'choose-on-map'
     *  * 'choose'
     *  * 'less-than-1-minute'
     *  * 'around-in-distance'
     *  * 'around-in-distance_km'
     *  * 'around-in-minute_one'
     *  * 'around-in-minute_other'
     *  * 'around-in-hour_one'
     *  * 'around-in-hour_other'
     *  * 'adding-way-point'
     *  * 'adding-way-point-notice'
     *
     * This is an example of runtime added locales:
     * @example
     * const locales = {
     *   en: {
     *     'i-am-the-key': 'I am the value',
     *     iAmAnotherKey: 'I am another value',
     *     key: 'one value',
     *     key_many: '{{ count }} values', // Use it with Context
     *   },
     *   ja: {
     *     hello: 'こんにちは',
     *     turn_right: '右折',
     *   }
     * };
     * myVenue.translator.addLocale('en', locales.en);
     * myVenue.translator.addLocale('ja', locales.ja);
     *
     * myVenue.translator.translate('hello', 'ja') // => 'こんにちは'
     * myVenue.translator.translate('iAmAnotherKey', 'en') // => 'I am another value'
     */
    addLocale(locale: string, resources: Resources): void;
    /**
     * Remove a locale for the available locales.
     * @param locale the locale to remove
     */
    removeLocale(locale: string): void;
    /**
     * Retrieve the translation resources for a specific locale.
     * @param locale The locale to retrieve the translation resources.
     * @return All the defined translation resources for the specified locale. This is a key-value structure
     * allowing to translate a semantic code into an internationalized string.
     */
    getLocale(locale: string): Resources;
}
