/*
 * Copyright (C) 2009 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.view.cts;

import com.android.cts.view.R;
import com.android.internal.util.XmlUtils;

import org.xmlpull.v1.XmlPullParser;

import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.XmlResourceParser;
import android.test.AndroidTestCase;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.util.Xml;
import android.view.Gravity;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater.Factory;
import android.view.LayoutInflater.Filter;
import android.widget.LinearLayout;

public class LayoutInflaterTest extends AndroidTestCase {
    private LayoutInflater mLayoutInflater;

    @SuppressWarnings("hiding")
    private Context mContext;

    private final Factory mFactory = new Factory() {
        @Override
        public View onCreateView(String name, Context context, AttributeSet attrs) {
            return null;
        }
    };
    private boolean isOnLoadClass;
    private final Filter mFilter = new Filter() {
        @SuppressWarnings({ "unchecked", "rawtypes" })
        @Override
        public boolean onLoadClass(Class clazz) {
            isOnLoadClass = true;
            return true;
        }

    };

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mContext = getContext();
        mLayoutInflater = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    public void testFrom() {
        mLayoutInflater = null;
        mLayoutInflater = LayoutInflater.from(mContext);
        assertNotNull(mLayoutInflater);
        mLayoutInflater = null;
        mLayoutInflater = new MockLayoutInflater(mContext);
        assertNotNull(mLayoutInflater);

        LayoutInflater layoutInflater = new MockLayoutInflater(mLayoutInflater,
                mContext);
        assertNotNull(layoutInflater);
    }

    public void testAccessLayoutInflaterProperties() {
        mLayoutInflater.setFilter(mFilter);
        assertSame(mFilter, mLayoutInflater.getFilter());
        mLayoutInflater.setFactory(mFactory);
        assertSame(mFactory, mLayoutInflater.getFactory());
        mLayoutInflater=new MockLayoutInflater(mContext);
        assertSame(mContext, mLayoutInflater.getContext());
    }

    private AttributeSet getAttrs() {
        XmlResourceParser parser = null;
        AttributeSet attrs = null;
        ActivityInfo ai = null;
        ComponentName mComponentName = new ComponentName(mContext,
                MockActivity.class);
        try {
            ai = mContext.getPackageManager().getActivityInfo(mComponentName,
                    PackageManager.GET_META_DATA);
            parser = ai.loadXmlMetaData(mContext.getPackageManager(),
                    "android.widget.layout");
            int type;
            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                    && type != XmlPullParser.START_TAG) {
            }
            String nodeName = parser.getName();
            if (!"alias".equals(nodeName)) {
                throw new InflateException();
            }
            int outerDepth = parser.getDepth();
            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                    continue;
                }
                nodeName = parser.getName();
                if ("AbsoluteLayout".equals(nodeName)) {
                    attrs = Xml.asAttributeSet(parser);
                } else {
                    XmlUtils.skipCurrentTag(parser);
                }
            }
        } catch (Exception e) {
        }
        return attrs;
    }

    public void testCreateView() {

        AttributeSet attrs = getAttrs();
        isOnLoadClass = false;
        View view = null;
        try {
            view = mLayoutInflater
                    .createView("testthrow", "com.android", attrs);
            fail("should throw exception");
        } catch (InflateException e) {
        } catch (ClassNotFoundException e) {
        }
        assertFalse(isOnLoadClass);
        assertNull(view);
        mLayoutInflater = null;
        mLayoutInflater = LayoutInflater.from(mContext);
        isOnLoadClass = false;
        mLayoutInflater.setFilter(new Filter() {
            @SuppressWarnings({ "unchecked", "rawtypes" })
            @Override
            public boolean onLoadClass(Class clazz) {
                isOnLoadClass = true;
                return false;
            }
        });
        try {
            view = mLayoutInflater.createView("MockActivity",
                    "com.android.app.", attrs);
            fail("should throw exception");
        } catch (InflateException e) {
        } catch (ClassNotFoundException e) {
        }
        assertFalse(isOnLoadClass);
        assertNull(view);

        isOnLoadClass = false;
        // allowedState is false
        try {
            view = mLayoutInflater.createView(MockActivity.class.getName(),
                    MockActivity.class.getPackage().toString(), attrs);
            fail("should throw exception");
        } catch (InflateException e) {
        } catch (ClassNotFoundException e) {
        }
        assertFalse(isOnLoadClass);
        assertNull(view);
        mLayoutInflater = null;
        mLayoutInflater = LayoutInflater.from(mContext);
        try {
            mLayoutInflater.setFilter(null);
            view = mLayoutInflater.createView("com.android.app.MockActivity",
                    null, attrs);
            assertNotNull(view);
            assertFalse(isOnLoadClass);
            mLayoutInflater = null;
            mLayoutInflater = LayoutInflater.from(mContext);
            mLayoutInflater.setFilter(null);

            view = mLayoutInflater.createView(MockActivity.class.getName(),
                    MockActivity.class.getPackage().toString(), attrs);
            assertNotNull(view);
            assertFalse(isOnLoadClass);
            mLayoutInflater.setFilter(mFilter);
            view = mLayoutInflater.createView(MockActivity.class.getName(),
                    MockActivity.class.getPackage().toString(), attrs);
            assertNotNull(view);
            assertTrue(isOnLoadClass);
            // allowedState!=null
            view = mLayoutInflater.createView(MockActivity.class.getName(),
                    MockActivity.class.getPackage().toString(), attrs);
            assertNotNull(view);
            assertTrue(isOnLoadClass);
        } catch (InflateException e) {
        } catch (ClassNotFoundException e) {
        }
    }

    public void testInflate() {
        View view = mLayoutInflater.inflate(
                com.android.cts.view.R.layout.inflater_layout, null);
        assertNotNull(view);
        view = null;
        try {
            view = mLayoutInflater.inflate(-1, null);
            fail("should throw exception");
        } catch (Resources.NotFoundException e) {
        }
        LinearLayout mLayout;
        mLayout = new LinearLayout(mContext);
        mLayout.setOrientation(LinearLayout.VERTICAL);
        mLayout.setHorizontalGravity(Gravity.LEFT);
        mLayout.setLayoutParams(new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT));
        assertEquals(0, mLayout.getChildCount());
        view = mLayoutInflater.inflate(R.layout.inflater_layout,
                mLayout);
        assertNotNull(view);
        assertEquals(1, mLayout.getChildCount());
    }

    public void testInflate2() {
        View view = mLayoutInflater.inflate(
                R.layout.inflater_layout, null, false);
        assertNotNull(view);
        view = null;
        try {
            view = mLayoutInflater.inflate(-1, null, false);
            fail("should throw exception");
        } catch (Resources.NotFoundException e) {

        }
        LinearLayout mLayout;
        mLayout = new LinearLayout(mContext);
        mLayout.setOrientation(LinearLayout.VERTICAL);
        mLayout.setHorizontalGravity(Gravity.LEFT);
        mLayout.setLayoutParams(new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT));
        assertEquals(0, mLayout.getChildCount());
        view = mLayoutInflater.inflate(R.layout.inflater_layout,
                mLayout, false);
        assertNotNull(view);
        assertEquals(0, mLayout.getChildCount());

        view = null;
        view = mLayoutInflater.inflate(R.layout.inflater_layout,
                mLayout, true);
        assertNotNull(view);
        assertEquals(1, mLayout.getChildCount());
    }

    public void testInflate3() {
        XmlResourceParser parser = getContext().getResources().getLayout(
                R.layout.inflater_layout);
        View view = mLayoutInflater.inflate(parser, null);
        assertNotNull(view);
        view = null;
        try {
            view = mLayoutInflater.inflate(null, null);
            fail("should throw exception");
        } catch (NullPointerException e) {
        }
        LinearLayout mLayout;
        mLayout = new LinearLayout(mContext);
        mLayout.setOrientation(LinearLayout.VERTICAL);
        mLayout.setHorizontalGravity(Gravity.LEFT);
        mLayout.setLayoutParams(new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT));
        assertEquals(0, mLayout.getChildCount());

        try {
            view = mLayoutInflater.inflate(parser, mLayout);
            fail("should throw exception");
        } catch (NullPointerException e) {
        }
        parser = getContext().getResources().getLayout(
                R.layout.inflater_layout);
        view = mLayoutInflater.inflate(parser, mLayout);
        assertNotNull(view);
        assertEquals(1, mLayout.getChildCount());
        parser = getContext().getResources().getLayout(
                R.layout.inflater_layout);
        view = mLayoutInflater.inflate(parser, mLayout);
        assertNotNull(view);
        assertEquals(2, mLayout.getChildCount());

        parser = null;
        view = null;
        parser = getParser();

        view = mLayoutInflater.inflate(parser, mLayout);
        assertNotNull(view);
        assertEquals(3, mLayout.getChildCount());
    }

    public void testInflate4() {
        XmlResourceParser parser = getContext().getResources().getLayout(
                R.layout.inflater_layout);
        View view = mLayoutInflater.inflate(parser, null, false);
        assertNotNull(view);
        view = null;
        try {
            view = mLayoutInflater.inflate(null, null, false);
            fail("should throw exception");
        } catch (NullPointerException e) {
        }
        LinearLayout mLayout;
        mLayout = new LinearLayout(mContext);
        mLayout.setOrientation(LinearLayout.VERTICAL);
        mLayout.setHorizontalGravity(Gravity.LEFT);
        mLayout.setLayoutParams(new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT));
        assertEquals(0, mLayout.getChildCount());

        try {
            view = mLayoutInflater.inflate(parser, mLayout, false);
            fail("should throw exception");
        } catch (NullPointerException e) {
        }
        parser = getContext().getResources().getLayout(
                R.layout.inflater_layout);
        view = mLayoutInflater.inflate(parser, mLayout, false);
        assertNull(view.getParent());
        assertNotNull(view);
        assertEquals(0, mLayout.getChildCount());
        parser = getContext().getResources().getLayout(
                R.layout.inflater_layout);
        assertEquals(0, mLayout.getChildCount());
        view = mLayoutInflater.inflate(parser, mLayout, true);
        assertNotNull(view);
        assertNull(view.getParent());
        assertEquals(1, mLayout.getChildCount());

        parser = null;
        parser = getParser();
        try {
            view = mLayoutInflater.inflate(parser, mLayout, false);
            fail("should throw exception");
        } catch (InflateException e) {
        }

        parser = null;
        view = null;
        parser = getParser();

        view = mLayoutInflater.inflate(parser, mLayout, true);
        assertNotNull(view);
        assertEquals(2, mLayout.getChildCount());
    }

    public void testOverrideTheme() {
        View container = mLayoutInflater.inflate(R.layout.inflater_override_theme_layout, null);
        verifyThemeType(container, "view_outer", R.id.view_outer, 1);
        verifyThemeType(container, "view_inner", R.id.view_inner, 2);
        verifyThemeType(container, "view_attr", R.id.view_attr, 3);
    }

    private void verifyThemeType(View container, String tag, int id, int type) {
        TypedValue outValue = new TypedValue();
        View view = container.findViewById(id);
        assertNotNull("Found " + tag, view);
        Theme theme = view.getContext().getTheme();
        boolean resolved = theme.resolveAttribute(R.attr.themeType, outValue, true);
        assertTrue("Resolved themeType for " + tag, resolved);
        assertEquals(tag + " has themeType " + type, type, outValue.data);
    }

    public void testInflateTags() {
        final View view = mLayoutInflater.inflate(
                com.android.cts.view.R.layout.inflater_layout_tags, null);
        assertNotNull(view);

        checkViewTag(view, R.id.viewlayout_root, R.id.tag_viewlayout_root, R.string.tag1);
        checkViewTag(view, R.id.mock_view, R.id.tag_mock_view, R.string.tag2);
    }

    private void checkViewTag(View parent, int viewId, int tagId, int valueResId) {
        final View target = parent.findViewById(viewId);
        assertNotNull("Found target view for " + viewId, target);

        final Object tag = target.getTag(tagId);
        assertNotNull("Tag is set", tag);
        assertTrue("Tag is a character sequence", tag instanceof CharSequence);

        final Context targetContext = target.getContext();
        final CharSequence expectedValue = targetContext.getString(valueResId);
        assertEquals(tagId + " has tag " + expectedValue, expectedValue, tag);
    }

    static class MockLayoutInflater extends LayoutInflater {

        public MockLayoutInflater(Context c) {
            super(c);
        }

        public MockLayoutInflater(LayoutInflater original, Context newContext) {
            super(original, newContext);
        }

        @Override
        public View onCreateView(String name, AttributeSet attrs)
                throws ClassNotFoundException {
            return super.onCreateView(name, attrs);
        }

        @Override
        public LayoutInflater cloneInContext(Context newContext) {
            return null;
        }
    }

    private XmlResourceParser getParser() {
        XmlResourceParser parser = null;
        ActivityInfo ai = null;
        ComponentName mComponentName = new ComponentName(mContext,
                MockActivity.class);
        try {
            ai = mContext.getPackageManager().getActivityInfo(mComponentName,
                    PackageManager.GET_META_DATA);
            parser = ai.loadXmlMetaData(mContext.getPackageManager(),
                    "android.view.merge");
        } catch (Exception e) {
        }
        return parser;
    }
}
