<commit_before>package org.wikipedia.search;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.widget.DrawerLayout;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.*;
import android.view.inputmethod.InputMethodManager;
import android.widget.*;
import com.squareup.otto.Subscribe;
import com.squareup.picasso.Picasso;
import org.wikipedia.*;
import org.wikipedia.events.NewWikiPageNavigationEvent;
import org.wikipedia.history.HistoryEntry;
import org.wikipedia.page.PageActionsHandler;
import org.wikipedia.pageimages.PageImagesTask;

import java.util.List;
import java.util.Map;

public class SearchArticlesFragment extends Fragment {
    private static final int DELAY_MILLIS = 300;

    private static final int MESSAGE_SEARCH = 1;

    private WikipediaApp app;

    private View searchBarIcon;
    private EditText searchTermText;
    private ListView searchResultsList;
    private ProgressBar searchProgress;
    private View searchNetworkError;
    private View searchNoResults;
    private View searchBarMenuButton;
    private View drawerIndicator;

    private SearchResultAdapter adapter;

    private boolean isSearchActive = false;

    private ParcelableLruCache<List<PageTitle>> searchResultsCache = new ParcelableLruCache<List<PageTitle>>(4, List.class);
    private ParcelableLruCache<String> pageImagesCache = new ParcelableLruCache<String>(48, String.class);
    private String lastSearchedText;

    private Handler searchHandler;

    private DrawerLayout drawerLayout;

    private SearchArticlesTask curSearchTask;

    /**
     * Displays results passed to it as search suggestions.
     *
     * @param results List of results to display. If null, clears the list of suggestions & hides it.
     */
    private void displayResults(List<PageTitle> results) {
        adapter.setResults(results);
        ((BaseAdapter)searchResultsList.getAdapter()).notifyDataSetInvalidated();
        if (results == null) {
            searchResultsList.setVisibility(View.GONE);
            isSearchActive = false;
        } else if (results.size() == 0) {
            searchNoResults.setVisibility(View.VISIBLE);
        } else {
            searchResultsList.setVisibility(View.VISIBLE);
            PageImagesTask imagesTask = new PageImagesTask(
                    app.getAPIForSite(app.getPrimarySite()),
                    app.getPrimarySite(),
                    results,
                    (int)(48f * WikipediaApp.SCREEN_DENSITY)) {
                @Override
                public void onFinish(Map<PageTitle, String> result) {
                    for(Map.Entry<PageTitle, String> entry : result.entrySet()) {
                        if (entry.getValue() == null) {
                            continue;
                        }
                        pageImagesCache.put(entry.getKey().getPrefixedText(), entry.getValue());
                    }
                    ((BaseAdapter)searchResultsList.getAdapter()).notifyDataSetInvalidated();
                }

                @Override
                public void onCatch(Throwable caught) {
                    // Don't actually do anything.
                    // Thumbnails are expendable
                }
            };
            imagesTask.execute();
        }
    }

    @Override
    public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        app = (WikipediaApp)getActivity().getApplicationContext();
        LinearLayout parentLayout = (LinearLayout) inflater.inflate(R.layout.fragment_search, container, false);

        if (savedInstanceState != null) {
            searchResultsCache = savedInstanceState.getParcelable("searchResultsCache");
            pageImagesCache = savedInstanceState.getParcelable("pageImagesCache");
            lastSearchedText = savedInstanceState.getString("lastSearchedText");
            isSearchActive = savedInstanceState.getBoolean("isSearchActive");
        }

        searchTermText = (EditText) parentLayout.findViewById(R.id.search_term_text);
        searchResultsList = (ListView) parentLayout.findViewById(R.id.search_results_list);
        searchProgress = (ProgressBar) parentLayout.findViewById(R.id.search_progress);
        searchBarIcon = parentLayout.findViewById(R.id.search_bar_icon);
        searchNetworkError = parentLayout.findViewById(R.id.search_network_error);
        searchBarMenuButton = parentLayout.findViewById(R.id.search_bar_show_menu);
        drawerIndicator = parentLayout.findViewById(R.id.search_drawer_indicator);
        searchNoResults = parentLayout.findViewById(R.id.search_results_empty);

        PopupMenu pageActionsMenu = new PopupMenu(getActivity(), searchBarMenuButton);
        PageActionsHandler pageActionsHandler = new PageActionsHandler(app.getBus(), pageActionsMenu, searchBarMenuButton);

