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

import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ContentUris;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.BrowserContract;
import android.provider.BrowserContract.Accounts;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.Toast;

import com.android.browser.provider.BrowserProvider2;
import com.android.browser.view.BookmarkExpandableView;
import com.android.browser.view.BookmarkExpandableView.BookmarkContextMenuInfo;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;

interface BookmarksPageCallbacks {
    // Return true if handled
    boolean onBookmarkSelected(Cursor c, boolean isFolder);
    // Return true if handled
    boolean onOpenInNewWindow(String... urls);
}

/**
 *  View showing the user's bookmarks in the browser.
 */
public class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener,
        LoaderManager.LoaderCallbacks<Cursor>, BreadCrumbView.Controller,
        OnChildClickListener {

    public static class ExtraDragState {
        public int childPosition;
        public int groupPosition;
    }

    static final String LOGTAG = "browser";

    static final int LOADER_ACCOUNTS = 1;
    static final int LOADER_BOOKMARKS = 100;

    static final String EXTRA_DISABLE_WINDOW = "disable_new_window";
    static final String PREF_GROUP_STATE = "bbp_group_state";

    static final String ACCOUNT_TYPE = "account_type";
    static final String ACCOUNT_NAME = "account_name";

    BookmarksPageCallbacks mCallbacks;
    View mRoot;
    BookmarkExpandableView mGrid;
    boolean mDisableNewWindow;
    boolean mEnableContextMenu = true;
    View mEmptyView;
    View mHeader;
    HashMap<Integer, BrowserBookmarksAdapter> mBookmarkAdapters = new HashMap<Integer, BrowserBookmarksAdapter>();
    JSONObject mState;

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        if (id == LOADER_ACCOUNTS) {
            return new AccountsLoader(getActivity());
        } else if (id >= LOADER_BOOKMARKS) {
            String accountType = args.getString(ACCOUNT_TYPE);
            String accountName = args.getString(ACCOUNT_NAME);
            BookmarksLoader bl = new BookmarksLoader(getActivity(),
                    accountType, accountName);
            return bl;
        } else {
            throw new UnsupportedOperationException("Unknown loader id " + id);
        }
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        if (loader.getId() == LOADER_ACCOUNTS) {
            LoaderManager lm = getLoaderManager();
            int id = LOADER_BOOKMARKS;
            while (cursor.moveToNext()) {
                String accountName = cursor.getString(0);
                String accountType = cursor.getString(1);
                Bundle args = new Bundle();
                args.putString(ACCOUNT_NAME, accountName);
                args.putString(ACCOUNT_TYPE, accountType);
                BrowserBookmarksAdapter adapter = new BrowserBookmarksAdapter(
                        getActivity());
                mBookmarkAdapters.put(id, adapter);
                boolean expand = true;
                try {
                    expand = mState.getBoolean(accountName != null ? accountName
                            : BookmarkExpandableView.LOCAL_ACCOUNT_NAME);
                } catch (JSONException e) {} // no state for accountName
                mGrid.addAccount(accountName, adapter, expand);
                lm.restartLoader(id, args, this);
                id++;
            }
            // TODO: Figure out what a reload of these means
            // Currently, a reload is triggered whenever bookmarks change
            // This is less than ideal
            // It also causes UI flickering as a new adapter is created
            // instead of re-using an existing one when the account_name is the
            // same.
            // For now, this is a one-shot load
            getLoaderManager().destroyLoader(LOADER_ACCOUNTS);
        } else if (loader.getId() >= LOADER_BOOKMARKS) {
            BrowserBookmarksAdapter adapter = mBookmarkAdapters.get(loader.getId());
            adapter.changeCursor(cursor);
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        if (loader.getId() >= LOADER_BOOKMARKS) {
            BrowserBookmarksAdapter adapter = mBookmarkAdapters.get(loader.getId());
            adapter.changeCursor(null);
        }
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        if (!(item.getMenuInfo() instanceof BookmarkContextMenuInfo)) {
            return false;
        }
        BookmarkContextMenuInfo i = (BookmarkContextMenuInfo) item.getMenuInfo();
        // If we have no menu info, we can't tell which item was selected.
        if (i == null) {
            return false;
        }

        if (handleContextItem(item.getItemId(), i.groupPosition, i.childPosition)) {
            return true;
        }
        return super.onContextItemSelected(item);
    }

    public boolean handleContextItem(int itemId, int groupPosition,
            int childPosition) {
        final Activity activity = getActivity();
        BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition);

        switch (itemId) {
        case R.id.open_context_menu_id:
            loadUrl(adapter, childPosition);
            break;
        case R.id.edit_context_menu_id:
            editBookmark(adapter, childPosition);
            break;
        case R.id.shortcut_context_menu_id:
            Cursor c = adapter.getItem(childPosition);
            activity.sendBroadcast(createShortcutIntent(getActivity(), c));
            break;
        case R.id.delete_context_menu_id:
            displayRemoveBookmarkDialog(adapter, childPosition);
            break;
        case R.id.new_window_context_menu_id:
            openInNewWindow(adapter, childPosition);
            break;
        case R.id.share_link_context_menu_id: {
            Cursor cursor = adapter.getItem(childPosition);
            Controller.sharePage(activity,
                    cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE),
                    cursor.getString(BookmarksLoader.COLUMN_INDEX_URL),
                    getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON),
                    getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_THUMBNAIL));
            break;
        }
        case R.id.copy_url_context_menu_id:
            copy(getUrl(adapter, childPosition));
            break;
        case R.id.homepage_context_menu_id: {
            BrowserSettings.getInstance().setHomePage(getUrl(adapter, childPosition));
            Toast.makeText(activity, R.string.homepage_set, Toast.LENGTH_LONG).show();
            break;
        }
        // Only for the Most visited page
        case R.id.save_to_bookmarks_menu_id: {
            Cursor cursor = adapter.getItem(childPosition);
            String name = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
            String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
            // If the site is bookmarked, the item becomes remove from
            // bookmarks.
            Bookmarks.removeFromBookmarks(activity, activity.getContentResolver(), url, name);
            break;
        }
        default:
            return false;
        }
        return true;
    }

    static Bitmap getBitmap(Cursor cursor, int columnIndex) {
        return getBitmap(cursor, columnIndex, null);
    }

    static ThreadLocal<Options> sOptions = new ThreadLocal<Options>() {
        @Override
        protected Options initialValue() {
            return new Options();
        };
    };
    static Bitmap getBitmap(Cursor cursor, int columnIndex, Bitmap inBitmap) {
        byte[] data = cursor.getBlob(columnIndex);
        if (data == null) {
            return null;
        }
        Options opts = sOptions.get();
        opts.inBitmap = inBitmap;
        opts.inSampleSize = 1;
        opts.inScaled = false;
        try {
            return BitmapFactory.decodeByteArray(data, 0, data.length, opts);
        } catch (IllegalArgumentException ex) {
            // Failed to re-use bitmap, create a new one
            return BitmapFactory.decodeByteArray(data, 0, data.length);
        }
    }

    private MenuItem.OnMenuItemClickListener mContextItemClickListener =
            new MenuItem.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem item) {
            return onContextItemSelected(item);
        }
    };

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        BookmarkContextMenuInfo info = (BookmarkContextMenuInfo) menuInfo;
        BrowserBookmarksAdapter adapter = getChildAdapter(info.groupPosition);
        Cursor cursor = adapter.getItem(info.childPosition);
        if (!canEdit(cursor)) {
            return;
        }
        boolean isFolder
                = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;

        final Activity activity = getActivity();
        MenuInflater inflater = activity.getMenuInflater();
        inflater.inflate(R.menu.bookmarkscontext, menu);
        if (isFolder) {
            menu.setGroupVisible(R.id.FOLDER_CONTEXT_MENU, true);
        } else {
            menu.setGroupVisible(R.id.BOOKMARK_CONTEXT_MENU, true);
            if (mDisableNewWindow) {
                menu.findItem(R.id.new_window_context_menu_id).setVisible(false);
            }
        }
        BookmarkItem header = new BookmarkItem(activity);
        header.setEnableScrolling(true);
        populateBookmarkItem(cursor, header, isFolder);
        menu.setHeaderView(header);

        int count = menu.size();
        for (int i = 0; i < count; i++) {
            menu.getItem(i).setOnMenuItemClickListener(mContextItemClickListener);
        }
    }

    boolean canEdit(Cursor c) {
        int type = c.getInt(BookmarksLoader.COLUMN_INDEX_TYPE);
        return type == BrowserContract.Bookmarks.BOOKMARK_TYPE_BOOKMARK
                || type == BrowserContract.Bookmarks.BOOKMARK_TYPE_FOLDER;
    }

    private void populateBookmarkItem(Cursor cursor, BookmarkItem item, boolean isFolder) {
        item.setName(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
        if (isFolder) {
            item.setUrl(null);
            Bitmap bitmap =
                BitmapFactory.decodeResource(getResources(), R.drawable.ic_folder_holo_dark);
            item.setFavicon(bitmap);
            new LookupBookmarkCount(getActivity(), item)
                    .execute(cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID));
        } else {
            String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
            item.setUrl(url);
            Bitmap bitmap = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
            item.setFavicon(bitmap);
        }
    }

    /**
     *  Create a new BrowserBookmarksPage.
     */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        SharedPreferences prefs = BrowserSettings.getInstance().getPreferences();
        try {
            mState = new JSONObject(prefs.getString(PREF_GROUP_STATE, "{}"));
        } catch (JSONException e) {
            // Parse failed, clear preference and start with empty state
            prefs.edit().remove(PREF_GROUP_STATE).apply();
            mState = new JSONObject();
        }
        Bundle args = getArguments();
        mDisableNewWindow = args == null ? false : args.getBoolean(EXTRA_DISABLE_WINDOW, false);
        setHasOptionsMenu(true);
        if (mCallbacks == null && getActivity() instanceof CombinedBookmarksCallbacks) {
            mCallbacks = new CombinedBookmarksCallbackWrapper(
                    (CombinedBookmarksCallbacks) getActivity());
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        try {
            mState = mGrid.saveGroupState();
            // Save state
            SharedPreferences prefs = BrowserSettings.getInstance().getPreferences();
            prefs.edit()
                    .putString(PREF_GROUP_STATE, mState.toString())
                    .apply();
        } catch (JSONException e) {
            // Not critical, ignore
        }
    }

    private static class CombinedBookmarksCallbackWrapper
            implements BookmarksPageCallbacks {

        private CombinedBookmarksCallbacks mCombinedCallback;

        private CombinedBookmarksCallbackWrapper(CombinedBookmarksCallbacks cb) {
            mCombinedCallback = cb;
        }

        @Override
        public boolean onOpenInNewWindow(String... urls) {
            mCombinedCallback.openInNewTab(urls);
            return true;
        }

        @Override
        public boolean onBookmarkSelected(Cursor c, boolean isFolder) {
            if (isFolder) {
                return false;
            }
            mCombinedCallback.openUrl(BrowserBookmarksPage.getUrl(c));
            return true;
        }
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        mRoot = inflater.inflate(R.layout.bookmarks, container, false);
        mEmptyView = mRoot.findViewById(android.R.id.empty);

        mGrid = (BookmarkExpandableView) mRoot.findViewById(R.id.grid);
        mGrid.setOnChildClickListener(this);
        mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail);
        mGrid.setBreadcrumbController(this);
        setEnableContextMenu(mEnableContextMenu);

        // Start the loaders
        LoaderManager lm = getLoaderManager();
        lm.restartLoader(LOADER_ACCOUNTS, null, this);

        return mRoot;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mGrid.setBreadcrumbController(null);
        mGrid.clearAccounts();
        LoaderManager lm = getLoaderManager();
        lm.destroyLoader(LOADER_ACCOUNTS);
        for (int id : mBookmarkAdapters.keySet()) {
            lm.destroyLoader(id);
        }
        mBookmarkAdapters.clear();
    }

    private BrowserBookmarksAdapter getChildAdapter(int groupPosition) {
        return mGrid.getChildAdapter(groupPosition);
    }

    private BreadCrumbView getBreadCrumbs(int groupPosition) {
        return mGrid.getBreadCrumbs(groupPosition);
    }

    @Override
    public boolean onChildClick(ExpandableListView parent, View v,
            int groupPosition, int childPosition, long id) {
        BrowserBookmarksAdapter adapter = getChildAdapter(groupPosition);
        Cursor cursor = adapter.getItem(childPosition);
        boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
        if (mCallbacks != null &&
                mCallbacks.onBookmarkSelected(cursor, isFolder)) {
            return true;
        }

        if (isFolder) {
            String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
            Uri uri = ContentUris.withAppendedId(
                    BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id);
            BreadCrumbView crumbs = getBreadCrumbs(groupPosition);
            if (crumbs != null) {
                // update crumbs
                crumbs.pushView(title, uri);
                crumbs.setVisibility(View.VISIBLE);
            }
            loadFolder(groupPosition, uri);
        }
        return true;
    }

    /* package */ static Intent createShortcutIntent(Context context, Cursor cursor) {
        String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
        String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
        Bitmap touchIcon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_TOUCH_ICON);
        Bitmap favicon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
        return BookmarkUtils.createAddToHomeIntent(context, url, title, touchIcon, favicon);
    }

    private void loadUrl(BrowserBookmarksAdapter adapter, int position) {
        if (mCallbacks != null && adapter != null) {
            mCallbacks.onBookmarkSelected(adapter.getItem(position), false);
        }
    }

    private void openInNewWindow(BrowserBookmarksAdapter adapter, int position) {
        if (mCallbacks != null) {
            Cursor c = adapter.getItem(position);
            boolean isFolder = c.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1;
            if (isFolder) {
                long id = c.getLong(BookmarksLoader.COLUMN_INDEX_ID);
                new OpenAllInTabsTask(id).execute();
            } else {
                mCallbacks.onOpenInNewWindow(BrowserBookmarksPage.getUrl(c));
            }
        }
    }

    class OpenAllInTabsTask extends AsyncTask<Void, Void, Cursor> {
        long mFolderId;
        public OpenAllInTabsTask(long id) {
            mFolderId = id;
        }

        @Override
        protected Cursor doInBackground(Void... params) {
            Context c = getActivity();
            if (c == null) return null;
            return c.getContentResolver().query(BookmarkUtils.getBookmarksUri(c),
                    BookmarksLoader.PROJECTION, BrowserContract.Bookmarks.PARENT + "=?",
                    new String[] { Long.toString(mFolderId) }, null);
        }

        @Override
        protected void onPostExecute(Cursor result) {
            if (mCallbacks != null && result.getCount() > 0) {
                String[] urls = new String[result.getCount()];
                int i = 0;
                while (result.moveToNext()) {
                    urls[i++] = BrowserBookmarksPage.getUrl(result);
                }
                mCallbacks.onOpenInNewWindow(urls);
            }
        }

    }

    private void editBookmark(BrowserBookmarksAdapter adapter, int position) {
        Intent intent = new Intent(getActivity(), AddBookmarkPage.class);
        Cursor cursor = adapter.getItem(position);
        Bundle item = new Bundle();
        item.putString(BrowserContract.Bookmarks.TITLE,
                cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
        item.putString(BrowserContract.Bookmarks.URL,
                cursor.getString(BookmarksLoader.COLUMN_INDEX_URL));
        byte[] data = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_FAVICON);
        if (data != null) {
            item.putParcelable(BrowserContract.Bookmarks.FAVICON,
                    BitmapFactory.decodeByteArray(data, 0, data.length));
        }
        item.putLong(BrowserContract.Bookmarks._ID,
                cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID));
        item.putLong(BrowserContract.Bookmarks.PARENT,
                cursor.getLong(BookmarksLoader.COLUMN_INDEX_PARENT));
        intent.putExtra(AddBookmarkPage.EXTRA_EDIT_BOOKMARK, item);
        intent.putExtra(AddBookmarkPage.EXTRA_IS_FOLDER,
                cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) == 1);
        startActivity(intent);
    }

    private void displayRemoveBookmarkDialog(BrowserBookmarksAdapter adapter,
            int position) {
        // Put up a dialog asking if the user really wants to
        // delete the bookmark
        Cursor cursor = adapter.getItem(position);
        long id = cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID);
        String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
        Context context = getActivity();
        BookmarkUtils.displayRemoveBookmarkDialog(id, title, context, null);
    }

    private String getUrl(BrowserBookmarksAdapter adapter, int position) {
        return getUrl(adapter.getItem(position));
    }

    /* package */ static String getUrl(Cursor c) {
        return c.getString(BookmarksLoader.COLUMN_INDEX_URL);
    }

    private void copy(CharSequence text) {
        ClipboardManager cm = (ClipboardManager) getActivity().getSystemService(
                Context.CLIPBOARD_SERVICE);
        cm.setPrimaryClip(ClipData.newRawUri(null, Uri.parse(text.toString())));
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Resources res = getActivity().getResources();
        mGrid.setColumnWidthFromLayout(R.layout.bookmark_thumbnail);
        int paddingTop = (int) res.getDimension(R.dimen.combo_paddingTop);
        mRoot.setPadding(0, paddingTop, 0, 0);
        getActivity().invalidateOptionsMenu();
    }

    /**
     * BreadCrumb controller callback
     */
    @Override
    public void onTop(BreadCrumbView view, int level, Object data) {
        int groupPosition = (Integer) view.getTag(R.id.group_position);
        Uri uri = (Uri) data;
        if (uri == null) {
            // top level
            uri = BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER;
        }
        loadFolder(groupPosition, uri);
        if (level <= 1) {
            view.setVisibility(View.GONE);
        } else {
            view.setVisibility(View.VISIBLE);
        }
    }

    /**
     * @param uri
     */
    private void loadFolder(int groupPosition, Uri uri) {
        LoaderManager manager = getLoaderManager();
        // This assumes groups are ordered the same as loaders
        BookmarksLoader loader = (BookmarksLoader) ((Loader<?>)
                manager.getLoader(LOADER_BOOKMARKS + groupPosition));
        loader.setUri(uri);
        loader.forceLoad();
    }

    public void setCallbackListener(BookmarksPageCallbacks callbackListener) {
        mCallbacks = callbackListener;
    }

    public void setEnableContextMenu(boolean enable) {
        mEnableContextMenu = enable;
        if (mGrid != null) {
            if (mEnableContextMenu) {
                registerForContextMenu(mGrid);
            } else {
                unregisterForContextMenu(mGrid);
                mGrid.setLongClickable(false);
            }
        }
    }

    private static class LookupBookmarkCount extends AsyncTask<Long, Void, Integer> {
        Context mContext;
        BookmarkItem mHeader;

        public LookupBookmarkCount(Context context, BookmarkItem header) {
            mContext = context.getApplicationContext();
            mHeader = header;
        }

        @Override
        protected Integer doInBackground(Long... params) {
            if (params.length != 1) {
                throw new IllegalArgumentException("Missing folder id!");
            }
            Uri uri = BookmarkUtils.getBookmarksUri(mContext);
            Cursor c = null;
            try {
                c = mContext.getContentResolver().query(uri,
                        null, BrowserContract.Bookmarks.PARENT + "=?",
                        new String[] {params[0].toString()}, null);

                return c.getCount();
            } finally {
                if ( c != null) {
                    c.close();
                }
            }
        }

        @Override
        protected void onPostExecute(Integer result) {
            if (result > 0) {
                mHeader.setUrl(mContext.getString(R.string.contextheader_folder_bookmarkcount,
                        result));
            } else if (result == 0) {
                mHeader.setUrl(mContext.getString(R.string.contextheader_folder_empty));
            }
        }
    }

    static class AccountsLoader extends CursorLoader {

        static String[] ACCOUNTS_PROJECTION = new String[] {
            Accounts.ACCOUNT_NAME,
            Accounts.ACCOUNT_TYPE
        };

        public AccountsLoader(Context context) {
            super(context, Accounts.CONTENT_URI
                    .buildUpon()
                    .appendQueryParameter(BrowserProvider2.PARAM_ALLOW_EMPTY_ACCOUNTS, "false")
                    .build(),
                    ACCOUNTS_PROJECTION, null, null, null);
        }

    }
}
