/*
 * 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 com.android.wallpaper.livepicker;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.WallpaperColors;
import android.app.WallpaperInfo;
import android.app.WallpaperManager;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources.NotFoundException;
import android.graphics.Outline;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.service.wallpaper.IWallpaperConnection;
import android.service.wallpaper.IWallpaperEngine;
import android.service.wallpaper.IWallpaperService;
import android.service.wallpaper.WallpaperService;
import android.service.wallpaper.WallpaperSettingsActivity;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.view.ContextThemeWrapper;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.WindowManager.LayoutParams;
import android.view.animation.AnimationUtils;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toolbar;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.LiveData;
import androidx.slice.Slice;
import androidx.slice.widget.SliceLiveData;
import androidx.slice.widget.SliceView;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback;
import com.google.android.material.tabs.TabLayout;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class LiveWallpaperPreview extends Activity {
    static final String EXTRA_LIVE_WALLPAPER_INFO = "android.live_wallpaper.info";

    private static final String LOG_TAG = "LiveWallpaperPreview";

    private static final boolean SHOW_FAKE_DATA = false;

    private WallpaperManager mWallpaperManager;
    private WallpaperConnection mWallpaperConnection;

    private Intent mWallpaperIntent;
    private Intent mSettingsIntent;
    private Intent mDeleteIntent;

    private View mLoading;
    private View mViewBottomPane;
    private BottomSheetBehavior mBottomSheetBehavior;
    private ViewPager mViewPager;
    private TabLayout mTabLayout;
    private CheckBox mPreview;

    protected final List<Pair<String, View>> mPages = new ArrayList<>();
    private SliceView mSliceViewSettings;
    private LiveData<Slice> mLiveDataSettings;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        init();
    }

    protected void init() {
        WallpaperInfo info = getIntent().getParcelableExtra(EXTRA_LIVE_WALLPAPER_INFO);
        if (info == null) {
            finish();
            return;
        }
        initUI(info, null /* deleteAction */);
    }

    protected void initUI(WallpaperInfo info, @Nullable String deleteAction) {
        getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
        setContentView(R.layout.live_wallpaper_preview);
        mLoading = findViewById(R.id.loading);

        final String packageName = info.getPackageName();
        mWallpaperIntent = new Intent(WallpaperService.SERVICE_INTERFACE)
                .setClassName(info.getPackageName(), info.getServiceName());

        final String settingsActivity = info.getSettingsActivity();
        if (settingsActivity != null) {
            mSettingsIntent = new Intent();
            mSettingsIntent.setComponent(new ComponentName(packageName, settingsActivity));
            mSettingsIntent.putExtra(WallpaperSettingsActivity.EXTRA_PREVIEW_MODE, true);
            final PackageManager pm = getPackageManager();
            final ActivityInfo activityInfo = mSettingsIntent.resolveActivityInfo(pm, 0);
            if (activityInfo == null) {
                Log.e(LOG_TAG, "Couldn't find settings activity: " + settingsActivity);
                mSettingsIntent = null;
            }
        }

        final Toolbar toolbar = findViewById(R.id.toolbar);
        setActionBar(toolbar);
        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setDisplayShowTitleEnabled(false);

        final Drawable backArrow = getDrawable(R.drawable.ic_arrow_back_white_24dp);
        backArrow.setAutoMirrored(true);
        toolbar.setNavigationIcon(backArrow);

        mWallpaperManager = WallpaperManager.getInstance(this);
        mWallpaperConnection = new WallpaperConnection(mWallpaperIntent);
        getWindow().getDecorView().post(new Runnable() {
            public void run() {
                if (!mWallpaperConnection.connect()) {
                    mWallpaperConnection = null;
                }
            }
        });

        if (!TextUtils.isEmpty(deleteAction)) {
            mDeleteIntent = new Intent(deleteAction);
            mDeleteIntent.setPackage(info.getPackageName());
            mDeleteIntent.putExtra(EXTRA_LIVE_WALLPAPER_INFO, info);
        }

        initInfoPage(info);
        initSettingsPage(info);
        populateBottomPane();
    }

    private void initInfoPage(WallpaperInfo info) {
        final View pageInfo = getLayoutInflater().inflate(R.layout.page_info, null /* root */);
        final TextView attributionTitle = pageInfo.findViewById(
                R.id.preview_attribution_pane_title);
        final TextView attributionAuthor = pageInfo.findViewById(
                R.id.preview_attribution_pane_author);
        final TextView attributionDescription = pageInfo.findViewById(
                R.id.preview_attribution_pane_description);
        final Button attributionExploreButton = pageInfo.findViewById(
                R.id.preview_attribution_pane_explore_button);
        final View spacer = pageInfo.findViewById(R.id.spacer);
        final Button setWallpaperButton = pageInfo.findViewById(
                R.id.preview_attribution_pane_set_wallpaper_button);

        setWallpaperButton.setOnClickListener(this::setLiveWallpaper);
        mPages.add(Pair.create(getString(R.string.tab_info), pageInfo));

        if (SHOW_FAKE_DATA) {
            attributionTitle.setText("Diorama, Yosemite");
            attributionTitle.setVisibility(View.VISIBLE);
            attributionAuthor.setText("Live Earth Collection - Android Earth");
            attributionAuthor.setVisibility(View.VISIBLE);
            attributionDescription.setText("Lorem ipsum dolor sit amet, consectetur adipiscing"
                    + " elit. Sed imperdiet et mauris molestie laoreet. Proin volutpat elit nec"
                    + " magna tempus, ac aliquet lectus volutpat.");
            attributionDescription.setVisibility(View.VISIBLE);
            attributionExploreButton.setText("Explore");
            attributionExploreButton.setVisibility(View.VISIBLE);
            spacer.setVisibility(View.VISIBLE);
            return;
        }

        final PackageManager pm = getPackageManager();

        // Set attribution title
        final CharSequence title = info.loadLabel(pm);
        if (!TextUtils.isEmpty(title)) {
            attributionTitle.setText(title);
            attributionTitle.setVisibility(View.VISIBLE);
        }

        // Don't show other meta data if attribute showMetadataInPreview is set to False
        if (!info.getShowMetadataInPreview()) {
            return;
        }

        // Set attribution author
        try {
            final CharSequence author = info.loadAuthor(pm);
            if (!TextUtils.isEmpty(author)) {
                attributionAuthor.setText(author);
                attributionAuthor.setVisibility(View.VISIBLE);
            }
        } catch (NotFoundException e) {
            // It's expected if the live wallpaper doesn't provide this information
        }

        // Set attribution description
        try {
            final CharSequence description = info.loadDescription(pm);
            if (!TextUtils.isEmpty(description)) {
                attributionDescription.setText(description);
                attributionDescription.setVisibility(View.VISIBLE);
            }
        } catch (NotFoundException e) {
            // It's expected if the live wallpaper doesn't provide this information
        }

        // Set context information
        try {
            final Uri contextUri = info.loadContextUri(pm);
            if (contextUri != null) {
                final Intent intent = new Intent(Intent.ACTION_VIEW, contextUri);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                attributionExploreButton.setOnClickListener(v -> {
                    try {
                        startActivity(intent);
                    } catch (ActivityNotFoundException e) {
                        Log.e(LOG_TAG, "Couldn't find activity for context link.", e);
                    }
                });
                attributionExploreButton.setVisibility(View.VISIBLE);
                spacer.setVisibility(View.VISIBLE);

                // Update context description string if it's provided
                final CharSequence contextDescription = info.loadContextDescription(pm);
                if (!TextUtils.isEmpty(contextDescription)) {
                    attributionExploreButton.setText(contextDescription);
                }
            }
        } catch (NotFoundException e) {
            // It's expected if the wallpaper doesn't provide this information
        }
    }

    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    protected Uri getSettingsSliceUri(@NonNull WallpaperInfo info) {
        return info.getSettingsSliceUri();
    }

    private void initSettingsPage(WallpaperInfo info) {
        final Uri uriSettingsSlice = getSettingsSliceUri(info);
        if (uriSettingsSlice == null) {
            return;
        }

        final View pageSettings = getLayoutInflater().inflate(R.layout.page_settings,
                null /* root */);
        final Button setWallpaperButton = pageSettings.findViewById(
                R.id.preview_attribution_pane_set_wallpaper_button);

        mSliceViewSettings = pageSettings.findViewById(R.id.settings_slice);
        mSliceViewSettings.setMode(SliceView.MODE_LARGE);
        mSliceViewSettings.setScrollable(false);

        // Set LiveData for SliceView
        mLiveDataSettings = SliceLiveData.fromUri(this /* context */, uriSettingsSlice);
        mLiveDataSettings.observeForever(mSliceViewSettings);

        setWallpaperButton.setOnClickListener(this::setLiveWallpaper);

        mPages.add(Pair.create(getResources().getString(R.string.tab_customize), pageSettings));
    }

    private void populateBottomPane() {
        mViewBottomPane = findViewById(R.id.bottom_pane);
        mViewPager = findViewById(R.id.viewpager);
        mTabLayout = findViewById(R.id.tablayout);

        mBottomSheetBehavior = BottomSheetBehavior.from(mViewBottomPane);
        mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);

        // Create PagerAdapter
        final PagerAdapter pagerAdapter = new PagerAdapter() {
            @NonNull
            @Override
            public Object instantiateItem(ViewGroup container, int position) {
                final View page = mPages.get(position).second;
                container.addView(page);
                return page;
            }

            @Override
            public void destroyItem(@NonNull ViewGroup container, int position,
                    @NonNull Object object) {
                if (object instanceof View) {
                    container.removeView((View) object);
                }
            }

            @Override
            public int getCount() {
                return mPages.size();
            }

            @Override
            public CharSequence getPageTitle(int position) {
                try {
                    return mPages.get(position).first;
                } catch (IndexOutOfBoundsException e) {
                    return null;
                }
            }

            @Override
            public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
                return (view == object);
            }
        };

        // Add OnPageChangeListener to re-measure ViewPager's height
        mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                mViewPager.requestLayout();
            }
        });

        // Set PagerAdapter
        mViewPager.setAdapter(pagerAdapter);

        // Make TabLayout visible if there are more than one page
        if (mPages.size() > 1) {
            mTabLayout.setVisibility(View.VISIBLE);
            mTabLayout.setupWithViewPager(mViewPager);
        }

        // Initializes a rounded rectangle outline and clips the upper corners to be rounded.
        mViewBottomPane.setOutlineProvider(new ViewOutlineProvider() {
            private final int radius = getResources().getDimensionPixelSize(
                    R.dimen.preview_viewpager_round_radius);

            @Override
            public void getOutline(View view, Outline outline) {
                outline.setRoundRect(0 /* left */, 0 /* top */, view.getWidth(),
                        view.getHeight() + radius, radius);
            }
        });
        mViewBottomPane.setClipToOutline(true);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_preview, menu);
        setupPreviewMenu(menu);
        menu.findItem(R.id.configure).setVisible(mSettingsIntent != null);
        menu.findItem(R.id.delete_wallpaper).setVisible(mDeleteIntent != null);
        return super.onCreateOptionsMenu(menu);
    }

    private void setupPreviewMenu(Menu menu) {
        mPreview = (CheckBox) menu.findItem(R.id.preview).getActionView();
        mPreview.setOnClickListener(this::setPreviewBehavior);

        BottomSheetCallback callback = new BottomSheetCallback() {
            @Override
            public void onStateChanged(View bottomSheet, int newState) {
                switch (newState) {
                    case BottomSheetBehavior.STATE_COLLAPSED:
                        setPreviewChecked(true /* checked */);
                        break;
                    case BottomSheetBehavior.STATE_EXPANDED:
                        setPreviewChecked(false /* checked */);
                        break;
                }
            }

            @Override
            public void onSlide(View bottomSheet, float slideOffset) {
                mTabLayout.setAlpha(slideOffset);
                mViewPager.setAlpha(slideOffset);
            }
        };
        mBottomSheetBehavior.setBottomSheetCallback(callback);

        int state = mBottomSheetBehavior.getState();
        callback.onStateChanged(mViewBottomPane, state);
        switch (state) {
            case BottomSheetBehavior.STATE_COLLAPSED:
                callback.onSlide(mViewBottomPane, 0f);
                break;
            case BottomSheetBehavior.STATE_EXPANDED:
                callback.onSlide(mViewBottomPane, 1f);
                break;
        }
    }

    private void setPreviewChecked(boolean checked) {
        if (mPreview != null) {
            mPreview.setChecked(checked);
            int resId = checked ? R.string.expand_attribution_panel
                    : R.string.collapse_attribution_panel;
            mPreview.setContentDescription(getResources().getString(resId));
        }
    }

    private void setPreviewBehavior(final View v) {
        CheckBox checkbox = (CheckBox) v;
        if (checkbox.isChecked()) {
            mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
        } else {
            mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
        }
    }

    public void setLiveWallpaper(final View v) {
        if (mWallpaperManager.getWallpaperInfo() != null
                && mWallpaperManager.getWallpaperId(WallpaperManager.FLAG_LOCK) < 0) {
            // The lock screen does not have a distinct wallpaper and the current wallpaper is a
            // live wallpaper, so since we cannot preserve any static imagery on the lock screen,
            // set the live wallpaper directly without giving the user a destination option.
            try {
                setLiveWallpaper(v.getRootView().getWindowToken());
                setResult(RESULT_OK);
            } catch (RuntimeException e) {
                Log.w(LOG_TAG, "Failure setting wallpaper", e);
            }
            finish();
        } else {
            // Otherwise, prompt to either set on home or both home and lock screen.
            final Context themedContext = new ContextThemeWrapper(this /* base */,
                    android.R.style.Theme_DeviceDefault_Settings);
            new AlertDialog.Builder(themedContext)
                    .setTitle(R.string.set_live_wallpaper)
                    .setAdapter(new WallpaperTargetAdapter(themedContext),
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    try {
                                        setLiveWallpaper(v.getRootView().getWindowToken());
                                        if (which == 1) {
                                            // "Home screen and lock screen"; clear the lock
                                            // screen so it
                                            // shows through to the live wallpaper on home.
                                            mWallpaperManager.clear(WallpaperManager.FLAG_LOCK);
                                        }
                                        setResult(RESULT_OK);
                                    } catch (RuntimeException | IOException e) {
                                        Log.w(LOG_TAG, "Failure setting wallpaper", e);
                                    }
                                    finish();
                                }
                            })
                    .show();
        }
    }

    private void setLiveWallpaper(IBinder windowToken) {
        mWallpaperManager.setWallpaperComponent(mWallpaperIntent.getComponent());
        mWallpaperManager.setWallpaperOffsetSteps(0.5f /* xStep */, 0.0f /* yStep */);
        mWallpaperManager.setWallpaperOffsets(windowToken, 0.5f /* xOffset */, 0.0f /* yOffset */);
    }

    @VisibleForTesting
    void deleteLiveWallpaper() {
        if (mDeleteIntent != null) {
            startService(mDeleteIntent);
            finish();
        }
    }

    private void showDeleteConfirmDialog() {
        final AlertDialog alertDialog = new AlertDialog.Builder(this /* context */,
                R.style.AlertDialogStyle)
                .setMessage(R.string.delete_wallpaper_confirmation)
                .setPositiveButton(R.string.delete_live_wallpaper,
                        (dialog, which) -> deleteLiveWallpaper())
                .setNegativeButton(android.R.string.cancel, null /* listener */)
                .create();
        alertDialog.show();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.configure) {
            startActivity(mSettingsIntent);
            return true;
        } else if (id == R.id.delete_wallpaper) {
            showDeleteConfirmDialog();
            return true;
        } else if (id == android.R.id.home) {
            onBackPressed();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mWallpaperConnection != null) {
            mWallpaperConnection.setVisibility(true);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mWallpaperConnection != null) {
            mWallpaperConnection.setVisibility(false);
        }
    }

    @Override
    protected void onDestroy () {
        if (mLiveDataSettings != null && mLiveDataSettings.hasObservers()) {
            mLiveDataSettings.removeObserver(mSliceViewSettings);
            mLiveDataSettings = null;
        }
        if (mWallpaperConnection != null) {
            mWallpaperConnection.disconnect();
        }
        mWallpaperConnection = null;
        super.onDestroy();
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            onUserInteraction();
        }
        boolean handled = getWindow().superDispatchTouchEvent(ev);
        if (!handled) {
            handled = onTouchEvent(ev);
        }

        if (!handled && mWallpaperConnection != null && mWallpaperConnection.mEngine != null) {
            MotionEvent dup = MotionEvent.obtainNoHistory(ev);
            try {
                mWallpaperConnection.mEngine.dispatchPointer(dup);
            } catch (RemoteException e) {
            }

            int action = ev.getActionMasked();
            try {
                if (action == MotionEvent.ACTION_UP) {
                    mWallpaperConnection.mEngine.dispatchWallpaperCommand(
                            WallpaperManager.COMMAND_TAP,
                            (int) ev.getX(), (int) ev.getY(), 0, null);
                } else if (action == MotionEvent.ACTION_POINTER_UP) {
                    int pointerIndex = ev.getActionIndex();
                    mWallpaperConnection.mEngine.dispatchWallpaperCommand(
                            WallpaperManager.COMMAND_SECONDARY_TAP,
                            (int) ev.getX(pointerIndex), (int) ev.getY(pointerIndex), 0, null);
                }
            } catch (RemoteException e) {
            }
        }
        return handled;
    }

    class WallpaperConnection extends IWallpaperConnection.Stub implements ServiceConnection {
        final Intent mIntent;
        IWallpaperService mService;
        IWallpaperEngine mEngine;
        boolean mConnected;
        boolean mIsVisible;
        boolean mIsEngineVisible;

        WallpaperConnection(Intent intent) {
            mIntent = intent;
        }

        public boolean connect() {
            synchronized (this) {
                if (!bindService(mIntent, this, Context.BIND_AUTO_CREATE)) {
                    return false;
                }

                mConnected = true;
                return true;
            }
        }

        public void disconnect() {
            synchronized (this) {
                mConnected = false;
                if (mEngine != null) {
                    try {
                        mEngine.destroy();
                    } catch (RemoteException e) {
                        // Ignore
                    }
                    mEngine = null;
                }
                try {
                    unbindService(this);
                } catch (IllegalArgumentException e) {
                    Log.w(LOG_TAG, "Can't unbind wallpaper service. "
                            + "It might have crashed, just ignoring.", e);
                }
                mService = null;
            }
        }

        @Override
        public void onLocalWallpaperColorsChanged(RectF area,
                WallpaperColors colors, int displayId) {

        }

        public void onServiceConnected(ComponentName name, IBinder service) {
            if (mWallpaperConnection == this) {
                mService = IWallpaperService.Stub.asInterface(service);
                try {
                    final int displayId = getWindow().getDecorView().getDisplay().getDisplayId();
                    final View root = getWindow().getDecorView();
                    mService.attach(this, root.getWindowToken(),
                            LayoutParams.TYPE_APPLICATION_MEDIA,
                            true, root.getWidth(), root.getHeight(),
                            new Rect(0, 0, 0, 0), displayId);
                } catch (RemoteException e) {
                    Log.w(LOG_TAG, "Failed attaching wallpaper; clearing", e);
                }
            }
        }

        public void onServiceDisconnected(ComponentName name) {
            mService = null;
            mEngine = null;
            if (mWallpaperConnection == this) {
                Log.w(LOG_TAG, "Wallpaper service gone: " + name);
            }
        }

        public void attachEngine(IWallpaperEngine engine, int displayId) {
            synchronized (this) {
                if (mConnected) {
                    mEngine = engine;
                    if (mIsVisible) {
                        setEngineVisibility(true);
                    }
                } else {
                    try {
                        engine.destroy();
                    } catch (RemoteException e) {
                        // Ignore
                    }
                }
            }
        }

        public ParcelFileDescriptor setWallpaper(String name) {
            return null;
        }

        @Override
        public void onWallpaperColorsChanged(WallpaperColors colors, int displayId)
                throws RemoteException {

        }

        @Override
        public void engineShown(IWallpaperEngine engine) throws RemoteException {
            mLoading.post(() -> {
                mLoading.animate()
                        .alpha(0f)
                        .setDuration(220)
                        .setStartDelay(300)
                        .setInterpolator(AnimationUtils.loadInterpolator(LiveWallpaperPreview.this,
                                android.R.interpolator.fast_out_linear_in))
                        .withEndAction(() -> mLoading.setVisibility(View.INVISIBLE));
            });
        }

        public void setVisibility(boolean visible) {
            mIsVisible = visible;
            setEngineVisibility(visible);
        }

        private void setEngineVisibility(boolean visible) {
            if (mEngine != null && visible != mIsEngineVisible) {
                try {
                    mEngine.setVisibility(visible);
                    mIsEngineVisible = visible;
                } catch (RemoteException e) {
                    Log.w(LOG_TAG, "Failure setting wallpaper visibility ", e);
                }
            }
        }
    }

    private static class WallpaperTargetAdapter extends ArrayAdapter<CharSequence> {

        public WallpaperTargetAdapter(Context context) {
            super(context, R.layout.wallpaper_target_dialog_item,
                    context.getResources().getTextArray(R.array.which_wallpaper_options));
        }

        @Override
        public boolean hasStableIds() {
            return true;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView tv = (TextView) super.getView(position, convertView, parent);
            tv.setCompoundDrawablesRelativeWithIntrinsicBounds(
                    position == 0 ? R.drawable.ic_home : R.drawable.ic_device, 0, 0, 0);
            return tv;
        }
    }
}