        searchHandler = new Handler(new Handler.Callback(){
            @Override
            public boolean handleMessage(Message msg) {
                final String searchTerm = (String) msg.obj;
                SearchArticlesTask searchTask = new SearchArticlesTask(app.getAPIForSite(app.getPrimarySite()), app.getPrimarySite(), searchTerm) {
                    @Override
                    public void onFinish(List<PageTitle> result) {
                        searchProgress.setVisibility(View.GONE);
                        searchNetworkError.setVisibility(View.GONE);
                        displayResults(result);
                        searchResultsCache.put(app.getPrimaryLanguage() + "-" + searchTerm, result);
                        lastSearchedText = searchTerm;
                        curSearchTask = null;
                    }

                    @Override
                    public void onCatch(Throwable caught) {
                        searchProgress.setVisibility(View.GONE);
                        searchNetworkError.setVisibility(View.VISIBLE);
                        searchResultsList.setVisibility(View.GONE);
                        curSearchTask = null;
                    }

                    @Override
                    public void onBeforeExecute() {
                        searchProgress.setVisibility(View.VISIBLE);
                        isSearchActive = true;
                    }
                };
                if (curSearchTask != null) {
                    // This does not cancel the HTTP request itself
                    // But it does cancel th execution of onFinish
                    // This makes sure that a slower previous search query does not override
                    // the results of a newer search query
                    curSearchTask.cancel();
                }
                curSearchTask = searchTask;
                searchTask.execute();
                return true;
            }
        });

        searchResultsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                PageTitle title = (PageTitle) searchResultsList.getAdapter().getItem(position);
                HistoryEntry historyEntry = new HistoryEntry(title, HistoryEntry.SOURCE_SEARCH);
                app.getBus().post(new NewWikiPageNavigationEvent(title, historyEntry));
                displayResults(null);
            }
        });

        searchNetworkError.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Just retry!
                startSearch(searchTermText.getText().toString());
                searchNetworkError.setVisibility(View.GONE);
            }
        });

        searchTermText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                // DO NOTHING!<commit_msg>Slide the keyboard down on search result item tap.<commit_after>package org.wikipedia.search;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.widget.DrawerLayout;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.*;
import android.view.inputmethod.InputMethodManager;
import android.widget.*;
import com.squareup.otto.Subscribe;
import com.squareup.picasso.Picasso;
import org.wikipedia.*;
import org.wikipedia.events.NewWikiPageNavigationEvent;
import org.wikipedia.history.HistoryEntry;
import org.wikipedia.page.PageActionsHandler;
import org.wikipedia.pageimages.PageImagesTask;

import java.util.List;
import java.util.Map;

public class SearchArticlesFragment extends Fragment {
    private static final int DELAY_MILLIS = 300;

    private static final int MESSAGE_SEARCH = 1;

    private WikipediaApp app;

    private View searchBarIcon;
    private EditText searchTermText;
    private ListView searchResultsList;
    private ProgressBar searchProgress;
    private View searchNetworkError;
    private View searchNoResults;
    private View searchBarMenuButton;
    private View drawerIndicator;

    private SearchResultAdapter adapter;

    private boolean isSearchActive = false;

    private ParcelableLruCache<List<PageTitle>> searchResultsCache = new ParcelableLruCache<List<PageTitle>>(4, List.class);
    private ParcelableLruCache<String> pageImagesCache = new ParcelableLruCache<String>(48, String.class);
    private String lastSearchedText;

    private Handler searchHandler;

    private DrawerLayout drawerLayout;

    private SearchArticlesTask curSearchTask;

    /**
     * Displays results passed to it as search suggestions.
     *
     * @param results List of results to display. If null, clears the list of suggestions & hides it.
     */
    private void displayResults(List<PageTitle> results) {
        adapter.setResults(results);
        ((BaseAdapter)searchResultsList.getAdapter()).notifyDataSetInvalidated();
        if (results == null) {
            searchResultsList.setVisibility(View.GONE);
            isSearchActive = false;
        } else if (results.size() == 0) {
            searchNoResults.setVisibility(View.VISIBLE);
        } else {
            searchResultsList.setVisibility(View.VISIBLE);
            PageImagesTask imagesTask = new PageImagesTask(
                    app.getAPIForSite(app.getPrimarySite()),
                    app.getPrimarySite(),
                    results,
                    (int)(48f * WikipediaApp.SCREEN_DENSITY)) {
                @Override
                public void onFinish(Map<PageTitle, String> result) {
                    for(Map.Entry<PageTitle, String> entry : result.entrySet()) {
                        if (entry.getValue() == null) {
                            continue;
                        }
                        pageImagesCache.put(entry.getKey().getPrefixedText(), entry.getValue());
                    }
                    ((BaseAdapter)searchResultsList.getAdapter()).notifyDataSetInvalidated();
                }

                @Override
                public void onCatch(Throwable caught) {
                    // Don't actually do anything.
                    // Thumbnails are expendable
                }
            };
            imagesTask.execute();
        }
    }

