/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * 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 android.transition;

import android.annotation.TransitionRes;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.Xml;
import android.view.InflateException;
import android.view.ViewGroup;

import com.android.internal.R;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * This class inflates scenes and transitions from resource files.
 *
 * Information on XML resource descriptions for transitions can be found for
 * {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet},
 * {@link android.R.styleable#TransitionTarget}, {@link android.R.styleable#Fade},
 * and {@link android.R.styleable#TransitionManager}.
 */
public class TransitionInflater {

    private static final Class<?>[] sConstructorSignature = new Class[] {
            Context.class, AttributeSet.class};
    private final static ArrayMap<String, Constructor> sConstructors =
            new ArrayMap<String, Constructor>();

    private Context mContext;

    private TransitionInflater(Context context) {
        mContext = context;
    }

    /**
     * Obtains the TransitionInflater from the given context.
     */
    public static TransitionInflater from(Context context) {
        return new TransitionInflater(context);
    }

    /**
     * Loads a {@link Transition} object from a resource
     *
     * @param resource The resource id of the transition to load
     * @return The loaded Transition object
     * @throws android.content.res.Resources.NotFoundException when the
     * transition cannot be loaded
     */
    public Transition inflateTransition(@TransitionRes int resource) {
        //noinspection ResourceType
        XmlResourceParser parser =  mContext.getResources().getXml(resource);
        try {
            return createTransitionFromXml(parser, Xml.asAttributeSet(parser), null);
        } catch (XmlPullParserException e) {
            InflateException ex = new InflateException(e.getMessage());
            ex.initCause(e);
            throw ex;
        } catch (IOException e) {
            InflateException ex = new InflateException(
                    parser.getPositionDescription()
                            + ": " + e.getMessage());
            ex.initCause(e);
            throw ex;
        } finally {
            parser.close();
        }
    }

    /**
     * Loads a {@link TransitionManager} object from a resource
     *
     * @param resource The resource id of the transition manager to load
     * @return The loaded TransitionManager object
     * @throws android.content.res.Resources.NotFoundException when the
     * transition manager cannot be loaded
     */
    public TransitionManager inflateTransitionManager(@TransitionRes int resource,
            ViewGroup sceneRoot) {
        //noinspection ResourceType
        XmlResourceParser parser =  mContext.getResources().getXml(resource);
        try {
            return createTransitionManagerFromXml(parser, Xml.asAttributeSet(parser), sceneRoot);
        } catch (XmlPullParserException e) {
            InflateException ex = new InflateException(e.getMessage());
            ex.initCause(e);
            throw ex;
        } catch (IOException e) {
            InflateException ex = new InflateException(
                    parser.getPositionDescription()
                            + ": " + e.getMessage());
            ex.initCause(e);
            throw ex;
        } finally {
            parser.close();
        }
    }

    //
    // Transition loading
    //
    private Transition createTransitionFromXml(XmlPullParser parser,
            AttributeSet attrs, Transition parent)
            throws XmlPullParserException, IOException {

        Transition transition = null;

        // Make sure we are on a start tag.
        int type;
        int depth = parser.getDepth();

        TransitionSet transitionSet = (parent instanceof TransitionSet)
                ? (TransitionSet) parent : null;

        while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
                && type != XmlPullParser.END_DOCUMENT) {

            if (type != XmlPullParser.START_TAG) {
                continue;
            }

            String  name = parser.getName();
            if ("fade".equals(name)) {
                transition = new Fade(mContext, attrs);
            } else if ("changeBounds".equals(name)) {
                transition = new ChangeBounds(mContext, attrs);
            } else if ("slide".equals(name)) {
                transition = new Slide(mContext, attrs);
            } else if ("explode".equals(name)) {
                transition = new Explode(mContext, attrs);
            } else if ("changeImageTransform".equals(name)) {
                transition = new ChangeImageTransform(mContext, attrs);
            } else if ("changeTransform".equals(name)) {
                transition = new ChangeTransform(mContext, attrs);
            } else if ("changeClipBounds".equals(name)) {
                transition = new ChangeClipBounds(mContext, attrs);
            } else if ("autoTransition".equals(name)) {
                transition = new AutoTransition(mContext, attrs);
            } else if ("recolor".equals(name)) {
                transition = new Recolor(mContext, attrs);
            } else if ("changeScroll".equals(name)) {
                transition = new ChangeScroll(mContext, attrs);
            } else if ("transitionSet".equals(name)) {
                transition = new TransitionSet(mContext, attrs);
            } else if ("transition".equals(name)) {
                transition = (Transition) createCustom(attrs, Transition.class, "transition");
            } else if ("targets".equals(name)) {
                getTargetIds(parser, attrs, parent);
            } else if ("arcMotion".equals(name)) {
                parent.setPathMotion(new ArcMotion(mContext, attrs));
            } else if ("pathMotion".equals(name)) {
                parent.setPathMotion((PathMotion)createCustom(attrs, PathMotion.class, "pathMotion"));
            } else if ("patternPathMotion".equals(name)) {
                parent.setPathMotion(new PatternPathMotion(mContext, attrs));
            } else {
                throw new RuntimeException("Unknown scene name: " + parser.getName());
            }
            if (transition != null) {
                if (!parser.isEmptyElementTag()) {
                    createTransitionFromXml(parser, attrs, transition);
                }
                if (transitionSet != null) {
                    transitionSet.addTransition(transition);
                    transition = null;
                } else if (parent != null) {
                    throw new InflateException("Could not add transition to another transition.");
                }
            }
        }

        return transition;
    }

    private Object createCustom(AttributeSet attrs, Class expectedType, String tag) {
        String className = attrs.getAttributeValue(null, "class");

        if (className == null) {
            throw new InflateException(tag + " tag must have a 'class' attribute");
        }

        try {
            synchronized (sConstructors) {
                Constructor constructor = sConstructors.get(className);
                if (constructor == null) {
                    Class c = mContext.getClassLoader().loadClass(className)
                            .asSubclass(expectedType);
                    if (c != null) {
                        constructor = c.getConstructor(sConstructorSignature);
                        constructor.setAccessible(true);
                        sConstructors.put(className, constructor);
                    }
                }
                return constructor.newInstance(mContext, attrs);
            }
        } catch (InstantiationException e) {
            throw new InflateException("Could not instantiate " + expectedType + " class " +
                    className, e);
        } catch (ClassNotFoundException e) {
            throw new InflateException("Could not instantiate " + expectedType + " class " +
                    className, e);
        } catch (InvocationTargetException e) {
            throw new InflateException("Could not instantiate " + expectedType + " class " +
                    className, e);
        } catch (NoSuchMethodException e) {
            throw new InflateException("Could not instantiate " + expectedType + " class " +
                    className, e);
        } catch (IllegalAccessException e) {
            throw new InflateException("Could not instantiate " + expectedType + " class " +
                    className, e);
        }
    }

    private void getTargetIds(XmlPullParser parser,
            AttributeSet attrs, Transition transition) throws XmlPullParserException, IOException {

        // Make sure we are on a start tag.
        int type;
        int depth = parser.getDepth();

        while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
                && type != XmlPullParser.END_DOCUMENT) {

            if (type != XmlPullParser.START_TAG) {
                continue;
            }

            String  name = parser.getName();
            if (name.equals("target")) {
                TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.TransitionTarget);
                int id = a.getResourceId(R.styleable.TransitionTarget_targetId, 0);
                String transitionName;
                if (id != 0) {
                    transition.addTarget(id);
                } else if ((id = a.getResourceId(R.styleable.TransitionTarget_excludeId, 0)) != 0) {
                    transition.excludeTarget(id, true);
                } else if ((transitionName = a.getString(R.styleable.TransitionTarget_targetName))
                        != null) {
                    transition.addTarget(transitionName);
                } else if ((transitionName = a.getString(R.styleable.TransitionTarget_excludeName))
                        != null) {
                    transition.excludeTarget(transitionName, true);
                } else {
                    String className = a.getString(R.styleable.TransitionTarget_excludeClass);
                    try {
                        if (className != null) {
                            Class clazz = Class.forName(className);
                            transition.excludeTarget(clazz, true);
                        } else if ((className =
                                a.getString(R.styleable.TransitionTarget_targetClass)) != null) {
                            Class clazz = Class.forName(className);
                            transition.addTarget(clazz);
                        }
                    } catch (ClassNotFoundException e) {
                        a.recycle();
                        throw new RuntimeException("Could not create " + className, e);
                    }
                }
                a.recycle();
            } else {
                throw new RuntimeException("Unknown scene name: " + parser.getName());
            }
        }
    }

    //
    // TransitionManager loading
    //

    private TransitionManager createTransitionManagerFromXml(XmlPullParser parser,
            AttributeSet attrs, ViewGroup sceneRoot) throws XmlPullParserException, IOException {

        // Make sure we are on a start tag.
        int type;
        int depth = parser.getDepth();
        TransitionManager transitionManager = null;

        while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
                && type != XmlPullParser.END_DOCUMENT) {

            if (type != XmlPullParser.START_TAG) {
                continue;
            }

            String  name = parser.getName();
            if (name.equals("transitionManager")) {
                transitionManager = new TransitionManager();
            } else if (name.equals("transition") && (transitionManager != null)) {
                loadTransition(attrs, sceneRoot, transitionManager);
            } else {
                throw new RuntimeException("Unknown scene name: " + parser.getName());
            }
        }
        return transitionManager;
    }

    private void loadTransition(AttributeSet attrs, ViewGroup sceneRoot,
            TransitionManager transitionManager) throws Resources.NotFoundException {

        TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.TransitionManager);
        int transitionId = a.getResourceId(R.styleable.TransitionManager_transition, -1);
        int fromId = a.getResourceId(R.styleable.TransitionManager_fromScene, -1);
        Scene fromScene = (fromId < 0) ? null: Scene.getSceneForLayout(sceneRoot, fromId, mContext);
        int toId = a.getResourceId(R.styleable.TransitionManager_toScene, -1);
        Scene toScene = (toId < 0) ? null : Scene.getSceneForLayout(sceneRoot, toId, mContext);

        if (transitionId >= 0) {
            Transition transition = inflateTransition(transitionId);
            if (transition != null) {
                if (toScene == null) {
                    throw new RuntimeException("No toScene for transition ID " + transitionId);
                }
                if (fromScene == null) {
                    transitionManager.setTransition(toScene, transition);
                } else {
                    transitionManager.setTransition(fromScene, toScene, transition);
                }
            }
        }
        a.recycle();
    }
}
