/*
 * Copyright (C) 2012 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.settings;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.LauncherActivity.IconResizer;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.IWindowManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.android.internal.widget.LockPatternUtils;

import java.lang.ref.WeakReference;
import java.util.List;

/**
 * Displays a list of {@link AppWidgetProviderInfo} widgets, along with any
 * injected special widgets specified through
 * {@link AppWidgetManager#EXTRA_CUSTOM_INFO} and
 * {@link AppWidgetManager#EXTRA_CUSTOM_EXTRAS}.
 * <p>
 * When an installed {@link AppWidgetProviderInfo} is selected, this activity
 * will bind it to the given {@link AppWidgetManager#EXTRA_APPWIDGET_ID},
 * otherwise it will return the requested extras.
 */
public class KeyguardAppWidgetPickActivity extends Activity
    implements GridView.OnItemClickListener,
        AppWidgetLoader.ItemConstructor<KeyguardAppWidgetPickActivity.Item> {
    private static final String TAG = "KeyguardAppWidgetPickActivity";
    private static final int REQUEST_PICK_APPWIDGET = 126;
    private static final int REQUEST_CREATE_APPWIDGET = 127;

    private AppWidgetLoader<Item> mAppWidgetLoader;
    private List<Item> mItems;
    private GridView mGridView;
    private AppWidgetAdapter mAppWidgetAdapter;
    private AppWidgetManager mAppWidgetManager;
    private int mAppWidgetId;
    // Might make it possible to make this be false in future
    private boolean mAddingToKeyguard = true;
    private Intent mResultData;
    private LockPatternUtils mLockPatternUtils;
    private Bundle mExtraConfigureOptions;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.keyguard_appwidget_picker_layout);
        super.onCreate(savedInstanceState);

        // Set default return data
        setResultData(RESULT_CANCELED, null);

        // Read the appWidgetId passed our direction, otherwise bail if not found
        final Intent intent = getIntent();
        if (intent.hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
            mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                    AppWidgetManager.INVALID_APPWIDGET_ID);
        } else {
            finish();
        }
        mExtraConfigureOptions = intent.getBundleExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS);

        mGridView = (GridView) findViewById(R.id.widget_list);
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int maxGridWidth = getResources().getDimensionPixelSize(
                R.dimen.keyguard_appwidget_picker_max_width);

        if (maxGridWidth < dm.widthPixels) {
            mGridView.getLayoutParams().width = maxGridWidth;
        }
        mAppWidgetManager = AppWidgetManager.getInstance(this);
        mAppWidgetLoader = new AppWidgetLoader<Item>(this, mAppWidgetManager, this);
        mItems = mAppWidgetLoader.getItems(getIntent());
        mAppWidgetAdapter = new AppWidgetAdapter(this, mItems);
        mGridView.setAdapter(mAppWidgetAdapter);
        mGridView.setOnItemClickListener(this);

        mLockPatternUtils = new LockPatternUtils(this); // TEMP-- we want to delete this
    }

    /**
     * Convenience method for setting the result code and intent. This method
     * correctly injects the {@link AppWidgetManager#EXTRA_APPWIDGET_ID} that
     * most hosts expect returned.
     */
    void setResultData(int code, Intent intent) {
        Intent result = intent != null ? intent : new Intent();
        result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
        mResultData = result;
        setResult(code, result);
    }

    /**
     * Item that appears in the AppWidget picker grid.
     */
    public static class Item implements AppWidgetLoader.LabelledItem {
        protected static IconResizer sResizer;


        CharSequence label;
        int appWidgetPreviewId;
        int iconId;
        String packageName;
        String className;
        Bundle extras;
        private WidgetPreviewLoader mWidgetPreviewLoader;
        private Context mContext;

        /**
         * Create a list item from given label and icon.
         */
        Item(Context context, CharSequence label) {
            this.label = label;
            mContext = context;
        }

        void loadWidgetPreview(ImageView v) {
            mWidgetPreviewLoader = new WidgetPreviewLoader(mContext, v);
            mWidgetPreviewLoader.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
        }

        void cancelLoadingWidgetPreview() {
            if (mWidgetPreviewLoader != null) {
                mWidgetPreviewLoader.cancel(false);
                mWidgetPreviewLoader = null;
            }
        }

        /**
         * Build the {@link Intent} described by this item. If this item
         * can't create a valid {@link android.content.ComponentName}, it will return
         * {@link Intent#ACTION_CREATE_SHORTCUT} filled with the item label.
         */
        Intent getIntent() {
            Intent intent = new Intent();
            if (packageName != null && className != null) {
                // Valid package and class, so fill details as normal intent
                intent.setClassName(packageName, className);
                if (extras != null) {
                    intent.putExtras(extras);
                }
            } else {
                // No valid package or class, so treat as shortcut with label
                intent.setAction(Intent.ACTION_CREATE_SHORTCUT);
                intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, label);
            }
            return intent;
        }

        public CharSequence getLabel() {
            return label;
        }

        class WidgetPreviewLoader extends AsyncTask<Void, Bitmap, Void> {
            private Resources mResources;
            private PackageManager mPackageManager;
            private int mIconDpi;
            private ImageView mView;
            public WidgetPreviewLoader(Context context, ImageView v) {
                super();
                mResources = context.getResources();
                mPackageManager = context.getPackageManager();
                ActivityManager activityManager =
                        (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
                mIconDpi = activityManager.getLauncherLargeIconDensity();
                mView = v;
            }
            public Void doInBackground(Void... params) {
                if (!isCancelled()) {
                    int appWidgetPreviewWidth =
                            mResources.getDimensionPixelSize(R.dimen.appwidget_preview_width);
                    int appWidgetPreviewHeight =
                            mResources.getDimensionPixelSize(R.dimen.appwidget_preview_height);
                    Bitmap b = getWidgetPreview(new ComponentName(packageName, className),
                            appWidgetPreviewId, iconId,
                            appWidgetPreviewWidth, appWidgetPreviewHeight);
                    publishProgress(b);
                }
                return null;
            }
            public void onProgressUpdate(Bitmap... values) {
                if (!isCancelled()) {
                    Bitmap b = values[0];
                    mView.setImageBitmap(b);
                }
            }
            abstract class WeakReferenceThreadLocal<T> {
                private ThreadLocal<WeakReference<T>> mThreadLocal;
                public WeakReferenceThreadLocal() {
                    mThreadLocal = new ThreadLocal<WeakReference<T>>();
                }

                abstract T initialValue();

                public void set(T t) {
                    mThreadLocal.set(new WeakReference<T>(t));
                }

                public T get() {
                    WeakReference<T> reference = mThreadLocal.get();
                    T obj;
                    if (reference == null) {
                        obj = initialValue();
                        mThreadLocal.set(new WeakReference<T>(obj));
                        return obj;
                    } else {
                        obj = reference.get();
                        if (obj == null) {
                            obj = initialValue();
                            mThreadLocal.set(new WeakReference<T>(obj));
                        }
                        return obj;
                    }
                }
            }

            class CanvasCache extends WeakReferenceThreadLocal<Canvas> {
                @Override
                protected Canvas initialValue() {
                    return new Canvas();
                }
            }

            class PaintCache extends WeakReferenceThreadLocal<Paint> {
                @Override
                protected Paint initialValue() {
                    return null;
                }
            }

            class BitmapCache extends WeakReferenceThreadLocal<Bitmap> {
                @Override
                protected Bitmap initialValue() {
                    return null;
                }
            }

            class RectCache extends WeakReferenceThreadLocal<Rect> {
                @Override
                protected Rect initialValue() {
                    return new Rect();
                }
            }

            // Used for drawing widget previews
            CanvasCache sCachedAppWidgetPreviewCanvas = new CanvasCache();
            RectCache sCachedAppWidgetPreviewSrcRect = new RectCache();
            RectCache sCachedAppWidgetPreviewDestRect = new RectCache();
            PaintCache sCachedAppWidgetPreviewPaint = new PaintCache();

            private Bitmap getWidgetPreview(ComponentName provider, int previewImage,
                    int iconId, int maxWidth, int maxHeight) {
                // Load the preview image if possible
                String packageName = provider.getPackageName();
                if (maxWidth < 0) maxWidth = Integer.MAX_VALUE;
                if (maxHeight < 0) maxHeight = Integer.MAX_VALUE;


                int appIconSize = mResources.getDimensionPixelSize(R.dimen.app_icon_size);

                Drawable drawable = null;
                if (previewImage != 0) {
                    drawable = mPackageManager.getDrawable(packageName, previewImage, null);
                    if (drawable == null) {
                        Log.w(TAG, "Can't load widget preview drawable 0x" +
                                Integer.toHexString(previewImage) + " for provider: " + provider);
                    }
                }

                int bitmapWidth;
                int bitmapHeight;
                Bitmap defaultPreview = null;
                boolean widgetPreviewExists = (drawable != null);
                if (widgetPreviewExists) {
                    bitmapWidth = drawable.getIntrinsicWidth();
                    bitmapHeight = drawable.getIntrinsicHeight();
                } else {
                    // Generate a preview image if we couldn't load one
                    bitmapWidth = appIconSize;
                    bitmapHeight = appIconSize;
                    defaultPreview = Bitmap.createBitmap(bitmapWidth, bitmapHeight,
                            Config.ARGB_8888);

                    try {
                        Drawable icon = null;
                        if (iconId > 0)
                            icon = getFullResIcon(packageName, iconId);
                        if (icon != null) {
                            renderDrawableToBitmap(icon, defaultPreview, 0,
                                    0, appIconSize, appIconSize);
                        }
                    } catch (Resources.NotFoundException e) {
                    }
                }

                // Scale to fit width only - let the widget preview be clipped in the
                // vertical dimension
                float scale = 1f;
                if (bitmapWidth > maxWidth) {
                    scale = maxWidth / (float) bitmapWidth;
                }
                int finalPreviewWidth = (int) (scale * bitmapWidth);
                int finalPreviewHeight = (int) (scale * bitmapHeight);

                bitmapWidth = finalPreviewWidth;
                bitmapHeight = Math.min(finalPreviewHeight, maxHeight);

                Bitmap preview = Bitmap.createBitmap(bitmapWidth, bitmapHeight,
                        Config.ARGB_8888);

                // Draw the scaled preview into the final bitmap
                if (widgetPreviewExists) {
                    renderDrawableToBitmap(drawable, preview, 0, 0, finalPreviewWidth,
                            finalPreviewHeight);
                } else {
                    final Canvas c = sCachedAppWidgetPreviewCanvas.get();
                    final Rect src = sCachedAppWidgetPreviewSrcRect.get();
                    final Rect dest = sCachedAppWidgetPreviewDestRect.get();
                    c.setBitmap(preview);
                    src.set(0, 0, defaultPreview.getWidth(), defaultPreview.getHeight());
                    dest.set(0, 0, finalPreviewWidth, finalPreviewHeight);

                    Paint p = sCachedAppWidgetPreviewPaint.get();
                    if (p == null) {
                        p = new Paint();
                        p.setFilterBitmap(true);
                        sCachedAppWidgetPreviewPaint.set(p);
                    }
                    c.drawBitmap(defaultPreview, src, dest, p);
                    c.setBitmap(null);
                }
                return preview;
            }
            public Drawable getFullResDefaultActivityIcon() {
                return getFullResIcon(Resources.getSystem(),
                        android.R.mipmap.sym_def_app_icon);
            }

            public Drawable getFullResIcon(Resources resources, int iconId) {
                Drawable d;
                try {
                    d = resources.getDrawableForDensity(iconId, mIconDpi);
                } catch (Resources.NotFoundException e) {
                    d = null;
                }

                return (d != null) ? d : getFullResDefaultActivityIcon();
            }

            public Drawable getFullResIcon(String packageName, int iconId) {
                Resources resources;
                try {
                    resources = mPackageManager.getResourcesForApplication(packageName);
                } catch (PackageManager.NameNotFoundException e) {
                    resources = null;
                }
                if (resources != null) {
                    if (iconId != 0) {
                        return getFullResIcon(resources, iconId);
                    }
                }
                return getFullResDefaultActivityIcon();
            }

            private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h) {
                renderDrawableToBitmap(d, bitmap, x, y, w, h, 1f);
            }

            private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h,
                    float scale) {
                if (bitmap != null) {
                    Canvas c = new Canvas(bitmap);
                    c.scale(scale, scale);
                    Rect oldBounds = d.copyBounds();
                    d.setBounds(x, y, x + w, y + h);
                    d.draw(c);
                    d.setBounds(oldBounds); // Restore the bounds
                    c.setBitmap(null);
                }
            }
        }
    }

    @Override
    public Item createItem(Context context, AppWidgetProviderInfo info, Bundle extras) {
        CharSequence label = info.label;

        Item item = new Item(context, label);
        item.appWidgetPreviewId = info.previewImage;
        item.iconId = info.icon;
        item.packageName = info.provider.getPackageName();
        item.className = info.provider.getClassName();
        item.extras = extras;
        return item;
    }

    protected static class AppWidgetAdapter extends BaseAdapter {
        private final LayoutInflater mInflater;
        private final List<Item> mItems;

        /**
         * Create an adapter for the given items.
         */
        public AppWidgetAdapter(Context context, List<Item> items) {
            mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            mItems = items;
        }

        /**
         * {@inheritDoc}
         */
        public int getCount() {
            return mItems.size();
        }

        /**
         * {@inheritDoc}
         */
        public Object getItem(int position) {
            return mItems.get(position);
        }

        /**
         * {@inheritDoc}
         */
        public long getItemId(int position) {
            return position;
        }

        /**
         * {@inheritDoc}
         */
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.keyguard_appwidget_item, parent, false);
            }

            Item item = (Item) getItem(position);
            TextView textView = (TextView) convertView.findViewById(R.id.label);
            textView.setText(item.label);
            ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
            iconView.setImageDrawable(null);
            item.loadWidgetPreview(iconView);
            return convertView;
        }

        public void cancelAllWidgetPreviewLoaders() {
            for (int i = 0; i < mItems.size(); i++) {
                mItems.get(i).cancelLoadingWidgetPreview();
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Item item = mItems.get(position);
        Intent intent = item.getIntent();

        int result;
        if (item.extras != null) {
            // If these extras are present it's because this entry is custom.
            // Don't try to bind it, just pass it back to the app.
            result = RESULT_OK;
            setResultData(result, intent);
        } else {
            try {
                if (mAddingToKeyguard && mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
                    // Found in KeyguardHostView.java
                    final int KEYGUARD_HOST_ID = 0x4B455947;
                    mAppWidgetId = AppWidgetHost.allocateAppWidgetIdForSystem(KEYGUARD_HOST_ID);
                }
                mAppWidgetManager.bindAppWidgetId(
                        mAppWidgetId, intent.getComponent(), mExtraConfigureOptions);
                result = RESULT_OK;
            } catch (IllegalArgumentException e) {
                // This is thrown if they're already bound, or otherwise somehow
                // bogus.  Set the result to canceled, and exit.  The app *should*
                // clean up at this point.  We could pass the error along, but
                // it's not clear that that's useful -- the widget will simply not
                // appear.
                result = RESULT_CANCELED;
            }
            setResultData(result, null);
        }
        if (mAddingToKeyguard) {
            onActivityResult(REQUEST_PICK_APPWIDGET, result, mResultData);
        } else {
            finish();
        }
    }

    protected void onDestroy() {
        if (mAppWidgetAdapter != null) {
            mAppWidgetAdapter.cancelAllWidgetPreviewLoaders();
        }
        super.onDestroy();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_PICK_APPWIDGET || requestCode == REQUEST_CREATE_APPWIDGET) {
            int appWidgetId;
            if  (data == null) {
                appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID ;
            } else {
                appWidgetId = data.getIntExtra(
                        AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
            }
            if (requestCode == REQUEST_PICK_APPWIDGET && resultCode == Activity.RESULT_OK) {
                AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);

                AppWidgetProviderInfo appWidget = null;
                appWidget = appWidgetManager.getAppWidgetInfo(appWidgetId);

                if (appWidget.configure != null) {
                    // Launch over to configure widget, if needed
                    Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
                    intent.setComponent(appWidget.configure);
                    intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);

                    startActivityForResultSafely(intent, REQUEST_CREATE_APPWIDGET);
                } else {
                    // Otherwise just add it
                    onActivityResult(REQUEST_CREATE_APPWIDGET, Activity.RESULT_OK, data);
                }
            } else if (requestCode == REQUEST_CREATE_APPWIDGET && resultCode == Activity.RESULT_OK) {
                mLockPatternUtils.addAppWidget(appWidgetId, 0);
                finishDelayedAndShowLockScreen(appWidgetId);
            } else {
                if (mAddingToKeyguard &&
                        mAppWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
                    AppWidgetHost.deleteAppWidgetIdForSystem(mAppWidgetId);
                }
                finishDelayedAndShowLockScreen(AppWidgetManager.INVALID_APPWIDGET_ID);
            }
        }
    }

    private void finishDelayedAndShowLockScreen(int appWidgetId) {
        IBinder b = ServiceManager.getService(Context.WINDOW_SERVICE);
        IWindowManager iWm = IWindowManager.Stub.asInterface(b);
        Bundle opts = null;
        if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
            opts = new Bundle();
            opts.putInt(LockPatternUtils.KEYGUARD_SHOW_APPWIDGET, appWidgetId);
        }
        try {
            iWm.lockNow(opts);
        } catch (RemoteException e) {
        }

        // Change background to all black
        ViewGroup root = (ViewGroup) findViewById(R.id.layout_root);
        root.setBackgroundColor(0xFF000000);
        // Hide all children
        final int childCount = root.getChildCount();
        for (int i = 0; i < childCount; i++) {
            root.getChildAt(i).setVisibility(View.INVISIBLE);
        }
        mGridView.postDelayed(new Runnable() {
            public void run() {
                finish();
            }
        }, 500);
    }

    void startActivityForResultSafely(Intent intent, int requestCode) {
        try {
            startActivityForResult(intent, requestCode);
        } catch (ActivityNotFoundException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
        } catch (SecurityException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Settings does not have the permission to launch " + intent, e);
        }
    }
}
