/*
 * Copyright (C) 2010 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.SearchManager;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.BrowserContract;
import android.text.Html;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

import com.android.browser.provider.BrowserProvider2.OmniboxSuggestions;
import com.android.browser.search.SearchEngine;

import java.util.ArrayList;
import java.util.List;

/**
 * adapter to wrap multiple cursors for url/search completions
 */
public class SuggestionsAdapter extends BaseAdapter implements Filterable,
        OnClickListener {

    public static final int TYPE_BOOKMARK = 0;
    public static final int TYPE_HISTORY = 1;
    public static final int TYPE_SUGGEST_URL = 2;
    public static final int TYPE_SEARCH = 3;
    public static final int TYPE_SUGGEST = 4;

    private static final String[] COMBINED_PROJECTION = {
            OmniboxSuggestions._ID,
            OmniboxSuggestions.TITLE,
            OmniboxSuggestions.URL,
            OmniboxSuggestions.IS_BOOKMARK
            };

    private static final String COMBINED_SELECTION =
            "(url LIKE ? OR url LIKE ? OR url LIKE ? OR url LIKE ? OR title LIKE ?)";

    final Context mContext;
    final Filter mFilter;
    SuggestionResults mMixedResults;
    List<SuggestItem> mSuggestResults, mFilterResults;
    List<CursorSource> mSources;
    boolean mLandscapeMode;
    final CompletionListener mListener;
    final int mLinesPortrait;
    final int mLinesLandscape;
    final Object mResultsLock = new Object();
    boolean mIncognitoMode;
    BrowserSettings mSettings;

    interface CompletionListener {

        public void onSearch(String txt);

        public void onSelect(String txt, int type, String extraData);

    }

    public SuggestionsAdapter(Context ctx, CompletionListener listener) {
        mContext = ctx;
        mSettings = BrowserSettings.getInstance();
        mListener = listener;
        mLinesPortrait = mContext.getResources().
                getInteger(R.integer.max_suggest_lines_portrait);
        mLinesLandscape = mContext.getResources().
                getInteger(R.integer.max_suggest_lines_landscape);

        mFilter = new SuggestFilter();
        addSource(new CombinedCursor());
    }

    public void setLandscapeMode(boolean mode) {
        mLandscapeMode = mode;
        notifyDataSetChanged();
    }

    public void addSource(CursorSource c) {
        if (mSources == null) {
            mSources = new ArrayList<CursorSource>(5);
        }
        mSources.add(c);
    }

    @Override
    public void onClick(View v) {
        SuggestItem item = (SuggestItem) ((View) v.getParent()).getTag();

        if (R.id.icon2 == v.getId()) {
            // replace input field text with suggestion text
            mListener.onSearch(getSuggestionUrl(item));
        } else {
            mListener.onSelect(getSuggestionUrl(item), item.type, item.extra);
        }
    }

    @Override
    public Filter getFilter() {
        return mFilter;
    }

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

    @Override
    public SuggestItem getItem(int position) {
        if (mMixedResults == null) {
            return null;
        }
        return mMixedResults.items.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final LayoutInflater inflater = LayoutInflater.from(mContext);
        View view = convertView;
        if (view == null) {
            view = inflater.inflate(R.layout.suggestion_item, parent, false);
        }
        bindView(view, getItem(position));
        return view;
    }

    private void bindView(View view, SuggestItem item) {
        // store item for click handling
        view.setTag(item);
        TextView tv1 = (TextView) view.findViewById(android.R.id.text1);
        TextView tv2 = (TextView) view.findViewById(android.R.id.text2);
        ImageView ic1 = (ImageView) view.findViewById(R.id.icon1);
        View ic2 = view.findViewById(R.id.icon2);
        View div = view.findViewById(R.id.divider);
        tv1.setText(Html.fromHtml(item.title));
        if (TextUtils.isEmpty(item.url)) {
            tv2.setVisibility(View.GONE);
            tv1.setMaxLines(2);
        } else {
            tv2.setVisibility(View.VISIBLE);
            tv2.setText(item.url);
            tv1.setMaxLines(1);
        }
        int id = -1;
        switch (item.type) {
            case TYPE_SUGGEST:
            case TYPE_SEARCH:
                id = R.drawable.ic_search_category_suggest;
                break;
            case TYPE_BOOKMARK:
                id = R.drawable.ic_search_category_bookmark;
                break;
            case TYPE_HISTORY:
                id = R.drawable.ic_search_category_history;
                break;
            case TYPE_SUGGEST_URL:
                id = R.drawable.ic_search_category_browser;
                break;
            default:
                id = -1;
        }
        if (id != -1) {
            ic1.setImageDrawable(mContext.getResources().getDrawable(id));
        }
        ic2.setVisibility(((TYPE_SUGGEST == item.type)
                || (TYPE_SEARCH == item.type))
                ? View.VISIBLE : View.GONE);
        div.setVisibility(ic2.getVisibility());
        ic2.setOnClickListener(this);
        view.findViewById(R.id.suggestion).setOnClickListener(this);
    }

    class SlowFilterTask extends AsyncTask<CharSequence, Void, List<SuggestItem>> {

        @Override
        protected List<SuggestItem> doInBackground(CharSequence... params) {
            SuggestCursor cursor = new SuggestCursor();
            cursor.runQuery(params[0]);
            List<SuggestItem> results = new ArrayList<SuggestItem>();
            int count = cursor.getCount();
            for (int i = 0; i < count; i++) {
                results.add(cursor.getItem());
                cursor.moveToNext();
            }
            cursor.close();
            return results;
        }

        @Override
        protected void onPostExecute(List<SuggestItem> items) {
            mSuggestResults = items;
            mMixedResults = buildSuggestionResults();
            notifyDataSetChanged();
        }
    }

    SuggestionResults buildSuggestionResults() {
        SuggestionResults mixed = new SuggestionResults();
        List<SuggestItem> filter, suggest;
        synchronized (mResultsLock) {
            filter = mFilterResults;
            suggest = mSuggestResults;
        }
        if (filter != null) {
            for (SuggestItem item : filter) {
                mixed.addResult(item);
            }
        }
        if (suggest != null) {
            for (SuggestItem item : suggest) {
                mixed.addResult(item);
            }
        }
        return mixed;
    }

    class SuggestFilter extends Filter {

        @Override
        public CharSequence convertResultToString(Object item) {
            if (item == null) {
                return "";
            }
            SuggestItem sitem = (SuggestItem) item;
            if (sitem.title != null) {
                return sitem.title;
            } else {
                return sitem.url;
            }
        }

        void startSuggestionsAsync(final CharSequence constraint) {
            if (!mIncognitoMode) {
                new SlowFilterTask().execute(constraint);
            }
        }

        private boolean shouldProcessEmptyQuery() {
            final SearchEngine searchEngine = mSettings.getSearchEngine();
            return searchEngine.wantsEmptyQuery();
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults res = new FilterResults();
            if (TextUtils.isEmpty(constraint) && !shouldProcessEmptyQuery()) {
                res.count = 0;
                res.values = null;
                return res;
            }
            startSuggestionsAsync(constraint);
            List<SuggestItem> filterResults = new ArrayList<SuggestItem>();
            if (constraint != null) {
                for (CursorSource sc : mSources) {
                    sc.runQuery(constraint);
                }
                mixResults(filterResults);
            }
            synchronized (mResultsLock) {
                mFilterResults = filterResults;
            }
            SuggestionResults mixed = buildSuggestionResults();
            res.count = mixed.getLineCount();
            res.values = mixed;
            return res;
        }

        void mixResults(List<SuggestItem> results) {
            int maxLines = getMaxLines();
            for (int i = 0; i < mSources.size(); i++) {
                CursorSource s = mSources.get(i);
                int n = Math.min(s.getCount(), maxLines);
                maxLines -= n;
                boolean more = false;
                for (int j = 0; j < n; j++) {
                    results.add(s.getItem());
                    more = s.moveToNext();
                }
            }
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults fresults) {
            if (fresults.values instanceof SuggestionResults) {
                mMixedResults = (SuggestionResults) fresults.values;
                notifyDataSetChanged();
            }
        }
    }

    private int getMaxLines() {
        int maxLines = mLandscapeMode ? mLinesLandscape : mLinesPortrait;
        maxLines = (int) Math.ceil(maxLines / 2.0);
        return maxLines;
    }

    /**
     * sorted list of results of a suggestion query
     *
     */
    class SuggestionResults {

        ArrayList<SuggestItem> items;
        // count per type
        int[] counts;

        SuggestionResults() {
            items = new ArrayList<SuggestItem>(24);
            // n of types:
            counts = new int[5];
        }

        int getTypeCount(int type) {
            return counts[type];
        }

        void addResult(SuggestItem item) {
            int ix = 0;
            while ((ix < items.size()) && (item.type >= items.get(ix).type))
                ix++;
            items.add(ix, item);
            counts[item.type]++;
        }

        int getLineCount() {
            return Math.min((mLandscapeMode ? mLinesLandscape : mLinesPortrait), items.size());
        }

        @Override
        public String toString() {
            if (items == null) return null;
            if (items.size() == 0) return "[]";
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < items.size(); i++) {
                SuggestItem item = items.get(i);
                sb.append(item.type + ": " + item.title);
                if (i < items.size() - 1) {
                    sb.append(", ");
                }
            }
            return sb.toString();
        }
    }

    /**
     * data object to hold suggestion values
     */
    public class SuggestItem {
        public String title;
        public String url;
        public int type;
        public String extra;

        public SuggestItem(String text, String u, int t) {
            title = text;
            url = u;
            type = t;
        }

    }

    abstract class CursorSource {

        Cursor mCursor;

        boolean moveToNext() {
            return mCursor.moveToNext();
        }

        public abstract void runQuery(CharSequence constraint);

        public abstract SuggestItem getItem();

        public int getCount() {
            return (mCursor != null) ? mCursor.getCount() : 0;
        }

        public void close() {
            if (mCursor != null) {
                mCursor.close();
            }
        }
    }

    /**
     * combined bookmark & history source
     */
    class CombinedCursor extends CursorSource {

        @Override
        public SuggestItem getItem() {
            if ((mCursor != null) && (!mCursor.isAfterLast())) {
                String title = mCursor.getString(1);
                String url = mCursor.getString(2);
                boolean isBookmark = (mCursor.getInt(3) == 1);
                return new SuggestItem(getTitle(title, url), getUrl(title, url),
                        isBookmark ? TYPE_BOOKMARK : TYPE_HISTORY);
            }
            return null;
        }

        @Override
        public void runQuery(CharSequence constraint) {
            // constraint != null
            if (mCursor != null) {
                mCursor.close();
            }
            String like = constraint + "%";
            String[] args = null;
            String selection = null;
            if (like.startsWith("http") || like.startsWith("file")) {
                args = new String[1];
                args[0] = like;
                selection = "url LIKE ?";
            } else {
                args = new String[5];
                args[0] = "http://" + like;
                args[1] = "http://www." + like;
                args[2] = "https://" + like;
                args[3] = "https://www." + like;
                // To match against titles.
                args[4] = like;
                selection = COMBINED_SELECTION;
            }
            Uri.Builder ub = OmniboxSuggestions.CONTENT_URI.buildUpon();
            ub.appendQueryParameter(BrowserContract.PARAM_LIMIT,
                    Integer.toString(Math.max(mLinesLandscape, mLinesPortrait)));
            mCursor =
                    mContext.getContentResolver().query(ub.build(), COMBINED_PROJECTION,
                            selection, (constraint != null) ? args : null, null);
            if (mCursor != null) {
                mCursor.moveToFirst();
            }
        }

        /**
         * Provides the title (text line 1) for a browser suggestion, which should be the
         * webpage title. If the webpage title is empty, returns the stripped url instead.
         *
         * @return the title string to use
         */
        private String getTitle(String title, String url) {
            if (TextUtils.isEmpty(title) || TextUtils.getTrimmedLength(title) == 0) {
                title = UrlUtils.stripUrl(url);
            }
            return title;
        }

        /**
         * Provides the subtitle (text line 2) for a browser suggestion, which should be the
         * webpage url. If the webpage title is empty, then the url should go in the title
         * instead, and the subtitle should be empty, so this would return null.
         *
         * @return the subtitle string to use, or null if none
         */
        private String getUrl(String title, String url) {
            if (TextUtils.isEmpty(title)
                    || TextUtils.getTrimmedLength(title) == 0
                    || title.equals(url)) {
                return null;
            } else {
                return UrlUtils.stripUrl(url);
            }
        }
    }

    class SuggestCursor extends CursorSource {

        @Override
        public SuggestItem getItem() {
            if (mCursor != null) {
                String title = mCursor.getString(
                        mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1));
                String text2 = mCursor.getString(
                        mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2));
                String url = mCursor.getString(
                        mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2_URL));
                String uri = mCursor.getString(
                        mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_INTENT_DATA));
                int type = (TextUtils.isEmpty(url)) ? TYPE_SUGGEST : TYPE_SUGGEST_URL;
                SuggestItem item = new SuggestItem(title, url, type);
                item.extra = mCursor.getString(
                        mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA));
                return item;
            }
            return null;
        }

        @Override
        public void runQuery(CharSequence constraint) {
            if (mCursor != null) {
                mCursor.close();
            }
            SearchEngine searchEngine = mSettings.getSearchEngine();
            if (!TextUtils.isEmpty(constraint)) {
                if (searchEngine != null && searchEngine.supportsSuggestions()) {
                    mCursor = searchEngine.getSuggestions(mContext, constraint.toString());
                    if (mCursor != null) {
                        mCursor.moveToFirst();
                    }
                }
            } else {
                if (searchEngine.wantsEmptyQuery()) {
                    mCursor = searchEngine.getSuggestions(mContext, "");
                }
                mCursor = null;
            }
        }

    }

    public void clearCache() {
        mFilterResults = null;
        mSuggestResults = null;
        notifyDataSetInvalidated();
    }

    public void setIncognitoMode(boolean incognito) {
        mIncognitoMode = incognito;
        clearCache();
    }

    static String getSuggestionTitle(SuggestItem item) {
        // There must be a better way to strip HTML from things.
        // This method is used in multiple places. It is also more
        // expensive than a standard html escaper.
        return (item.title != null) ? Html.fromHtml(item.title).toString() : null;
    }

    static String getSuggestionUrl(SuggestItem item) {
        final String title = SuggestionsAdapter.getSuggestionTitle(item);

        if (TextUtils.isEmpty(item.url)) {
            return title;
        }

        return item.url;
    }
}
