/*
 * Copyright (C) 2016 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.example.android.pm.shortcutdemo;

import android.content.Context;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ShortcutInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

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

public abstract class ShortcutAdapter extends BaseAdapter implements OnClickListener {
    public static final String TAG = "ShortcutDemo";

    private final Context mContext;
    private final LayoutInflater mInflater;
    private LauncherApps mLauncherApps;
    private final AppLabelCache mAppLabelCache;
    private List<ShortcutInfo> mShortcuts;

    public ShortcutAdapter(Context context) {
        mContext = context;
        mAppLabelCache = new AppLabelCache(mContext);
        mInflater = mContext.getSystemService(LayoutInflater.class);
        mLauncherApps = mContext.getSystemService(LauncherApps.class);
    }

    protected abstract int getLayoutId();
    protected abstract int getText1Id();
    protected abstract int getText2Id();
    protected abstract int getImageId();
    protected abstract int getLaunchId();
    protected abstract int getToggleId();

    protected boolean showLaunch() {
        return false;
    }

    protected boolean showToggle() {
        return false;
    }

    protected String getToggleText(ShortcutInfo si) {
        return "Toggle";
    }

    protected void onLaunchClicked(ShortcutInfo si) {
    }

    protected void onToggleClicked(ShortcutInfo si) {
    }

    public void setShortcuts(List<ShortcutInfo> shortcuts) {
        mShortcuts = shortcuts;
        notifyDataSetChanged();
    }

    public List<ShortcutInfo> getShortcuts() {
        return mShortcuts;
    }

    @Override
    public int getCount() {
        return mShortcuts == null ? 0 : mShortcuts.size();
    }

    @Override
    public Object getItem(int position) {
        return mShortcuts.get(position);
    }

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

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

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

    @Override
    public boolean isEnabled(int position) {
        return true;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final View view;
        if (convertView != null) {
            view = convertView;
        } else {
            view = mInflater.inflate(getLayoutId(), null);
        }

        bindView(view, position, mShortcuts.get(position));

        return view;
    }

    public void bindView(View view, int position, ShortcutInfo si) {
        if (showLaunch()) {
            final View v = view.findViewById(getLaunchId());
            v.setOnClickListener(this);
        }
        if (showToggle()) {
            final Button v = (Button) view.findViewById(getToggleId());
            v.setOnClickListener(this);
            v.setText(getToggleText(si));
        }

        final TextView line1 = (TextView) view.findViewById(getText1Id());
        final TextView line2 = (TextView) view.findViewById(getText2Id());

        view.setTag(si);

        line1.setText(si.getTitle());
        line2.setText(
                si.getId() + (si.isDynamic() ? " [dynamic]" : "")
                        + (si.isPinned() ? " [pinned]" : "") + "\n"
                + mAppLabelCache.getAppLabel(si.getPackageName()));

        // view.setBackgroundColor(si.isPinned() ? Color.rgb(255, 255, 192) : Color.WHITE);

        // TODO Do it on worker thread
        final ImageView image = (ImageView) view.findViewById(getImageId());
        Bitmap icon = null;
        if (si.hasIconResource()) {
            try {
                final Resources res = mContext.getPackageManager().getResourcesForApplication(
                        si.getPackageName());
                icon = BitmapFactory.decodeResource(res,
                        mLauncherApps.getShortcutIconResId(si, Process.myUserHandle()));

            } catch (NameNotFoundException e) {
                Log.w(TAG, "Unable to load icon from " + si.getPackageName(), e);
            }
        } else if (si.hasIconFile()) {
            icon = pfdToBitmap(mLauncherApps.getShortcutIconFd(si, Process.myUserHandle()));
        }
        image.setImageBitmap(icon);
    }

    private Bitmap pfdToBitmap(ParcelFileDescriptor pfd) {
        if (pfd == null) {
            return null;
        }
        try {
            final Bitmap bmp = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
            if (bmp == null) {
                Log.w(TAG, "Failed to decode icon");
            }
            return bmp;
        } finally {
            try {
                pfd.close();
            } catch (IOException e) {
            }
        }
    }

    @Override
    public void onClick(View v) {
        final ShortcutInfo si = (ShortcutInfo)(((View) v.getParent()).getTag());
        if (v.getId() == getLaunchId()) {
            onLaunchClicked(si);
        } else if (v.getId() == getToggleId()) {
            onToggleClicked(si);
        }
    }
}
