/*
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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 flash.localization;

import java.util.*;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * A utility class for looking up localized text.
 */
public class LocalizationManager
{
    private Locale locale = Locale.getDefault();
    private List<ILocalizer> localizers = new LinkedList<ILocalizer>();

    public LocalizationManager()
    {
    }

    public void addLocalizer( ILocalizer localizer )
    {
        localizers.add( localizer );
    }

    private ILocalizedText getLocalizedTextInner( Locale locale, String id )
    {
        for (Iterator it = localizers.iterator(); it.hasNext(); )
        {
            ILocalizer localizer = (ILocalizer) it.next();

            ILocalizedText text = localizer.getLocalizedText( locale, id );

            if (text != null)
            {
                return text;
            }
        }

        return null;
    }

    private ILocalizedText getLocalizedText( Locale locale, String id )
    {
        ILocalizedText t = getLocalizedTextInner( locale, id );

        if ((t == null) && (locale.getCountry().length() > 0) && (locale.getVariant().length() > 0))
        {
            t = getLocalizedTextInner( new Locale( locale.getLanguage(), locale.getCountry() ), id );
        }

        if ((t == null) && (locale.getCountry().length() > 0))
        {
            t = getLocalizedTextInner( new Locale( locale.getLanguage() ), id );
        }

        return t;
    }

    protected static String replaceInlineReferences( String text, Map parameters )
    {
        if (parameters == null)
            return text;

        int depth = 100;
        while (depth-- > 0)
        {
            int o = text.indexOf( "${" );
            if (o == -1)
                break;
            if ((o >= 1) && (text.charAt( o-1 ) == '$'))
            {
                o = text.indexOf( "${", o+2 );
                if (o == -1)
                    break;
            }

            int c = text.indexOf( "}", o );

            if (c == -1)
            {
                return null; // FIXME
            }
            String name = text.substring( o + 2, c );
            String value = null;
            if (parameters.containsKey( name ) && (parameters.get( name ) != null))
            {
                value = parameters.get( name ).toString();
            }

            if (value == null)
            {
                value = "";
            }
            text = text.substring( 0, o ) + value + text.substring( c + 1 );
        }
        return text.replaceAll( "[$][$][{]", "\\${" );
    }

	public String getLocalizedTextString( String id )
	{
		return getLocalizedTextString( id, Collections.EMPTY_MAP );
	}

	public String getLocalizedTextString( String id, Map parameters )
	{
		return getLocalizedTextString(locale, id, parameters );
	}

    public String getLocalizedTextString( Locale locale, String id, Map parameters )
    {
        ILocalizedText t = getLocalizedText( locale, id );

        if ((t == null) && !locale.equals(locale))
        {
            t = getLocalizedText(locale, id );
        }
        if ((t == null) && !locale.getLanguage().equals( "en" ))
        {
            t = getLocalizedText( new Locale( "en" ), id );
        }

        return (t == null)? null : t.format( parameters );
    }

	public String getLocalizedTextString( Object object )
	{
		String s = getLocalizedTextString(locale, object );

        return s;
    }

    // todo - this is a pretty specialized helper function, hoist up to client code?
    public String getLocalizedTextString( Locale locale, Object object )
    {
        String id = object.getClass().getName().replaceAll( "\\$", "." );

        Map<String, Object> parameters = new HashMap<String, Object>();
        Class c = object.getClass();

        while (c != Object.class)
        {
            Field[] fields = c.getDeclaredFields();

            for (int i = 0; i < fields.length; ++i)
            {
                Field f = fields[i];

                if (!Modifier.isPublic( f.getModifiers() ))
                {
                    continue;
                }
                if (Modifier.isStatic( f.getModifiers() ))
                {
                    continue;
                }

                try
                {
                    parameters.put( f.getName(), f.get( object ) );
                }
                catch (Exception e)
                {
                }
            }
            c = c.getSuperclass();
        }

        String s = null;
        if ((parameters.containsKey( "id" ) && parameters.get( "id" ) != null ))
        {
            String subid = parameters.get( "id" ).toString();
            if (subid.length() > 0)
            {
                // fixme - Formalize?
                s = getLocalizedTextString( locale, id + "." + subid, parameters );
            }
        }
        if (s == null)
        {
            s = getLocalizedTextString( locale, id, parameters );
        }

        if (s == null)
        {
            s = id;

            if (parameters != null)
            {
                s += "[";
                for (Iterator it = parameters.entrySet().iterator(); it.hasNext(); )
                {
                    Map.Entry e = (Map.Entry) it.next();
                    s += e.getKey();
                    if (e.getValue() != null)
                        s += "='" + e.getValue() + "'";
                    if (it.hasNext())
                        s += ", ";
                }
                s += "]";
            }
            return s;
        }

        return s;
    }

    public Locale getLocale()
    {
    	return this.locale;
    }

    public void setLocale(Locale locale)
    {
        this.locale = locale;
    }
}