    @Override
    public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        app = (WikipediaApp)getActivity().getApplicationContext();
        LinearLayout parentLayout = (LinearLayout) inflater.inflate(R.layout.fragment_search, container, false);

        if (savedInstanceState != null) {
            searchResultsCache = savedInstanceState.getParcelable("searchResultsCache");
            pageImagesCache = savedInstanceState.getParcelable("pageImagesCache");
            lastSearchedText = savedInstanceState.getString("lastSearchedText");
            isSearchActive = savedInstanceState.getBoolean("isSearchActive");
        }

        searchTermText = (EditText) parentLayout.findViewById(R.id.search_term_text);
        searchResultsList = (ListView) parentLayout.findViewById(R.id.search_results_list);
        searchProgress = (ProgressBar) parentLayout.findViewById(R.id.search_progress);
        searchBarIcon = parentLayout.findViewById(R.id.search_bar_icon);
        searchNetworkError = parentLayout.findViewById(R.id.search_network_error);
        searchBarMenuButton = parentLayout.findViewById(R.id.search_bar_show_menu);
        drawerIndicator = parentLayout.findViewById(R.id.search_drawer_indicator);
        searchNoResults = parentLayout.findViewById(R.id.search_results_empty);

        PopupMenu pageActionsMenu = new PopupMenu(getActivity(), searchBarMenuButton);
        PageActionsHandler pageActionsHandler = new PageActionsHandler(app.getBus(), pageActionsMenu, searchBarMenuButton);

        searchHandler = new Handler(new Handler.Callback(){
            @Override
            public boolean handleMessage(Message msg) {
                final String searchTerm = (String) msg.obj;
                SearchArticlesTask searchTask = new SearchArticlesTask(app.getAPIForSite(app.getPrimarySite()), app.getPrimarySite(), searchTerm) {
                    @Override
                    public void onFinish(List<PageTitle> result) {
                        searchProgress.setVisibility(View.GONE);
                        searchNetworkError.setVisibility(View.GONE);
                        displayResults(result);
                        searchResultsCache.put(app.getPrimaryLanguage() + "-" + searchTerm, result);
                        lastSearchedText = searchTerm;
                        curSearchTask = null;
                    }

                    @Override
                    public void onCatch(Throwable caught) {
                        searchProgress.setVisibility(View.GONE);
                        searchNetworkError.setVisibility(View.VISIBLE);
                        searchResultsList.setVisibility(View.GONE);
                        curSearchTask = null;
                    }

                    @Override
                    public void onBeforeExecute() {
                        searchProgress.setVisibility(View.VISIBLE);
                        isSearchActive = true;
                    }
                };
                if (curSearchTask != null) {
                    // This does not cancel the HTTP request itself
                    // But it does cancel th execution of onFinish
                    // This makes sure that a slower previous search query does not override
                    // the results of a newer search query
                    curSearchTask.cancel();
                }
                curSearchTask = searchTask;
                searchTask.execute();
                return true;
            }
        });

        searchResultsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                PageTitle title = (PageTitle) searchResultsList.getAdapter().getItem(position);
                HistoryEntry historyEntry = new HistoryEntry(title, HistoryEntry.SOURCE_SEARCH);
                InputMethodManager keyboard = (InputMethodManager)app.getSystemService(Context.INPUT_METHOD_SERVICE);
                keyboard.hideSoftInputFromWindow(searchTermText.getWindowToken(), 0);
                app.getBus().post(new NewWikiPageNavigationEvent(title, historyEntry));
                displayResults(null);
            }
        });

        searchNetworkError.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Just retry!
                startSearch(searchTermText.getText().toString());
                searchNetworkError.setVisibility(View.GONE);
            }
        });

        searchTermText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                // DO NOTHING!
{'fraction_non_alphanumeric': 0.0807544405786486, 'fraction_numerical': 0.0015259720441921504, 'mean_word_length': 2.2469282600079272, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6542938', 'n_tokens_mistral': 4033, 'n_tokens_neox': 3789, 'n_words': 824}