I18n

package revel

const (
    CurrentLocaleRenderArg = "currentLocale" // The key for the current locale render arg value

)

// Return all currently loaded message languages.
func MessageLanguages() []string {
    languages := make([]string, len(messages))
    i := 0
    for language, _ := range messages {
        languages[i] = language
        i++
    }
    return languages
}

// Perform a message look-up for the given locale and message using the given arguments.
//
// When either an unknown locale or message is detected, a specially formatted string is returned.
func Message(locale, message string, args ...interface{}) string {
    language, region := parseLocale(locale)
    TRACE.Printf("Resolving message '%s' for language '%s' and region '%s'", message, language, region)

    messageConfig, knownLanguage := messages[language]
    if !knownLanguage {
        TRACE.Printf("Unsupported language for locale '%s' and message '%s', trying default language", locale, message)

        if defaultLanguage, found := Config.String(defaultLanguageOption); found {
            TRACE.Printf("Using default language '%s'", defaultLanguage)

            messageConfig, knownLanguage = messages[defaultLanguage]
            if !knownLanguage {
                WARN.Printf("Unsupported default language for locale '%s' and message '%s'", defaultLanguage, message)
                return fmt.Sprintf(unknownValueFormat, message)
            }
        } else {
            WARN.Printf("Unable to find default language option (%s); messages for unsupported locales will never be translated", defaultLanguageOption)
            return fmt.Sprintf(unknownValueFormat, message)
        }
    }

    // This works because unlike the goconfig documentation suggests it will actually
    // try to resolve message in DEFAULT if it did not find it in the given section.
    value, error := messageConfig.String(region, message)
    if error != nil {
        WARN.Printf("Unknown message '%s' for locale '%s'", message, locale)
        return fmt.Sprintf(unknownValueFormat, message)
    }

    if len(args) > 0 {
        TRACE.Printf("Arguments detected, formatting '%s' with %v", value, args)
        value = fmt.Sprintf(value, args...)
    }

    return value
}

func I18nFilter(c *Controller, fc []Filter) {
    if foundCookie, cookieValue := hasLocaleCookie(c.Request); foundCookie {
        TRACE.Printf("Found locale cookie value: %s", cookieValue)
        setCurrentLocaleControllerArguments(c, cookieValue)
    } else if foundHeader, headerValue := hasAcceptLanguageHeader(c.Request); foundHeader {
        TRACE.Printf("Found Accept-Language header value: %s", headerValue)
        setCurrentLocaleControllerArguments(c, headerValue)
    } else {
        TRACE.Println("Unable to find locale in cookie or header, using empty string")
        setCurrentLocaleControllerArguments(c, "")
    }
    fc[0](c, fc[1:])
}